JDK-8232925 : FSInfo#getJarClassPath does not comply with the JAR specification
  • Type: Bug
  • Component: tools
  • Affected Version: 11,13
  • Priority: P3
  • Status: Resolved
  • Resolution: Duplicate
  • Submitted: 2019-10-24
  • Updated: 2020-05-18
  • Resolved: 2019-12-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14
14Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
Raised in compiler-dev by David Lloyd http://mail.openjdk.java.net/pipermail/compiler-dev/2019-October/013766.html

The JAR specification specifies that the `Class-Path` attribute is a
space-separated sequence of relative URLs.  A relative URL is defined
([2], [3]) as a hierarchical URI with no scheme component.

Relative URLs resemble file paths.  However they differ in some
important ways: for example, a relative URL is URL-encoded, whereas a
file path is not, causing problems when dealing with paths that have
embedded spaces (among other things).  Relative URLs representing
absolute paths on Windows have a form like `/C:/Foo/Bar`, whereas the
corresponding file path would be `C:/Foo/Bar` or `C:\Foo\Bar`.

Note (since this is a point of frequent confusion) that a relative URL
can have an absolute path.

AFAIK neither of these cases work correctly when javac interacts with
a JAR that contains a `Class-Path` attribute.

The current FSInfo code, as noted in the recent thread entitled
`FSInfo#getJarClassPath throws an exception not declared in its throws
clause`, reads the class path attribute value with code that uses
FileSystems.getDefault().getPath(xxx) on each class path element [4].

The correct behavior would be to wrap each item in a `java.net.URI`.
If the syntax is invalid, report an error or skip the element.  Then
determine if the URI is absolute; if it is, report an error or skip
the element.  Finally, query the Path API to look up the file by URI
using Path.of(uri) or similar, reporting an error or skipping the
element if there's a problem.

The less-elegant solution would be to manually URL-decode the string,
and (on windows) manually check to see if there's a drive letter,
removing the leading slash if there is one.  However I would consider
this to be more likely to be bug-prone.

This problem is the underlying cause of at least one Quarkus bug [5],
where the issue was discussed in depth.

[1] https://docs.oracle.com/javase/10/docs/specs/jar/jar.html#class-path-attribute
[2] RFC 3986 �� 4.2 - https://tools.ietf.org/html/rfc3986#section-4.2
[3] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URI.html
[4] https://github.com/openjdk/jdk/blob/4ad3d82c76936a8927ed8a505689a3683144ad98/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java#L112
[5] https://github.com/quarkusio/quarkus/issues/3592

Comments
FYI, JDK-8218268 has now been resolved.
06-12-2019

Marking noreg-hard because full and proper testing would involve setting up something like an http: server to help verify that http: URLs on the Class-Path are ignored.
04-12-2019