mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-10 04:25:35 +00:00
8385355: NullPointerException in jdk.tools.jlink.internal.ImageResourcesTree after JDK-8377070
Reviewed-by: alanb Backport-of: 92298786486daf092c8eb8f278818441df1f6b51
This commit is contained in:
parent
f8f7ad28ba
commit
cce810ed30
@ -235,22 +235,46 @@ public final class ImageResourcesTree {
|
||||
return;
|
||||
}
|
||||
String modName = fullPath.substring(1, modEnd);
|
||||
String pkgPath = fullPath.substring(modEnd + 1);
|
||||
String resPath = fullPath.substring(modEnd + 1);
|
||||
int pathEnd = resPath.lastIndexOf('/');
|
||||
|
||||
Node parentNode = getDirectoryNode(modName, modulesRoot);
|
||||
boolean isPreviewPath = false;
|
||||
if (pkgPath.startsWith(PREVIEW_PREFIX)) {
|
||||
if (resPath.startsWith("META-INF/")) {
|
||||
parentNode = getDirectoryNode("META-INF", parentNode);
|
||||
if (!resPath.startsWith(PREVIEW_PREFIX)) {
|
||||
// Non-preview META-INF paths are resources, not package
|
||||
// hierarchies, so directory and file names may contain dots.
|
||||
for (int i = "META-INF".length(), j; i != pathEnd; i = j) {
|
||||
j = resPath.indexOf('/', i + 1);
|
||||
parentNode = getDirectoryNode(resPath.substring(i + 1, j), parentNode);
|
||||
}
|
||||
String resourceName = resPath.substring(pathEnd + 1);
|
||||
Node resourceNode = parentNode.getChildren(resourceName);
|
||||
if (resourceNode == null) {
|
||||
new ResourceNode(resourceName, parentNode);
|
||||
} else if (!(resourceNode instanceof ResourceNode)) {
|
||||
throw new InvalidTreeException(resourceNode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// For preview paths, process nodes relative to the preview directory.
|
||||
pkgPath = pkgPath.substring(PREVIEW_PREFIX.length());
|
||||
Node metaInf = getDirectoryNode("META-INF", parentNode);
|
||||
parentNode = getDirectoryNode("preview", metaInf);
|
||||
parentNode = getDirectoryNode("preview", parentNode);
|
||||
resPath = resPath.substring(PREVIEW_PREFIX.length());
|
||||
pathEnd -= PREVIEW_PREFIX.length();
|
||||
isPreviewPath = true;
|
||||
}
|
||||
|
||||
int pathEnd = pkgPath.lastIndexOf('/');
|
||||
// From invariants tested above, this must now be well-formed.
|
||||
String fullPkgName = (pathEnd == -1) ? "" : pkgPath.substring(0, pathEnd).replace('/', '.');
|
||||
String resourceName = pkgPath.substring(pathEnd + 1);
|
||||
String pkgPath = (pathEnd == -1) ? "" : resPath.substring(0, pathEnd);
|
||||
if (pkgPath.contains(".")) {
|
||||
// Non META-INF entries are package paths. Dots in path segment
|
||||
// names would otherwise be confused with package separators.
|
||||
System.err.println("Invalid package path, skipping " + pkgPath);
|
||||
return;
|
||||
}
|
||||
String fullPkgName = pkgPath.replace('/', '.');
|
||||
String resourceName = resPath.substring(pathEnd + 1);
|
||||
// Intermediate packages are marked "empty" (no resources). This might
|
||||
// later be merged with a non-empty link for the same package.
|
||||
ModuleLink emptyLink = ModuleLink.forEmptyPackage(modName, isPreviewPath);
|
||||
|
||||
@ -37,6 +37,7 @@ import tests.Helper;
|
||||
import tests.JImageGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -58,6 +59,7 @@ import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8385355
|
||||
* @summary Tests for ImageReader.
|
||||
* @modules java.base/jdk.internal.jimage
|
||||
* jdk.jlink/jdk.tools.jlink.internal
|
||||
@ -72,13 +74,18 @@ import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||
/// There is no mutable test instance state to worry about.
|
||||
@TestInstance(PER_CLASS)
|
||||
public class ImageReaderTest {
|
||||
// The '@' prefix marks the entry as a preview entry which will be placed in
|
||||
// the '/modules/<module>/META-INF/preview/...' namespace.
|
||||
// The '@' prefix marks the entry as a preview class entry which will be placed in
|
||||
// the '/modules/<module>/META-INF/preview/...' namespace. The '!' prefix marks
|
||||
// the entry as a non-class resource path.
|
||||
private static final Map<String, List<String>> IMAGE_ENTRIES = Map.of(
|
||||
"modfoo", Arrays.asList(
|
||||
"com.foo.HasPreviewVersion",
|
||||
"com.foo.NormalFoo",
|
||||
"com.foo.bar.NormalBar",
|
||||
"!META-INF/maven/com.google.code.findbugs/jsr305/pom.properties",
|
||||
"!META-INF/z",
|
||||
"!META-INF/collision/child.properties",
|
||||
"!META-INF/collision",
|
||||
// Replaces original class in preview mode.
|
||||
"@com.foo.HasPreviewVersion",
|
||||
// New class in existing package in preview mode.
|
||||
@ -138,6 +145,23 @@ public class ImageReaderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetaInfResourcesAreNotPackagePaths() throws IOException {
|
||||
for (PreviewMode mode : List.of(PreviewMode.ENABLED, PreviewMode.DISABLED)) {
|
||||
try (ImageReader reader = ImageReader.open(image, mode)) {
|
||||
assertResource(reader, "modfoo", "META-INF/maven/com.google.code.findbugs/jsr305/pom.properties");
|
||||
assertResource(reader, "modfoo", "META-INF/z");
|
||||
assertResource(reader, "modfoo", "META-INF/collision/child.properties");
|
||||
assertDirContents(reader, "/modules/modfoo/META-INF", "MANIFEST.MF", "collision", "maven", "z");
|
||||
assertDirContents(reader, "/modules/modfoo/META-INF/collision", "child.properties");
|
||||
assertDirContents(reader, "/modules/modfoo/META-INF/maven", "com.google.code.findbugs");
|
||||
assertDirContents(reader, "/modules/modfoo/META-INF/maven/com.google.code.findbugs", "jsr305");
|
||||
assertDirContents(reader, "/modules/modfoo/META-INF/maven/com.google.code.findbugs/jsr305", "pom.properties");
|
||||
assertAbsent(reader, "/modules/modfoo/META-INF/maven/com/google/code/findbugs/jsr305/pom.properties");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(delimiter = ':', value = {
|
||||
"modfoo:com/foo/HasPreviewVersion.class",
|
||||
@ -416,6 +440,10 @@ public class ImageReaderTest {
|
||||
jar.addEntry("module-info.class", InMemoryJavaCompiler.compile("module-info", moduleInfo));
|
||||
|
||||
classes.forEach(fqn -> {
|
||||
if (fqn.startsWith("!")) {
|
||||
jar.addEntry(fqn.substring(1), "resource".getBytes(StandardCharsets.UTF_8));
|
||||
return;
|
||||
}
|
||||
boolean isPreviewEntry = fqn.startsWith("@");
|
||||
if (isPreviewEntry) {
|
||||
fqn = fqn.substring(1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user