Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8217215

Enable checking/ignoring of non-conforming Class-Path entries

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 13
    • Component/s: core-libs
    • Labels:
      None
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      low
    • Compatibility Risk Description:
      Hide
      With Class-Path checking enabled, absolute URLs and non-adjacent paths could now be ignored.

      Applications depending on classes/resources in such an invalid Class-Path entry could encounter a ClassNotFoundException, or a missing resource.

      The developer would need to fix their Class-Path attribute. To aid in diagnosing which entries are invalid and ignored, ignored entries can be printed out by setting the "jdk.net.URLClassPath.showIgnoredClassPathEntries" system property to an empty string or "true"
      Show
      With Class-Path checking enabled, absolute URLs and non-adjacent paths could now be ignored. Applications depending on classes/resources in such an invalid Class-Path entry could encounter a ClassNotFoundException, or a missing resource. The developer would need to fix their Class-Path attribute. To aid in diagnosing which entries are invalid and ignored, ignored entries can be printed out by setting the "jdk.net.URLClassPath.showIgnoredClassPathEntries" system property to an empty string or "true"
    • Interface Kind:
      File or wire format
    • Scope:
      SE

      Description

      Summary

      Stricter enforcement of the JAR Class-Path attribute requires changing the JAR spec.

      Problem

      The JAR spec specifies that Class-Path entries must be relative URLs. However the JDK has also accepted absolute URLs for quite some time.

      There is now code in the JDK to enforce this, but it is disabled by default, for compatibility. The JDK-8216401 fix improves compatibility of this code, so for JDK 13, we want to enable the enforcement code by default.

      Solution

      Update the JAR spec to specify a valid Class-Path entry and reflect the new default behavior.

      Some previously-working Class-Path entries could now be ignored. Such entries would need to be updated. To help isolate ignored Class-Path entries, setting the "jdk.net.URLClassPath.showIgnoredClassPathEntries" system property to "true" (or empty string) will print a warning message for Class-Path entries that are ignored.

      Specification

      JAR specification diff:

              -and interpreted by the Java 2 Platform to configure applications, class
              +and interpreted by the Java Platform to configure applications, class
      ...
               The manifest for an application can specify one or more relative URLs
               referring to the JAR files and directories for other libraries that it
               needs. These relative URLs will be treated relative to the code base
              -that the containing application was loaded from.
              +that the containing application was loaded from (the "*context JAR*").
      
               An application (or, more generally, JAR file) specifies the relative
      ...     
               At most one `Class-Path` header may be specified in a JAR file's
              -manifest..
              +manifest.
              +
              +A `Class-Path` entry is valid if the following conditions are true:
      
              -Currently, the URLs must be *relative* to the code base of the JAR file
              -for security reasons. Thus, remote optional packages will originate from
              -the same code base as the application.
              +-   It can be used to create a [`URL`](../../api/java.base/java/net/URL.html#<init>(java.net.URL,java.lang.String)),
              +    by resolving it against the context JAR’s URL.
              +
              +-   It is relative, not [absolute](../../api/java.base/java/net/URI.html#isAbsolute()),
              +    i.e. it does not contain a scheme component, except for the case when the
              +    context JAR is loaded from the file system, in which case the `file` scheme
              +    is permitted for compatibility reasons.
      
              -Each relative URL is resolved against the code base that the containing
              -application or library was loaded from. If the resulting URL is invalid
              -or refers to a resource that cannot be found then it is ignored.
              +-   The location of the JAR file or directory represented by this entry
              +    is contained within the containing directory of the context JAR.
              +    Use of "`../`" to navigate to the parent directory is not permitted,
              +    except for the case when the context JAR is loaded from the file system.
      
              -The resulting URLs are used to extend the class path for the
              -application, applet, or servlet by inserting the URLs in the class path
              -immediately following the URL of the containing JAR file. Any duplicate
              -URLs are omitted. For example, given the following class path:
              +Invalid entries are ignored.  Valid entries are resolved against the context JAR.
              +If the resulting URL is invalid or refers to a resource that cannot be found,
              +then it is ignored. Duplicate URLs are ignored.
              +
              +The resulting URLs are inserted into the class path,
              +immediately following the path of the context JAR.
              +For example, given the following class path:
      ...
              -Class-Path: x.jar a.jar
              +Class-Path: lib/x.jar a.jar
               ```
      
              -Then the resulting application class path would be the following:
              +Then the effective search path of such a `URLClassLoader` instance would be:
      
               ``` {style="MARGIN-LEFT: 40px"}
              -a.jar b.jar x.jar
              +a.jar b.jar lib/x.jar
               ```
      
               Of course, if `x.jar` had dependencies of its own then these would be

      Updated JAR specification:

      Class-Path Attribute
      --------------------
      
      The manifest for an application can specify one or more relative URLs
      referring to the JAR files and directories for other libraries that it
      needs. These relative URLs will be treated relative to the code base
      that the containing application was loaded from (the "context JAR").
      
      An application (or, more generally, JAR file) specifies the relative
      URLs of the libraries that it needs via the manifest attribute
      `Class-Path`. This attribute lists the URLs to search for
      implementations of other libraries if they cannot be found on the host
      Java Virtual Machine. These relative URLs may include JAR files
      and directories for any libraries or resources needed by the
      application. Relative URLs not ending with '/' are assumed to refer to
      JAR files. For example,
      
      ``` {style="MARGIN-LEFT: 40px"}
      Class-Path: servlet.jar infobus.jar acme/beans.jar images/
      ```
      
      At most one `Class-Path` header may be specified in a JAR file's
      manifest.
      
      A `Class-Path` entry is valid if the following conditions are true:
      
      -   It can be used to create a [`URL`](../../api/java.base/java/net/URL.html#<init>(java.net.URL,java.lang.String)),
          by resolving it against the context JAR’s URL.
      
      -   It is relative, not [absolute](../../api/java.base/java/net/URI.html#isAbsolute()),
          i.e. it does not contain a scheme component, except for the case when the
          context JAR is loaded from the file system, in which case the `file` scheme
          is permitted for compatibility reasons.
      
      -   The location of the JAR file or directory represented by this entry
          is contained within the containing directory of the context JAR.
          Use of "`../`" to navigate to the parent directory is not permitted,
          except for the case when the context JAR is loaded from the file system.
      
      Invalid entries are ignored.  Valid entries are resolved against the context JAR.
      If the resulting URL is invalid or refers to a resource that cannot be found,
      then it is ignored. Duplicate URLs are ignored.
      
      The resulting URLs are inserted into the class path, 
      immediately following the URL of the context JAR.
      For example, given the following class path:
      
      ``` {style="MARGIN-LEFT: 40px"}
      a.jar b.jar
      ```
      
      If `b.jar` contained the following `Class-Path` manifest attribute:
      
      ``` {style="MARGIN-LEFT: 40px"}
      Class-Path: lib/x.jar a.jar
      ```
      
      Then the effective search path of such a `URLClassLoader` instance would be:
      
      ``` {style="MARGIN-LEFT: 40px"}
      a.jar b.jar lib/x.jar
      ```
      
      Of course, if `x.jar` had dependencies of its own then these would be
      added according to the same rules and so on for each subsequent URL. In
      the actual implementation, JAR file dependencies are processed lazily so
      that the JAR files are not actually opened until needed.

      A new JDK-specific system property:

      Setting -Djdk.net.URLClassPath.showIgnoredClassPathEntries or -Djdk.net.URLClassPath.showIgnoredClassPathEntries=true will print a warning message for Class-Path entries that are ignored.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                bchristi Brent Christian
                Reporter:
                bchristi Brent Christian
                Reviewed By:
                Alan Bateman, Mandy Chung
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: