Skip to content

Commit d687bf0

Browse files
authored
Support finding packages in the JRT rather than just classpath (#10153)
Fixes #10149
1 parent 1fdf4cf commit d687bf0

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,12 @@
7878
import java.io.File;
7979
import java.io.IOException;
8080
import java.io.InputStream;
81+
import java.net.URI;
8182
import java.net.URISyntaxException;
8283
import java.net.URL;
84+
import java.nio.file.FileSystem;
85+
import java.nio.file.FileSystems;
86+
import java.nio.file.Files;
8387
import java.util.ArrayList;
8488
import java.util.Arrays;
8589
import java.util.Collection;
@@ -384,13 +388,20 @@ private static class INameEnvironmentImpl implements INameEnvironment {
384388

385389
private final Map<String, CompiledClass> internalTypes;
386390

391+
private final FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
392+
387393
public INameEnvironmentImpl(Set<String> packages, Map<String, CompiledClass> internalTypes) {
388394
this.packages = packages;
389395
this.internalTypes = internalTypes;
390396
}
391397

392398
@Override
393399
public void cleanup() {
400+
try {
401+
jrt.close();
402+
} catch (IOException e) {
403+
// Ignore failure to close read-only jrt file system
404+
}
394405
}
395406

396407
@Override
@@ -547,8 +558,8 @@ private NameEnvironmentAnswer doFindTypeInClassPath(String internalName) {
547558

548559
ClassFileReader classFileReader =
549560
ClassFileReader.read(openStream, resource.toExternalForm(), true);
550-
// In case insensitive file systems we might have found a resource whose name is different
551-
// in case and should not be returned as an answer.
561+
// In case-insensitive file systems we might have found a resource whose name is
562+
// different in case and should not be returned as an answer.
552563
if (internalName.equals(CharOperation.charToString(classFileReader.getName()))) {
553564
return new NameEnvironmentAnswer(classFileReader, null);
554565
}
@@ -606,14 +617,40 @@ private boolean isPackage(String slashedPackageName) {
606617
return false;
607618
}
608619
// Include class loader check for binary-only annotations.
609-
if (caseSensitivePathExists(slashedPackageName)) {
620+
if (caseSensitivePackageExists(slashedPackageName)) {
610621
addPackages(packages, slashedPackageName);
611622
return true;
612623
} else {
613624
notPackages.add(slashedPackageName);
614625
return false;
615626
}
616627
}
628+
629+
private boolean caseSensitivePackageExists(String slashedPackage) {
630+
URL resourceURL = getClassLoader().getResource(slashedPackage + '/');
631+
if (resourceURL == null) {
632+
// Can't be found in jars or class directories - might be system defined, test jrt
633+
String pkg = slashedPackage.replace('/', '.');
634+
// This check is always case-sensitive - we're looking inside the modules, rather than on
635+
// the host file system, so no additional checks are needed.
636+
return Files.exists(jrt.getPath("/packages", pkg));
637+
}
638+
639+
try {
640+
File resourceFile = new File(resourceURL.toURI());
641+
return Arrays.asList(resourceFile.getParentFile().list()).contains(resourceFile.getName());
642+
} catch (URISyntaxException e) {
643+
// The URL can not be converted to a URI.
644+
} catch (IllegalArgumentException e) {
645+
// A file instance can not be constructed from a URI.
646+
}
647+
648+
// Some exception occurred while trying to make sure the name for the resource on disk is
649+
// exactly the same as the one requested including case. If an exception is thrown in the
650+
// process we assume that the URI does not refer to a resource in the filesystem and that the
651+
// resource obtained from the classloader is the one requested.
652+
return true;
653+
}
617654
}
618655

619656
/**
@@ -1091,28 +1128,6 @@ private static void addPackages(Set<String> packages, String slashedPackageName)
10911128
}
10921129
}
10931130

1094-
private static boolean caseSensitivePathExists(String resourcePath) {
1095-
URL resourceURL = getClassLoader().getResource(resourcePath + '/');
1096-
if (resourceURL == null) {
1097-
return false;
1098-
}
1099-
1100-
try {
1101-
File resourceFile = new File(resourceURL.toURI());
1102-
return Arrays.asList(resourceFile.getParentFile().list()).contains(resourceFile.getName());
1103-
} catch (URISyntaxException e) {
1104-
// The URL can not be converted to a URI.
1105-
} catch (IllegalArgumentException e) {
1106-
// A file instance can not be constructed from a URI.
1107-
}
1108-
1109-
// Some exception occurred while trying to make sure the name for the resource on disk is
1110-
// exactly the same as the one requested including case. If an exception is thrown in the
1111-
// process we assume that the URI does not refer to a resource in the filesystem and that the
1112-
// resource obtained from the classloader is the one requested.
1113-
return true;
1114-
}
1115-
11161131
private static ClassLoader getClassLoader() {
11171132
return Thread.currentThread().getContextClassLoader();
11181133
}

dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ public void testSourceNames() throws Exception {
127127
"com.google.Outer.Inner", "com.google.Outer.Inner.Deep$est", "com.google.Pseudo$Inner")));
128128
}
129129

130+
public void testReferencesToJrtPackages() throws UnableToCompleteException {
131+
// Pick two different annotations from different java modules, with no emulation in GWT,
132+
// and confirm they can compile
133+
assertUnitCompilesWithNoErrors("com.example.JrtPackageReference",
134+
"package com.example;",
135+
"import javax.annotation.processing.Generated;",
136+
"import jdk.jfr.Label;",
137+
"@Generated(\"foo\")",
138+
"@Label(\"asdf\")",
139+
"public class JrtPackageReference {",
140+
"}");
141+
}
142+
130143
private void assertUnitCompilesWithNoErrors(String sourceName, String... sourceLines)
131144
throws UnableToCompleteException {
132145
CompilationUnit unit = compileUnit(sourceName, sourceLines);

0 commit comments

Comments
 (0)