mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8261090: Store old classfiles in static CDS archive
Reviewed-by: iklam, minqi
This commit is contained in:
parent
159f5e1ede
commit
9499175064
29 changed files with 895 additions and 42 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
81
test/hotspot/jtreg/runtime/cds/appcds/OldSuperClass.java
Normal file
81
test/hotspot/jtreg/runtime/cds/appcds/OldSuperClass.java
Normal 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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
84
test/hotspot/jtreg/runtime/cds/appcds/OldSuperInf.java
Normal file
84
test/hotspot/jtreg/runtime/cds/appcds/OldSuperInf.java
Normal 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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue