2727import java .io .InputStream ;
2828import java .io .PrintWriter ;
2929import java .io .StringWriter ;
30+ import java .net .URI ;
3031import java .nio .file .Path ;
3132import java .util .ArrayList ;
3233import java .util .HashMap ;
4748import org .eclipse .jdt .internal .compiler .ICompilerRequestor ;
4849import org .eclipse .jdt .internal .compiler .batch .ClasspathLocation ;
4950import org .eclipse .jdt .internal .compiler .batch .FileSystem ;
50- import org .eclipse .jdt .internal .compiler .batch .FileSystem .Classpath ;
51- import org .eclipse .jdt .internal .compiler .batch .FileSystem .ClasspathAnswer ;
5251import org .eclipse .jdt .internal .compiler .batch .Main ;
5352import org .eclipse .jdt .internal .compiler .classfmt .ClassFileConstants ;
53+ import org .eclipse .jdt .internal .compiler .env .IBinaryType ;
5454import org .eclipse .jdt .internal .compiler .env .ICompilationUnit ;
55+ import org .eclipse .jdt .internal .compiler .env .NameEnvironmentAnswer ;
5556import org .eclipse .jdt .internal .compiler .impl .CompilerOptions ;
5657import org .eclipse .jdt .internal .compiler .problem .ProblemSeverities ;
5758
@@ -170,7 +171,7 @@ public FileSystem getLibraryAccess() {
170171 // we use this to collect information about all used dependencies during
171172 // compilation
172173 FileSystem nameEnvironment = super .getLibraryAccess ();
173- nameEnvironment .nameEnvironmentListener = this ::recordNameEnvironmentAnswer ;
174+ nameEnvironment .setNameEnvironmentAnswerListener ( this ::recordNameEnvironmentAnswer ) ;
174175 return nameEnvironment ;
175176 }
176177
@@ -214,18 +215,13 @@ protected void recordAnnotationProcessingAndPackageInfo(CompilationResult result
214215 processingModule .recordUnit (builder .build ());
215216 }
216217
217- protected void recordNameEnvironmentAnswer (ClasspathAnswer classpathAnswer ) {
218- Classpath classpath = classpathAnswer . source ;
219- if (classpath instanceof ClasspathLocation ) {
220- String jar = (( ClasspathLocation ) classpath ). getPath ( );
218+ protected void recordNameEnvironmentAnswer (NameEnvironmentAnswer answer ) {
219+ IBinaryType binaryType = answer . getBinaryType () ;
220+ if (binaryType != null ) {
221+ String jar = extractBinaryTypeJarPath ( binaryType );
221222 if (jar != null && jar .endsWith (".jar" )) {
222223 Path jarPath = Path .of (jar );
223224 if (processedJars .add (jarPath )) {
224- // we assume jars come from the execroot; JDT uses absolute/canonical paths
225- // therefore we translate the path back into an execroot relative path for Bazel
226- // to be happy
227- jarPath = sandboxPathPrefix .relativize (jarPath );
228-
229225 // update the dependency proto
230226 if (usedDependencyCollectionMode != UsedDependencyCollectionMode .None ) {
231227 if (directJars .contains (jarPath )) {
@@ -640,6 +636,37 @@ public static ClassLoader getPlatformClassLoader() {
640636 }
641637 }
642638
639+ /**
640+ * Extract the jar file path from a binary type URI. The URI of a binary type is generally in this format:
641+ * <pre>
642+ * jar:file://<path to jar>.jar!<path to class>
643+ * </pre>
644+ * We only use URIs that start with "jar:file:///" and containing ".jar!", e.g.:
645+ * <pre>
646+ * jar:file:///.../header_junit-jupiter-api-5.13.3.jar!/org/junit/jupiter/api/Test.class
647+ * </pre>
648+ * The URI format is coming from {@link org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader}, in particular see:
649+ * <ul>
650+ * <li>{@link org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader#read(ZipFile, String, boolean)}</li>
651+ * <li>{@link org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader#toUri(String)}</li>
652+ * </ul>
653+ *
654+ * @param binaryType a jar path is extracted from the URI of this binary type
655+ * @return the path of the binary types jar or {@code null} if the URI didn't match the expected format
656+ */
657+ private static String extractBinaryTypeJarPath (IBinaryType binaryType ) {
658+ URI binaryTypeUri = binaryType .getURI ();
659+ String uri = binaryTypeUri .toString ();
660+ String prefix = "jar:file:///" ;
661+ String suffix = ".jar!" ;
662+ int index = uri .indexOf (".jar!" );
663+ String jar = null ;
664+ if (uri .startsWith (prefix ) && index != -1 ) {
665+ jar = uri .substring (prefix .length (), index + suffix .length () - 1 );
666+ }
667+ return jar ;
668+ }
669+
643670 private BlazeEcjMain () {
644671 }
645- }
672+ }
0 commit comments