mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-29 08:05:14 +00:00
8354558: -XX:AOTMode=record crashes with boot loader package-info class
Reviewed-by: ccheung, matsaave
This commit is contained in:
parent
b10a304b2b
commit
bbec3c0730
@ -1219,6 +1219,7 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
|
||||
// must be valid since the class has been successfully parsed.
|
||||
const char* path = ClassLoader::uri_to_path(src);
|
||||
assert(path != nullptr, "sanity");
|
||||
bool found_invalid = false;
|
||||
AOTClassLocationConfig::dumptime_iterate([&] (AOTClassLocation* cl) {
|
||||
int i = cl->index();
|
||||
// for index 0 and the stream->source() is the modules image or has the jrt: protocol.
|
||||
@ -1242,10 +1243,15 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
|
||||
classpath_index = i;
|
||||
} else {
|
||||
if (cl->from_boot_classpath()) {
|
||||
// The class must be from boot loader append path which consists of
|
||||
// -Xbootclasspath/a and jvmti appended entries.
|
||||
assert(loader == nullptr, "sanity");
|
||||
classpath_index = i;
|
||||
if (loader != nullptr) {
|
||||
// Probably loaded by jdk/internal/loader/ClassLoaders$BootClassLoader. Don't archive
|
||||
// such classes.
|
||||
ik->set_shared_classpath_index(-1);
|
||||
ik->set_shared_class_loader_type(ClassLoader::BOOT_LOADER);
|
||||
found_invalid = true;
|
||||
} else {
|
||||
classpath_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1256,13 +1262,17 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classpath_index >= 0) {
|
||||
if (classpath_index >= 0 || found_invalid) {
|
||||
return false; // quit iterating
|
||||
} else {
|
||||
return true; // Keep iterating
|
||||
}
|
||||
});
|
||||
|
||||
if (found_invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No path entry found for this class: most likely a shared class loaded by the
|
||||
// user defined classloader.
|
||||
if (classpath_index < 0 && !SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) {
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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
|
||||
* @summary AOT cache handling for package-info class loaded by jdk/internal/loader/ClassLoaders$BootClassLoader
|
||||
* @bug 8354558
|
||||
* @requires vm.cds.supports.aot.class.linking
|
||||
* @comment work around JDK-8345635
|
||||
* @requires !vm.jvmci.enabled
|
||||
* @library /test/lib /test/jdk/java/lang/Package/bootclasspath/boot
|
||||
* @build PackageInfoClass foo.Foo foo.MyAnnotation foo.package-info
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar foo.Foo foo.package-info foo.MyAnnotation
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar PackageInfoClassApp
|
||||
* @run driver PackageInfoClass AOT
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.cds.CDSAppTester.RunMode;
|
||||
import jdk.test.lib.cds.SimpleCDSAppTester;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class PackageInfoClass {
|
||||
public static void main(String... args) throws Exception {
|
||||
SimpleCDSAppTester.of("PackageInfoClass")
|
||||
.classpath("app.jar")
|
||||
.addVmArgs("-Xbootclasspath/a:boot.jar")
|
||||
.appCommandLine("PackageInfoClassApp")
|
||||
.setAssemblyChecker((OutputAnalyzer out, RunMode runMode) -> {
|
||||
if (runMode == RunMode.TRAINING) {
|
||||
out.shouldContain("Skipping foo/package-info: Unsupported location");
|
||||
}
|
||||
})
|
||||
.runAOTWorkflow();
|
||||
}
|
||||
}
|
||||
|
||||
class PackageInfoClassApp {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// This code is taken from test/jdk/java/lang/Package/bootclasspath/GetPackageFromBootClassPath.java
|
||||
Class<?> c = Class.forName("foo.Foo", false, null);
|
||||
Package p = c.getPackage();
|
||||
Annotation[] annotations = p.getAnnotations();
|
||||
Class<?> annType = Class.forName("foo.MyAnnotation", false, null);
|
||||
if (annotations.length != 1 ||
|
||||
annotations[0].annotationType() != annType) {
|
||||
throw new RuntimeException("Expected foo.MyAnnotation but got " +
|
||||
Arrays.toString(annotations));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,7 +86,7 @@ abstract public class CDSAppTester {
|
||||
}
|
||||
|
||||
public enum RunMode {
|
||||
TRAINING, // -XX:DumpLoadedClassList OR {-XX:AOTMode=create -XX:AOTConfiguration}
|
||||
TRAINING, // -XX:DumpLoadedClassList OR {-XX:AOTMode=record -XX:AOTConfiguration}
|
||||
DUMP_STATIC, // -Xshare:dump
|
||||
DUMP_DYNAMIC, // -XX:ArchiveClassesArExit
|
||||
ASSEMBLY, // JEP 483 (assembly phase, app logic not executed)
|
||||
|
||||
@ -24,11 +24,13 @@
|
||||
package jdk.test.lib.cds;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jdk.test.lib.cds.CDSAppTester.RunMode;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.StringArrayUtils;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/*
|
||||
* A simpler way to use CDSAppTester. Example:
|
||||
*
|
||||
@ -49,8 +51,8 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class SimpleCDSAppTester {
|
||||
private String name;
|
||||
private Consumer<OutputAnalyzer> assemblyChecker;
|
||||
private Consumer<OutputAnalyzer> productionChecker;
|
||||
private BiConsumer<OutputAnalyzer, RunMode> assemblyChecker;
|
||||
private BiConsumer<OutputAnalyzer, RunMode> productionChecker;
|
||||
private String classpath;
|
||||
private String modulepath;
|
||||
private String[] appCommandLine;
|
||||
@ -98,16 +100,31 @@ public class SimpleCDSAppTester {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCDSAppTester setAssemblyChecker(Consumer<OutputAnalyzer> checker) {
|
||||
public SimpleCDSAppTester setAssemblyChecker(BiConsumer<OutputAnalyzer, RunMode> checker) {
|
||||
this.assemblyChecker = checker;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCDSAppTester setProductionChecker(Consumer<OutputAnalyzer> checker) {
|
||||
public SimpleCDSAppTester setProductionChecker(BiConsumer<OutputAnalyzer, RunMode> checker) {
|
||||
this.productionChecker = checker;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public SimpleCDSAppTester setAssemblyChecker(Consumer<OutputAnalyzer> checker) {
|
||||
this.assemblyChecker = (OutputAnalyzer out, RunMode runMode) -> {
|
||||
checker.accept(out);
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
public SimpleCDSAppTester setProductionChecker(Consumer<OutputAnalyzer> checker) {
|
||||
this.productionChecker = (OutputAnalyzer out, RunMode runMode) -> {
|
||||
checker.accept(out);
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
class Tester extends CDSAppTester {
|
||||
public Tester(String name) {
|
||||
super(name);
|
||||
@ -137,11 +154,11 @@ public class SimpleCDSAppTester {
|
||||
public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {
|
||||
if (isDumping(runMode) && runMode != RunMode.TRAINING) {
|
||||
if (assemblyChecker != null) {
|
||||
assemblyChecker.accept(out);
|
||||
assemblyChecker.accept(out, runMode);
|
||||
}
|
||||
} else if (runMode.isProductionRun()) {
|
||||
if (productionChecker != null) {
|
||||
productionChecker.accept(out);
|
||||
productionChecker.accept(out, runMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user