Skip to content

Commit f687cac

Browse files
committed
8353504: CDS archives are not found when JVM is in non-variant location
Reviewed-by: iklam, shade
1 parent 3ee1447 commit f687cac

File tree

3 files changed

+98
-5
lines changed

3 files changed

+98
-5
lines changed

src/hotspot/share/cds/cdsConfig.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,12 @@ const char* CDSConfig::default_archive_path() {
108108
// before CDSConfig::ergo_initialize() is called.
109109
assert(_cds_ergo_initialize_started, "sanity");
110110
if (_default_archive_path == nullptr) {
111+
char jvm_path[JVM_MAXPATHLEN];
112+
os::jvm_path(jvm_path, sizeof(jvm_path));
113+
char *end = strrchr(jvm_path, *os::file_separator());
114+
if (end != nullptr) *end = '\0';
111115
stringStream tmp;
112-
const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib");
113-
tmp.print("%s%s%s%s%s%sclasses", Arguments::get_java_home(), os::file_separator(), subdir,
114-
os::file_separator(), Abstract_VM_Version::vm_variant(), os::file_separator());
116+
tmp.print("%s%sclasses", jvm_path, os::file_separator());
115117
#ifdef _LP64
116118
if (!UseCompressedOops) {
117119
tmp.print_raw("_nocoops");
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2025, 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+
* @summary Test that CDS archive can be loaded if the archive is in a non-JVM variant directory.
28+
* @bug 8353504
29+
* @requires vm.cds
30+
* @requires vm.flagless
31+
* @requires vm.flavor == "server"
32+
* @comment This test doesn't work on Windows because it depends on symlinks
33+
* @requires os.family != "windows"
34+
* @library /test/lib appcds
35+
* @run driver NonJVMVariantLocation
36+
*/
37+
38+
import java.io.File;
39+
import java.io.IOException;
40+
import java.nio.file.Files;
41+
import java.nio.file.Paths;
42+
import java.util.List;
43+
import jdk.test.lib.cds.CDSTestUtils;
44+
import jdk.test.lib.process.OutputAnalyzer;
45+
46+
public class NonJVMVariantLocation {
47+
public static void main(String[] args) throws Exception {
48+
String java_home_src = System.getProperty("java.home");
49+
String java_home_dst = CDSTestUtils.getOutputDir() + File.separator + "moved_jdk";
50+
String homeJava = java_home_src + File.separator + "bin" + File.separator + "java";
51+
String dstJava = java_home_dst + File.separator + "bin" + File.separator + "java";
52+
53+
CDSTestUtils.clone(new File(java_home_src), new File(java_home_dst));
54+
System.out.println("============== Cloned JDK at " + java_home_dst);
55+
56+
// Replace "server" with "release" in jvm.cfg.
57+
// The jvm.cfg is parsed by the java launcher in java.c.
58+
String locDir = java_home_dst + File.separator + "lib";
59+
String jvmCfg = locDir + File.separator + "jvm.cfg";
60+
String serverDir = "server";
61+
String releaseDir = "release";
62+
replaceTextInFile(jvmCfg, serverDir, releaseDir);
63+
64+
// Rename "server" dir to "release" dir.
65+
CDSTestUtils.rename(new File(locDir + File.separator + serverDir),
66+
new File(locDir + File.separator + releaseDir));
67+
68+
// Test runtime with cloned JDK
69+
{
70+
ProcessBuilder pb = CDSTestUtils.makeBuilder(dstJava,
71+
"-Xshare:on",
72+
"-Xlog:cds",
73+
"-version");
74+
OutputAnalyzer out = TestCommon.executeAndLog(pb, "exec-dst");
75+
out.shouldHaveExitValue(0)
76+
.shouldMatch(".info..cds. Opened shared archive file.*classes.*\\.jsa");
77+
}
78+
}
79+
80+
private static void replaceTextInFile(String filePath, String oldText, String newText) {
81+
try {
82+
List<String> lines = Files.readAllLines(Paths.get(filePath));
83+
lines.replaceAll(line -> line.replace(oldText, newText));
84+
Files.write(Paths.get(filePath), lines);
85+
} catch (IOException e) {
86+
e.printStackTrace();
87+
}
88+
}
89+
}

test/lib/jdk/test/lib/cds/CDSTestUtils.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,8 +778,10 @@ private static boolean isAsciiPrintable(char ch) {
778778

779779
// Do a cheap clone of the JDK. Most files can be sym-linked. However, $JAVA_HOME/bin/java and $JAVA_HOME/lib/.../libjvm.so"
780780
// must be copied, because the java.home property is derived from the canonicalized paths of these 2 files.
781-
// Set a list of {jvm, "java"} which will be physically copied. If a file needs copied physically, add it to the list.
782-
private static String[] phCopied = {System.mapLibraryName("jvm"), "java"};
781+
// The jvm.cfg file must be copied because the cds/NonJVMVariantLocation.java
782+
// test is testing a CDS archive can be loaded from a non-JVM variant directory.
783+
// Set a list of {jvm, "java", "jvm.cfg"} which will be physically copied. If a file needs copied physically, add it to the list.
784+
private static String[] phCopied = {System.mapLibraryName("jvm"), "java", "jvm.cfg"};
783785
public static void clone(File src, File dst) throws Exception {
784786
if (dst.exists()) {
785787
if (!dst.isDirectory()) {

0 commit comments

Comments
 (0)