JDK-8227076 : A jrt URI can only encode paths to files in /modules tree
  • Type: CSR
  • Component: tools
  • Sub-Component: jlink
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-07-02
  • Updated: 2019-07-18
  • Resolved: 2019-07-11
Related Reports
CSR :  
Description
Summary
-------

The implementation of `java.nio.file.Path::toUri` in the `jrt` file system provider creates URIs that are not compliant with the syntax for jrt URIs described in [JEP 220](https://openjdk.java.net/jeps/220). Furthermore, the `jrt` file system provider's implementation of `getPath(URI)` does not parse `jrt` URLs correctly, the resulting file paths do not reliably locate files in the jrt file system.

The CSR proposes to fix the problems in the `jrt` file system provider so that it creates and parses URIs that are compliant with the syntax described in JEP 220. This change may have a compatibility impact on compilers or tools relying (perhaps unknowingly) on URIs that are not compliant with the syntax.

Problem
-------

Consider the file "`/modules/java.base/java/lang/Object.class`" in the jrt file system. If a tool has a `Path` to this file then invoking its `toUri` method should create the URI "`jrt:/java.base/java/lang/Object.class`".  Unfortunately, due to a bug (the bug exists in JDK 9, 10, 11, 12), it yields the URI "`jrt:/modules/java.base/java/lang/Object.class`". This URI cannot be used with the `jrt` protocol handler (`URL::openStream` will fail with an `IOException` because module "`modules`" is not found).

Now consider the URI "`jrt:/java.base/java/lang/Object.class`". If `Path.of(URI)` is used to create a `java.nio.file.Path` from this URI then the resulting jrt file path will be "`/java.base/java/lang/Object.class`" and so will not locate a file in the jrt file system.

Solution
--------

Fix the jrt file system provider so that its `Path::toUri` implementation yields a URI that is compliant with the syntax. The method will fail when the file is not in the `/modules` tree as a jrt URI can only encode file paths to files in this tree. It will also fail if the file path is not normalized, e.g. contains ".." elements.

Fix the jrt file system provider so that its `getPath(URI)` yields a file path prefixed with "`/modules`".

Specification
-------------

There are no specification changes in the CSR. This an implementation only change.


Comments
Moving to Approved.
11-07-2019

This is a retroactive CSR, the change has been in JDK 13 since jdk-13+24. The change has a release note. Since integration, we have become aware of a potential issue in the scala compiler. Lukas Eder reports that compiling the "jOOQ-scala" fails: java.lang.RuntimeException: /packages cannot be represented as URI java.base/jdk.internal.jrtfs.JrtPath.toUri(JrtPath.java:176) (toURI throws java.io.IOError so it's possible that the scala compiler has unwrapped the exception). The exception suggests that it has a file path to /packages and is trying to create a URI for that location. That location is a directory of sym links, it cannot be represented by a jrt URI.
02-07-2019