8338626: ClassLoaderExt::process_jar_manifest() should allow / separator on Windows

Reviewed-by: iklam, dholmes, matsaave
This commit is contained in:
Calvin Cheung 2024-09-13 14:59:35 +00:00
parent 3e0da58ee6
commit 89ca89cb26
2 changed files with 81 additions and 1 deletions

View File

@ -213,6 +213,15 @@ void ClassLoaderExt::process_jar_manifest(JavaThread* current, ClassPathEntry* e
char sep = os::file_separator()[0];
const char* dir_name = entry->name();
const char* dir_tail = strrchr(dir_name, sep);
#ifdef _WINDOWS
// On Windows, we also support forward slash as the file separator when locating entries in the classpath entry.
const char* dir_tail2 = strrchr(dir_name, '/');
if (dir_tail == nullptr) {
dir_tail = dir_tail2;
} else if (dir_tail2 != nullptr && dir_tail2 > dir_tail) {
dir_tail = dir_tail2;
}
#endif
int dir_len;
if (dir_tail == nullptr) {
dir_len = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, 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
@ -30,6 +30,7 @@
* @run driver/timeout=240 ClassPathAttr
*/
import jdk.test.lib.Platform;
import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.process.OutputAnalyzer;
import java.io.File;
@ -82,6 +83,76 @@ public class ClassPathAttr {
output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
});
// Test handling of forward slash ('/') file separator when locating entries
// in the classpath entry on Windows.
// Skip the following test when CDS dynamic dump is enabled due to some
// issue when converting a relative path to real path.
if (Platform.isWindows() && !CDSTestUtils.DYNAMIC_DUMP) {
// Test with relative path
// Find the index to the dir before the jar file.
int idx = jar1.lastIndexOf(File.separator);
idx = jar1.substring(0, idx - 1).lastIndexOf(File.separator);
// Setup jar directory and names.
String jarDir = jar1.substring(0, idx);
String jar1Name = jar1.substring(idx + 1);
String jar4Name = jar4.substring(idx + 1);
String newCp = jar1Name.replace("\\", "/") + File.pathSeparator + jar4Name.replace("\\", "/");
OutputAnalyzer out = TestCommon.testDump(jarDir, newCp, classlist, "-Xlog:class+path=info");
if (i == 1) {
out.shouldMatch("opened:.*cpattr1.jar"); // first jar on -cp
} else {
// first jar on -cp with long Class-Path: attribute
out.shouldMatch("opened:.*cpattr1_long.jar");
}
// one of the jar in the Class-Path: attribute of cpattr1.jar
out.shouldMatch("opened:.*cpattr2.jar");
TestCommon.runWithRelativePath(
jarDir.replace("\\", "/"),
"-Xlog:class+path,class+load",
"-cp", newCp,
"CpAttr1")
.assertNormalExit(output -> {
output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
});
// Go one directory up.
int idx2 = jar1.substring(0, idx - 1).lastIndexOf(File.separator);
if (idx2 != -1) {
// Setup jar directory and names.
jarDir = jar1.substring(0, idx2);
// Set relative path to jar containing '\' and '/' file separators
// e.g. d1\d2/A.jar
jar1Name = jar1.substring(idx2 + 1).replace("\\", "/");
jar4Name = jar4.substring(idx2 + 1).replace("\\", "/");
jar1Name = jar1Name.replaceFirst("/", "\\\\");
jar4Name = jar4Name.replaceFirst("/", "\\\\");
newCp = jar1Name + File.pathSeparator + jar4Name;
out = TestCommon.testDump(jarDir, newCp, classlist, "-Xlog:class+path=info");
if (i == 1) {
out.shouldMatch("opened:.*cpattr1.jar"); // first jar on -cp
} else {
// first jar on -cp with long Class-Path: attribute
out.shouldMatch("opened:.*cpattr1_long.jar");
}
// one of the jar in the Class-Path: attribute of cpattr1.jar
out.shouldMatch("opened:.*cpattr2.jar");
TestCommon.runWithRelativePath(
jarDir.replace("\\", "/"),
"-Xlog:class+path,class+load",
"-cp", newCp,
"CpAttr1")
.assertNormalExit(output -> {
output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
});
}
}
}
// test duplicate jars in the "Class-path" attribute in the jar manifest