8261090: Store old classfiles in static CDS archive

Reviewed-by: iklam, minqi
This commit is contained in:
Calvin Cheung 2021-04-22 15:13:29 +00:00
parent 159f5e1ede
commit 9499175064
29 changed files with 895 additions and 42 deletions

View file

@ -5920,18 +5920,6 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
_minor_version = stream->get_u2_fast(); _minor_version = stream->get_u2_fast();
_major_version = stream->get_u2_fast(); _major_version = stream->get_u2_fast();
if (DumpSharedSpaces && _major_version < JAVA_6_VERSION) {
ResourceMark rm;
warning("Pre JDK 6 class not supported by CDS: %u.%u %s",
_major_version, _minor_version, _class_name->as_C_string());
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_UnsupportedClassVersionError(),
"Unsupported major.minor version for dump time %u.%u",
_major_version,
_minor_version);
}
// Check version numbers - we check this even with verifier off // Check version numbers - we check this even with verifier off
verify_class_version(_major_version, _minor_version, _class_name, CHECK); verify_class_version(_major_version, _minor_version, _class_name, CHECK);

View file

@ -1380,18 +1380,28 @@ bool SystemDictionaryShared::should_be_excluded(InstanceKlass* k) {
// class loader doesn't expect it. // class loader doesn't expect it.
if (has_class_failed_verification(k)) { if (has_class_failed_verification(k)) {
warn_excluded(k, "Failed verification"); warn_excluded(k, "Failed verification");
return true;
} else { } else {
warn_excluded(k, "Not linked"); if (!MetaspaceShared::is_old_class(k)) {
warn_excluded(k, "Not linked");
return true;
}
} }
return true;
} }
if (k->major_version() < 50 /*JAVA_6_VERSION*/) { if (DynamicDumpSharedSpaces && k->major_version() < 50 /*JAVA_6_VERSION*/) {
// In order to support old classes during dynamic dump, class rewriting needs to
// be reverted. This would result in more complex code and testing but not much gain.
ResourceMark rm; ResourceMark rm;
log_warning(cds)("Pre JDK 6 class not supported by CDS: %u.%u %s", log_warning(cds)("Pre JDK 6 class not supported by CDS: %u.%u %s",
k->major_version(), k->minor_version(), k->name()->as_C_string()); k->major_version(), k->minor_version(), k->name()->as_C_string());
return true; return true;
} }
if (MetaspaceShared::is_old_class(k) && k->is_linked()) {
warn_excluded(k, "Old class has been linked");
return true;
}
InstanceKlass* super = k->java_super(); InstanceKlass* super = k->java_super();
if (super != NULL && should_be_excluded(super)) { if (super != NULL && should_be_excluded(super)) {
ResourceMark rm; ResourceMark rm;

View file

@ -285,7 +285,9 @@ bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_ve
// already been rewritten to contain constant pool cache indices, // already been rewritten to contain constant pool cache indices,
// which the verifier can't understand. // which the verifier can't understand.
// Shared classes shouldn't have stackmaps either. // Shared classes shouldn't have stackmaps either.
!klass->is_shared() && // However, bytecodes for shared old classes can be verified because
// they have not been rewritten.
!(klass->is_shared() && klass->is_rewritten()) &&
// As of the fix for 4486457 we disable verification for all of the // As of the fix for 4486457 we disable verification for all of the
// dynamically-generated bytecodes associated with the 1.4 // dynamically-generated bytecodes associated with the 1.4

View file

@ -28,6 +28,7 @@
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "interpreter/rewriter.hpp" #include "interpreter/rewriter.hpp"
#include "memory/metadataFactory.hpp" #include "memory/metadataFactory.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "oops/constantPool.hpp" #include "oops/constantPool.hpp"
#include "oops/generateOopMap.hpp" #include "oops/generateOopMap.hpp"
@ -567,8 +568,9 @@ void Rewriter::rewrite_bytecodes(TRAPS) {
} }
void Rewriter::rewrite(InstanceKlass* klass, TRAPS) { void Rewriter::rewrite(InstanceKlass* klass, TRAPS) {
if (!DumpSharedSpaces) { if (klass->is_shared()) {
assert(!klass->is_shared(), "archive methods must not be rewritten at run time"); assert(!klass->is_rewritten(), "rewritten shared classes cannot be rewritten again");
assert(MetaspaceShared::is_old_class(klass), "only shared old classes aren't rewritten");
} }
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
constantPoolHandle cpool(THREAD, klass->constants()); constantPoolHandle cpool(THREAD, klass->constants());

View file

@ -389,7 +389,9 @@ static void rewrite_nofast_bytecode(const methodHandle& method) {
void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik) { void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik) {
for (int i = 0; i < ik->methods()->length(); i++) { for (int i = 0; i < ik->methods()->length(); i++) {
methodHandle m(thread, ik->methods()->at(i)); methodHandle m(thread, ik->methods()->at(i));
rewrite_nofast_bytecode(m); if (!is_old_class(ik)) {
rewrite_nofast_bytecode(m);
}
Fingerprinter fp(m); Fingerprinter fp(m);
// The side effect of this call sets method's fingerprint field. // The side effect of this call sets method's fingerprint field.
fp.fingerprint(); fp.fingerprint();
@ -578,9 +580,31 @@ public:
ClassLoaderData* cld_at(int index) { return _loaded_cld.at(index); } ClassLoaderData* cld_at(int index) { return _loaded_cld.at(index); }
}; };
// Check if a class or its super class/interface is old.
bool MetaspaceShared::is_old_class(InstanceKlass* ik) {
if (ik == NULL) {
return false;
}
if (ik->major_version() < 50 /*JAVA_6_VERSION*/) {
return true;
}
if (is_old_class(ik->java_super())) {
return true;
}
Array<InstanceKlass*>* interfaces = ik->local_interfaces();
int len = interfaces->length();
for (int i = 0; i < len; i++) {
if (is_old_class(interfaces->at(i))) {
return true;
}
}
return false;
}
bool MetaspaceShared::linking_required(InstanceKlass* ik) { bool MetaspaceShared::linking_required(InstanceKlass* ik) {
// For static CDS dump, do not link old classes.
// For dynamic CDS dump, only link classes loaded by the builtin class loaders. // For dynamic CDS dump, only link classes loaded by the builtin class loaders.
return DumpSharedSpaces ? true : !ik->is_shared_unregistered_class(); return DumpSharedSpaces ? !MetaspaceShared::is_old_class(ik) : !ik->is_shared_unregistered_class();
} }
bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) { bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) {
@ -760,7 +784,7 @@ bool MetaspaceShared::try_link_class(Thread* current, InstanceKlass* ik) {
ExceptionMark em(current); ExceptionMark em(current);
Thread* THREAD = current; // For exception macros. Thread* THREAD = current; // For exception macros.
Arguments::assert_is_dumping_archive(); Arguments::assert_is_dumping_archive();
if (ik->is_loaded() && !ik->is_linked() && if (ik->is_loaded() && !ik->is_linked() && !MetaspaceShared::is_old_class(ik) &&
!SystemDictionaryShared::has_class_failed_verification(ik)) { !SystemDictionaryShared::has_class_failed_verification(ik)) {
bool saved = BytecodeVerificationLocal; bool saved = BytecodeVerificationLocal;
if (ik->is_shared_unregistered_class() && ik->class_loader() == NULL) { if (ik->is_shared_unregistered_class() && ik->class_loader() == NULL) {
@ -806,7 +830,9 @@ void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray<Klass*>* k
Klass* k = klasses->at(i); Klass* k = klasses->at(i);
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k); InstanceKlass* ik = InstanceKlass::cast(k);
ik->constants()->add_dumped_interned_strings(); if (ik->is_linked()) {
ik->constants()->add_dumped_interned_strings();
}
} }
} }
if (_extra_interned_strings != NULL) { if (_extra_interned_strings != NULL) {

View file

@ -137,6 +137,7 @@ public:
static void link_and_cleanup_shared_classes(TRAPS) NOT_CDS_RETURN; static void link_and_cleanup_shared_classes(TRAPS) NOT_CDS_RETURN;
static bool link_class_for_cds(InstanceKlass* ik, TRAPS) NOT_CDS_RETURN_(false); static bool link_class_for_cds(InstanceKlass* ik, TRAPS) NOT_CDS_RETURN_(false);
static bool linking_required(InstanceKlass* ik) NOT_CDS_RETURN_(false); static bool linking_required(InstanceKlass* ik) NOT_CDS_RETURN_(false);
static bool is_old_class(InstanceKlass* ik);
#if INCLUDE_CDS #if INCLUDE_CDS
// Alignment for the 3 core CDS regions (MC/RW/RO) only. // Alignment for the 3 core CDS regions (MC/RW/RO) only.

View file

@ -405,7 +405,11 @@ void ConstMethod::copy_annotations_from(ClassLoaderData* loader_data, ConstMetho
void ConstMethod::metaspace_pointers_do(MetaspaceClosure* it) { void ConstMethod::metaspace_pointers_do(MetaspaceClosure* it) {
log_trace(cds)("Iter(ConstMethod): %p", this); log_trace(cds)("Iter(ConstMethod): %p", this);
it->push(&_constants); if (!method()->method_holder()->is_rewritten()) {
it->push(&_constants, MetaspaceClosure::_writable);
} else {
it->push(&_constants);
}
it->push(&_stackmap_data); it->push(&_stackmap_data);
if (has_method_annotations()) { if (has_method_annotations()) {
it->push(method_annotations_addr()); it->push(method_annotations_addr());
@ -419,7 +423,6 @@ void ConstMethod::metaspace_pointers_do(MetaspaceClosure* it) {
if (has_default_annotations()) { if (has_default_annotations()) {
it->push(default_annotations_addr()); it->push(default_annotations_addr());
} }
ConstMethod* this_ptr = this;
} }
// Printing // Printing

View file

@ -353,6 +353,9 @@ void ConstantPool::add_dumped_interned_strings() {
// CDS support. Create a new resolved_references array. // CDS support. Create a new resolved_references array.
void ConstantPool::restore_unshareable_info(TRAPS) { void ConstantPool::restore_unshareable_info(TRAPS) {
if (!_pool_holder->is_linked() && !_pool_holder->is_rewritten()) {
return;
}
assert(is_constantPool(), "ensure C++ vtable is restored"); assert(is_constantPool(), "ensure C++ vtable is restored");
assert(on_stack(), "should always be set for shared constant pools"); assert(on_stack(), "should always be set for shared constant pools");
assert(is_shared(), "should always be set for shared constant pools"); assert(is_shared(), "should always be set for shared constant pools");
@ -390,6 +393,9 @@ void ConstantPool::restore_unshareable_info(TRAPS) {
} }
void ConstantPool::remove_unshareable_info() { void ConstantPool::remove_unshareable_info() {
if (!_pool_holder->is_linked() && _pool_holder->is_shared_old_klass()) {
return;
}
// Resolved references are not in the shared archive. // Resolved references are not in the shared archive.
// Save the length for restoration. It is not necessarily the same length // Save the length for restoration. It is not necessarily the same length
// as reference_map.length() if invokedynamic is saved. It is needed when // as reference_map.length() if invokedynamic is saved. It is needed when

View file

@ -2454,7 +2454,11 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_annotations); it->push(&_annotations);
it->push((Klass**)&_array_klasses); it->push((Klass**)&_array_klasses);
it->push(&_constants); if (!is_rewritten()) {
it->push(&_constants, MetaspaceClosure::_writable);
} else {
it->push(&_constants);
}
it->push(&_inner_classes); it->push(&_inner_classes);
#if INCLUDE_JVMTI #if INCLUDE_JVMTI
it->push(&_previous_versions); it->push(&_previous_versions);
@ -2491,6 +2495,12 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
} }
void InstanceKlass::remove_unshareable_info() { void InstanceKlass::remove_unshareable_info() {
if (MetaspaceShared::is_old_class(this)) {
// Set the old class bit.
set_is_shared_old_klass();
}
Klass::remove_unshareable_info(); Klass::remove_unshareable_info();
if (SystemDictionaryShared::has_class_failed_verification(this)) { if (SystemDictionaryShared::has_class_failed_verification(this)) {

View file

@ -177,7 +177,8 @@ private:
u2 _shared_class_flags; u2 _shared_class_flags;
enum { enum {
_archived_lambda_proxy_is_available = 2, _archived_lambda_proxy_is_available = 2,
_has_value_based_class_annotation = 4 _has_value_based_class_annotation = 4,
_is_shared_old_klass = 8
}; };
#endif #endif
@ -333,6 +334,14 @@ protected:
NOT_CDS(return false;) NOT_CDS(return false;)
} }
void set_is_shared_old_klass() {
CDS_ONLY(_shared_class_flags |= _is_shared_old_klass;)
}
bool is_shared_old_klass() const {
CDS_ONLY(return (_shared_class_flags & _is_shared_old_klass) != 0;)
NOT_CDS(return false;)
}
// Obtain the module or package for this class // Obtain the module or package for this class
virtual ModuleEntry* module() const = 0; virtual ModuleEntry* module() const = 0;

View file

@ -51,7 +51,7 @@ inline InstanceKlass* klassVtable::ik() const {
} }
bool klassVtable::is_preinitialized_vtable() { bool klassVtable::is_preinitialized_vtable() {
return _klass->is_shared() && !MetaspaceShared::remapped_readwrite(); return _klass->is_shared() && !MetaspaceShared::remapped_readwrite() && !_klass->is_shared_old_klass();
} }
@ -1093,7 +1093,8 @@ void itableMethodEntry::initialize(Method* m) {
#ifdef ASSERT #ifdef ASSERT
if (MetaspaceShared::is_in_shared_metaspace((void*)&_method) && if (MetaspaceShared::is_in_shared_metaspace((void*)&_method) &&
!MetaspaceShared::remapped_readwrite()) { !MetaspaceShared::remapped_readwrite() &&
!MetaspaceShared::is_old_class(m->method_holder())) {
// At runtime initialize_itable is rerun as part of link_class_impl() // At runtime initialize_itable is rerun as part of link_class_impl()
// for a shared class loaded by the non-boot loader. // for a shared class loaded by the non-boot loader.
// The dumptime itable method entry should be the same as the runtime entry. // The dumptime itable method entry should be the same as the runtime entry.

View file

@ -344,11 +344,13 @@ Symbol* Method::klass_name() const {
void Method::metaspace_pointers_do(MetaspaceClosure* it) { void Method::metaspace_pointers_do(MetaspaceClosure* it) {
log_trace(cds)("Iter(Method): %p", this); log_trace(cds)("Iter(Method): %p", this);
it->push(&_constMethod); if (!method_holder()->is_rewritten()) {
it->push(&_constMethod, MetaspaceClosure::_writable);
} else {
it->push(&_constMethod);
}
it->push(&_method_data); it->push(&_method_data);
it->push(&_method_counters); it->push(&_method_counters);
Method* this_ptr = this;
} }
// Attempt to return method to original state. Clear any pointers // Attempt to return method to original state. Clear any pointers
@ -362,7 +364,7 @@ void Method::remove_unshareable_info() {
} }
void Method::set_vtable_index(int index) { void Method::set_vtable_index(int index) {
if (is_shared() && !MetaspaceShared::remapped_readwrite()) { if (is_shared() && !MetaspaceShared::remapped_readwrite() && !method_holder()->is_shared_old_klass()) {
// At runtime initialize_vtable is rerun as part of link_class_impl() // At runtime initialize_vtable is rerun as part of link_class_impl()
// for a shared class loaded by the non-boot loader to obtain the loader // for a shared class loaded by the non-boot loader to obtain the loader
// constraints based on the runtime classloaders' context. // constraints based on the runtime classloaders' context.
@ -373,7 +375,7 @@ void Method::set_vtable_index(int index) {
} }
void Method::set_itable_index(int index) { void Method::set_itable_index(int index) {
if (is_shared() && !MetaspaceShared::remapped_readwrite()) { if (is_shared() && !MetaspaceShared::remapped_readwrite() && !method_holder()->is_shared_old_klass()) {
// At runtime initialize_itable is rerun as part of link_class_impl() // At runtime initialize_itable is rerun as part of link_class_impl()
// for a shared class loaded by the non-boot loader to obtain the loader // for a shared class loaded by the non-boot loader to obtain the loader
// constraints based on the runtime classloaders' context. The dumptime // constraints based on the runtime classloaders' context. The dumptime

View file

@ -68,7 +68,7 @@ public class LambdaWithOldClass {
.addSuffix(mainClass); .addSuffix(mainClass);
OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts); OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts);
output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file") output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file")
.shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda[$].*/0x.*source:.*LambdaWithOldClassApp") .shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda[$].*/0x.*source:.*shared objects file")
.shouldHaveExitValue(0); .shouldHaveExitValue(0);
} }
} }

View file

@ -24,7 +24,7 @@
/* /*
* @test * @test
* @summary classes with major version < JDK_6 (50) should not be included in CDS * @summary CDS support of old classes with major version < JDK_6 (50) for static archive.
* @requires vm.cds * @requires vm.cds
* @library /test/lib * @library /test/lib
* @modules java.base/jdk.internal.org.objectweb.asm * @modules java.base/jdk.internal.org.objectweb.asm
@ -35,6 +35,7 @@
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.OutputAnalyzer;
import java.nio.file.Files; import java.nio.file.Files;
@ -55,26 +56,47 @@ public class OldClassTest implements Opcodes {
} }
String appClasses[] = TestCommon.list("Hello"); String appClasses[] = TestCommon.list("Hello");
boolean dynamicMode = CDSTestUtils.DYNAMIC_DUMP;
// CASE 1: pre-JDK 6 compiled classes should be excluded from the dump // CASE 1: pre-JDK 6 compiled classes should be excluded from the dump
OutputAnalyzer output = TestCommon.dump(jar, appClasses); OutputAnalyzer output = TestCommon.dump(jar, appClasses, "-Xlog:class+load,cds=debug");
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 6 class not supported by CDS"); TestCommon.checkExecReturn(output, 0,
dynamicMode ? true : false,
"Pre JDK 6 class not supported by CDS");
TestCommon.run( TestCommon.run(
"-cp", jar, "-cp", jar,
"-Xlog:class+load",
"Hello") "Hello")
.assertNormalExit("Hello Unicode world (Old)"); .assertNormalExit(out -> {
out.shouldContain("Hello Unicode world (Old)");
if (!dynamicMode) {
out.shouldContain("Hello source: shared objects file");
} else {
out.shouldMatch(".class.load. Hello source:.*OldClassTest_old.jar");
}
});
// CASE 2: if we exlcude old version of this class, we should not pick up // CASE 2: if we exlcude old version of this class, we should not pick up
// the newer version of this class in a subsequent classpath element. // the newer version of this class in a subsequent classpath element.
String classpath = jar + File.pathSeparator + jarSrcFile.getPath(); String classpath = jar + File.pathSeparator + jarSrcFile.getPath();
output = TestCommon.dump(classpath, appClasses); output = TestCommon.dump(classpath, appClasses);
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 6 class not supported by CDS"); TestCommon.checkExecReturn(output, 0,
dynamicMode ? true : false,
"Pre JDK 6 class not supported by CDS");
TestCommon.run( TestCommon.run(
"-cp", classpath, "-cp", classpath,
"-Xlog:class+load",
"Hello") "Hello")
.assertNormalExit("Hello Unicode world (Old)"); .assertNormalExit(out -> {
out.shouldContain("Hello Unicode world (Old)");
if (!dynamicMode) {
out.shouldContain("Hello source: shared objects file");
} else {
out.shouldMatch(".class.load. Hello source:.*OldClassTest_old.jar");
}
});
} }
static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception { static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8261090
* @summary CDS support of old classes with major version < JDK_6 (50) for static archive.
* Test with old super class.
* @requires vm.cds
* @library /test/lib
* @compile test-classes/OldSuper.jasm
* @compile test-classes/ChildOldSuper.java
* @compile test-classes/GChild.java
* @compile test-classes/OldSuperApp.java
* @run driver OldSuperClass
*/
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
public class OldSuperClass {
public static void main(String[] args) throws Exception {
String mainClass = "OldSuperApp";
String namePrefix = "oldsuperclass";
String appClasses[] = TestCommon.list("OldSuper", "ChildOldSuper", "GChild", mainClass);
JarBuilder.build(namePrefix, appClasses);
String appJar = TestCommon.getTestJar(namePrefix + ".jar");
boolean dynamicMode = CDSTestUtils.DYNAMIC_DUMP;
// create archive with class list
OutputAnalyzer output = TestCommon.dump(appJar, appClasses, "-Xlog:class+load,cds=debug,verification=trace");
TestCommon.checkExecReturn(output, 0,
dynamicMode ? true : false,
"Pre JDK 6 class not supported by CDS: 49.0 OldSuper",
"Skipping ChildOldSuper: Old class has been linked",
"Skipping GChild: Old class has been linked");
// run with archive
TestCommon.run(
"-cp", appJar,
"-Xlog:class+load,cds=debug,verification=trace",
mainClass)
.assertNormalExit(out -> {
out.shouldContain("Verifying class OldSuper with old format")
.shouldContain("Verifying class ChildOldSuper with new format")
.shouldContain("Verifying class GChild with new format");
if (!dynamicMode) {
out.shouldContain("OldSuper source: shared objects file")
.shouldContain("ChildOldSuper source: shared objects file")
.shouldContain("GChild source: shared objects file");
} else {
// Old classes were already linked before dynamic dump happened,
// so they couldn't be archived.
out.shouldMatch(".class.load.*OldSuper source:.*oldsuperclass.jar")
.shouldMatch(".class.load.*ChildOldSuper source:.*oldsuperclass.jar")
.shouldMatch(".class.load.*GChild source:.*oldsuperclass.jar");
}
});
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8261090
* @summary CDS support of old classes with major version < JDK_6 (50) for static archive.
* Test with old super interface.
* @requires vm.cds
* @library /test/lib
* @compile test-classes/OldInf.jasm
* @compile test-classes/ChildOldInf.java
* @compile test-classes/GChild2.java
* @compile test-classes/OldSuperInfApp.java
* @run driver OldSuperInf
*/
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
public class OldSuperInf {
public static void main(String[] args) throws Exception {
String mainClass = "OldSuperInfApp";
String namePrefix = "oldsuperinf";
String appClasses[] = TestCommon.list("OldInf", "ChildOldInf", "GChild2", mainClass);
JarBuilder.build(namePrefix, appClasses);
String appJar = TestCommon.getTestJar(namePrefix + ".jar");
String archiveName = namePrefix + ".jsa";
boolean dynamicMode = CDSTestUtils.DYNAMIC_DUMP;
// create archive with class list
OutputAnalyzer output = TestCommon.dump(appJar, appClasses, "-Xlog:class+load,cds=debug,verification=trace");
TestCommon.checkExecReturn(output, 0,
dynamicMode ? true : false,
"Pre JDK 6 class not supported by CDS: 49.0 OldInf",
"Skipping ChildOldInf: Old class has been linked",
"Skipping GChild2: Old class has been linked");
// run with archive
TestCommon.run(
"-cp", appJar,
"-Xlog:class+load,cds=debug,verification=trace",
mainClass)
.assertNormalExit(out -> {
out.shouldContain("Verifying class OldInf with old format")
.shouldContain("Verifying class ChildOldInf with new format")
.shouldContain("Verifying class GChild2 with new format");
if (!dynamicMode) {
out.shouldContain("OldInf source: shared objects file")
.shouldContain("ChildOldInf source: shared objects file")
.shouldContain("GChild2 source: shared objects file");
} else {
// Old classes were already linked before dynamic dump happened,
// so they couldn't be archived.
out.shouldMatch(".class.load.*OldInf source:.*oldsuperinf.jar")
.shouldMatch(".class.load.*ChildOldInf source:.*oldsuperinf.jar")
.shouldMatch(".class.load.*GChild2 source:.*oldsuperinf.jar");
}
});
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8261090
* @summary Test archiving of old class and interface with custom loader.
* @requires vm.cds
* @requires vm.cds.custom.loaders
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
* @compile test-classes/OldClassApp.java ../test-classes/OldSuper.jasm
* @compile ../test-classes/ChildOldSuper.java ../test-classes/GChild.java
* @compile ../test-classes/OldInf.jasm ../test-classes/ChildOldInf.java
* @compile ../test-classes/GChild2.java
* @build sun.hotspot.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar oldclassapp.jar OldClassApp
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar loadees.jar OldSuper ChildOldSuper GChild
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar loadees2.jar OldInf ChildOldInf GChild2
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
* @run driver OldClassAndInf
*/
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.helpers.ClassFileInstaller;
import sun.hotspot.WhiteBox;
public class OldClassAndInf {
static String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
static String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
static String appJar = ClassFileInstaller.getJarPath("oldclassapp.jar");
static String loadeesJar = ClassFileInstaller.getJarPath("loadees.jar");
static String loadeesJar2 = ClassFileInstaller.getJarPath("loadees2.jar");
public static void main(String[] args) throws Exception {
String classlist[] = new String[] {
"OldClassApp",
"java/lang/Object id: 1",
"OldSuper id: 2 super: 1 source: " + loadeesJar,
"ChildOldSuper id: 3 super: 2 source: " + loadeesJar,
"GChild id: 4 super: 3 source: " + loadeesJar
};
doTest(classlist, loadeesJar, "true", "OldSuper", "ChildOldSuper", "GChild");
String classlist2[] = new String[] {
"OldClassApp",
"java/lang/Object id: 1",
"OldInf id: 2 super: 1 source: " + loadeesJar2,
"ChildOldInf id: 3 super: 1 interfaces: 2 source: " + loadeesJar2,
"GChild2 id: 4 super: 3 source: " + loadeesJar2
};
doTest(classlist2, loadeesJar2, "true", "OldInf", "ChildOldInf", "GChild2");
}
public static void doTest(String[] classlist, String loadeesJar, String inArchive, String ...loadees) throws Exception {
OutputAnalyzer output;
TestCommon.testDump(appJar, classlist,
"-Xlog:cds=debug,class+load",
use_whitebox_jar);
output = TestCommon.exec(appJar,
TestCommon.concat(
TestCommon.list(
use_whitebox_jar,
"-Xlog:class+load,cds=debug",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"OldClassApp", loadeesJar, inArchive),
loadees));
TestCommon.checkExec(output);
for (String loadee : loadees) {
output.shouldContain("[class,load] " + loadee + " source: shared objects file");
}
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import sun.hotspot.WhiteBox;
public class OldClassApp {
public static void main(String args[]) throws Exception {
String path = args[0];
URL url = new File(path).toURI().toURL();
URL[] urls = new URL[] {url};
System.out.println(path);
System.out.println(url);
boolean inArchive = false;
if (args[1].equals("true")) {
inArchive = true;
} else if (args[1].equals("false")) {
inArchive = false;
} else {
throw new RuntimeException("args[1] can only be either \"true\" or \"false\", actual " + args[1]);
}
URLClassLoader urlClassLoader =
new URLClassLoader("OldClassAppClassLoader", urls, null);
for (int i = 2; i < args.length; i++) {
Class c = urlClassLoader.loadClass(args[i]);
System.out.println(c);
System.out.println(c.getClassLoader());
// [1] Check that class is defined by the correct loader
if (c.getClassLoader() != urlClassLoader) {
throw new RuntimeException("c.getClassLoader() == " + c.getClassLoader() +
", expected == " + urlClassLoader);
}
// [2] Check that class is loaded from shared static archive.
if (inArchive) {
WhiteBox wb = WhiteBox.getWhiteBox();
if (wb.isSharedClass(OldClassApp.class)) {
if (!wb.isSharedClass(c)) {
throw new RuntimeException("wb.isSharedClass(c) should be true");
}
}
}
}
}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8261090
* @summary Test archiving of old class and interface with custom loader with dynamic CDS.
* @requires vm.cds
* @requires vm.cds.custom.loaders
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
* @compile ../customLoader/test-classes/OldClassApp.java ../test-classes/OldSuper.jasm
* @compile ../test-classes/ChildOldSuper.java ../test-classes/GChild.java
* @compile ../test-classes/OldInf.jasm ../test-classes/ChildOldInf.java
* @compile ../test-classes/GChild2.java
* @build sun.hotspot.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar oldclassapp.jar OldClassApp
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar loadees.jar OldSuper ChildOldSuper GChild
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar loadees2.jar OldInf ChildOldInf GChild2
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar OldClassAndInf
*/
import java.io.File;
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.helpers.ClassFileInstaller;
public class OldClassAndInf extends DynamicArchiveTestBase {
private static final String ARCHIVE_NAME = CDSTestUtils.getOutputFileName("oldclass-top.jsa");
private static String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
private static String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar;
private static String appJar = ClassFileInstaller.getJarPath("oldclassapp.jar");
private static String mainAppClass = "OldClassApp";
public static void main(String[] args) throws Exception {
runTest(OldClassAndInf::testDefaultBase);
}
private static void testDefaultBase() throws Exception {
System.out.println("Run test with old super class...");
String loadeesJar = ClassFileInstaller.getJarPath("loadees.jar");
doTest(loadeesJar, "false", "OldSuper", "ChildOldSuper", "GChild");
System.out.println("Run test with old super interface...");
String loadeesJar2 = ClassFileInstaller.getJarPath("loadees2.jar");
doTest(loadeesJar2, "false", "OldInf", "ChildOldInf", "GChild2");
}
private static void doTest(String loadeesJar, String inArchive, String ...loadees) throws Exception {
String[] loadeesArray = TestCommon.list(loadees);
dump(ARCHIVE_NAME,
TestCommon.concat(
TestCommon.list(
use_whitebox_jar,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-Xlog:cds",
"-Xlog:cds+dynamic=debug",
"-cp", appJar,
mainAppClass, loadeesJar, inArchive),
loadees))
.assertNormalExit(output -> {
output.shouldContain("Written dynamic archive 0x")
.shouldContain("Pre JDK 6 class not supported by CDS: 49.0 " + loadeesArray[0])
.shouldMatch("Skipping " + loadeesArray[1] +":.*" + loadeesArray[0] + " is excluded")
.shouldMatch("Skipping " + loadeesArray[2] +": super.*" + loadeesArray[1] + " is excluded")
.shouldHaveExitValue(0);
});
run(ARCHIVE_NAME,
TestCommon.concat(
TestCommon.list(
use_whitebox_jar,
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-Xlog:class+load",
"-Xlog:cds=debug",
"-Xlog:cds+dynamic=info",
"-cp", appJar,
mainAppClass, loadeesJar, inArchive),
loadees))
.assertNormalExit(output -> {
output.shouldHaveExitValue(0);
for (String loadee : loadees) {
output.shouldMatch(".class.load. " + loadee + " source:.*" + loadeesJar);
}
});
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
* @test
* @bug 8261090
* @summary Dump old class with java agent.
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
* @requires vm.cds
* @requires vm.jvmti
* @compile ../../test-classes/OldSuper.jasm
* @compile SimpleAgent.java
* @run main/othervm OldClassWithJavaAgent
*/
import jdk.test.lib.cds.CDSOptions;
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.helpers.ClassFileInstaller;
public class OldClassWithJavaAgent {
public static String appClasses[] = {"OldSuper"};
public static String agentClasses[] = {"SimpleAgent"};
public static String diagnosticOption = "-XX:+AllowArchivingWithJavaAgent";
public static void main(String[] args) throws Throwable {
String agentJar =
ClassFileInstaller.writeJar("SimpleAgent.jar",
ClassFileInstaller.Manifest.fromSourceFile("SimpleAgent.mf"),
agentClasses);
String appJar =
ClassFileInstaller.writeJar("OldClassWithJavaAgent.jar", appClasses);
OutputAnalyzer output = TestCommon.testDump(appJar, TestCommon.list("OldSuper"),
"-Xlog:cds=debug,class+load",
"-XX:+UnlockDiagnosticVMOptions", diagnosticOption,
"-javaagent:" + agentJar + "=OldSuper");
boolean dynamicMode = CDSTestUtils.DYNAMIC_DUMP;
// The java agent will load and link the class. We will skip old classes
// which have been linked during static CDS dump.
// Dynamic CDS dump doesn't support old class.
if (!dynamicMode) {
output.shouldContain("Skipping OldSuper: Old class has been linked");
} else {
output.shouldContain("Pre JDK 6 class not supported by CDS: 49.0 OldSuper");
}
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,11 @@
import java.lang.instrument.Instrumentation; import java.lang.instrument.Instrumentation;
public class SimpleAgent { public class SimpleAgent {
public static void premain(String agentArg, Instrumentation instrumentation) { public static void premain(String agentArg, Instrumentation instrumentation) throws Exception {
System.out.println("inside SimpleAgent"); System.out.println("inside SimpleAgent");
// Only load the class if the test requires it.
if (agentArg != null && agentArg.equals("OldSuper")) {
Class<?> cls = Class.forName("OldSuper", true, ClassLoader.getSystemClassLoader());
}
} }
} }

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class ChildOldInf implements OldInf {
public String doit() {
return "ChildOldInf";
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class ChildOldSuper extends OldSuper {
public String doit() {
return super.doit();
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class GChild extends ChildOldSuper {
public String doit() {
return super.doit();
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class GChild2 extends ChildOldInf {
public String doit() {
return super.doit();
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public interface OldInf
version 49:0
{
public abstract Method doit:"()Ljava/lang/String;";
} // end Class OldInf

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
super public class OldSuper
version 49:0
{
public Method "<init>":"()V"
stack 1 locals 1
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
public Method doit:"()Ljava/lang/String;"
stack 1 locals 1
{
ldc String "Hello";
areturn;
}
} // end Class OldSuper

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class OldSuperApp {
public static void main(String args[]) {
ChildOldSuper c = new ChildOldSuper();
System.out.println(c.doit());
GChild g = new GChild();
System.out.println(g.doit());
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
public class OldSuperInfApp {
public static void main(String args[]) {
ChildOldInf c = new ChildOldInf();
System.out.println(c.doit());
GChild2 g = new GChild2();
System.out.println(g.doit());
}
}