Skip to content

Commit 841ab48

Browse files
committed
8322657: CDS filemap fastdebug assert while loading Graal CE Polyglot in isolated classloader
Reviewed-by: matsaave, dholmes
1 parent 61ebe3b commit 841ab48

File tree

6 files changed

+188
-9
lines changed

6 files changed

+188
-9
lines changed

src/hotspot/share/cds/filemap.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -576,12 +576,14 @@ int FileMapInfo::get_module_shared_path_index(Symbol* location) {
576576
const char* file = ClassLoader::skip_uri_protocol(location->as_C_string());
577577
for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) {
578578
SharedClassPathEntry* ent = shared_path(i);
579-
assert(ent->in_named_module(), "must be");
580-
bool cond = strcmp(file, ent->name()) == 0;
581-
log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i,
582-
location->as_C_string(), ent->name(), cond ? "same" : "different");
583-
if (cond) {
584-
return i;
579+
if (!ent->is_non_existent()) {
580+
assert(ent->in_named_module(), "must be");
581+
bool cond = strcmp(file, ent->name()) == 0;
582+
log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i,
583+
location->as_C_string(), ent->name(), cond ? "same" : "different");
584+
if (cond) {
585+
return i;
586+
}
585587
}
586588
}
587589

src/hotspot/share/cds/filemap.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -89,6 +89,7 @@ class SharedClassPathEntry : public MetaspaceObj {
8989
bool is_dir() const { return _type == dir_entry; }
9090
bool is_modules_image() const { return _type == modules_image_entry; }
9191
bool is_jar() const { return _type == jar_entry; }
92+
bool is_non_existent() const { return _type == non_existent_entry; }
9293
bool from_class_path_attr() { return _from_class_path_attr; }
9394
time_t timestamp() const { return _timestamp; }
9495
const char* name() const;

test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -199,6 +199,23 @@ public static void createModularJar(String jarPath,
199199
createJar(argList);
200200
}
201201

202+
public static void createModularJarWithManifest(String jarPath,
203+
String classesDir,
204+
String mainClass,
205+
String manifest) throws Exception {
206+
ArrayList<String> argList = new ArrayList<String>();
207+
argList.add("--create");
208+
argList.add("--file=" + jarPath);
209+
if (mainClass != null) {
210+
argList.add("--main-class=" + mainClass);
211+
}
212+
argList.add("--manifest=" + manifest);
213+
argList.add("-C");
214+
argList.add(classesDir);
215+
argList.add(".");
216+
createJar(argList);
217+
}
218+
202219
private static void createJar(ArrayList<String> args) {
203220
if (DEBUG) printIterable("createJar args: ", args);
204221

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
/**
26+
* @test
27+
* @bug 8322657
28+
* @summary This test defines an application module using the DefineModuleApp.
29+
* When performing dynamic dump, the modular jar containing the module
30+
* is in the -cp. The jar listed in the "Class-Path" attribute of the modular
31+
* jar doesn't exist. VM should not crash during dynamic dump under this scenario.
32+
* @requires vm.cds
33+
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
34+
* /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes
35+
* @build jdk.test.whitebox.WhiteBox DefineModuleApp
36+
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
37+
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar define_module_app.jar DefineModuleApp
38+
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. ModularJarWithNonExistentJar
39+
*/
40+
41+
import java.io.File;
42+
import java.nio.file.Files;
43+
import java.nio.file.Path;
44+
import java.nio.file.Paths;
45+
46+
import jdk.test.lib.cds.CDSTestUtils;
47+
import jdk.test.lib.helpers.ClassFileInstaller;
48+
49+
public class ModularJarWithNonExistentJar extends DynamicArchiveTestBase {
50+
private static final Path USER_DIR = Paths.get(CDSTestUtils.getOutputDir());
51+
52+
private static final String TEST_SRC = System.getProperty("test.src");
53+
54+
private static final Path SRC_DIR = Paths.get(TEST_SRC, "../jigsaw/modulepath/src");
55+
private static final Path MODS_DIR = Paths.get("mods");
56+
private static final Path MANIFEST_PATH = Paths.get(TEST_SRC, "test-classes/manifest-with-non-existent-jar.txt");
57+
58+
// the module name of the test module
59+
private static final String TEST_MODULE = "com.simple";
60+
61+
// the module main class
62+
private static final String MAIN_CLASS = "com.simple.Main";
63+
64+
private static Path moduleDir = null;
65+
private static Path modularJar = null;
66+
67+
public static void buildTestModule() throws Exception {
68+
69+
// javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/**
70+
JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE),
71+
MODS_DIR.resolve(TEST_MODULE),
72+
MODS_DIR.toString());
73+
74+
75+
moduleDir = Files.createTempDirectory(USER_DIR, "mlib");
76+
77+
modularJar = moduleDir.resolve(TEST_MODULE + ".jar");
78+
String classes = MODS_DIR.resolve(TEST_MODULE).toString();
79+
JarBuilder.createModularJarWithManifest(modularJar.toString(), classes,
80+
MAIN_CLASS, MANIFEST_PATH.toString());
81+
}
82+
83+
public static void main(String... args) throws Exception {
84+
runTest(ModularJarWithNonExistentJar::testDefaultBase);
85+
}
86+
87+
static void testDefaultBase() throws Exception {
88+
String topArchiveName = getNewArchiveName("top");
89+
doTest(topArchiveName);
90+
}
91+
92+
private static void doTest(String topArchiveName) throws Exception {
93+
// compile the module and create the modular jar file
94+
buildTestModule();
95+
String appJar = ClassFileInstaller.getJarPath("define_module_app.jar");
96+
dump(topArchiveName,
97+
"-Xlog:cds,class+path=info",
98+
"-Xlog:cds+dynamic=debug",
99+
"-cp", appJar + File.pathSeparator + modularJar.toString(),
100+
"DefineModuleApp", moduleDir.toString(), TEST_MODULE)
101+
.assertNormalExit(output -> {
102+
output.shouldContain("Written dynamic archive 0x");
103+
});
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
/**
26+
* This app defines a module using the ModuleLayer.defineModulesWithOneLoader API
27+
* which calls the JVM_DefineModule.
28+
**/
29+
30+
import java.nio.file.Path;
31+
import java.lang.ModuleLayer.Controller;
32+
import java.lang.module.*;
33+
import java.util.List;
34+
import java.util.Set;
35+
36+
public class DefineModuleApp {
37+
public static void main(String[] args) throws Throwable {
38+
if (args.length != 2) {
39+
throw new RuntimeException("DefineModuleApp expects 2 args but saw " + args.length);
40+
}
41+
final Path MODS = Path.of(args[0]);
42+
final String MODULE_NAME = args[1];
43+
Configuration cf = ModuleLayer.boot()
44+
.configuration()
45+
.resolve(ModuleFinder.of(), ModuleFinder.of(MODS), Set.of(MODULE_NAME));
46+
ResolvedModule m = cf.findModule(MODULE_NAME).orElseThrow();
47+
ModuleLayer bootLayer = ModuleLayer.boot();
48+
ClassLoader scl = ClassLoader.getSystemClassLoader();
49+
Controller controller = ModuleLayer.defineModulesWithOneLoader(cf, List.of(bootLayer), scl);
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Manifest-Version: 1.0
2+
Class-Path: NonExistent.jar
3+
Created-By: 23-internal (Oracle Corporation)

0 commit comments

Comments
 (0)