-
Bug
-
Resolution: Fixed
-
P4
-
11, 17, 20
-
b05
java.net.URL allows applications to specify a value for the java.protocol.handler.pkgs system property to point to protocol handlers for the URL instance. As noted in the javadoc of the java.net.URL constructor:
* the constructor reads the value of the system property:
* <blockquote>{@systemProperty
* java.protocol.handler.pkgs
* }</blockquote>
* If the value of that system property is not {@code null},
* it is interpreted as a list of packages separated by a vertical
* slash character '{@code |}'. The constructor tries to load
* the class named:
* <blockquote>{@code
* <package>.<protocol>.Handler
* }</blockquote>
* where {@code <package>} is replaced by the name of the package
* and {@code <protocol>} is replaced by the name of the protocol.
* If this class does not exist, or if the class exists but it is not
* a subclass of {@code URLStreamHandler}, then the next package
* in the list is tried.
The implementation in its current form matches this expected semantics. The implementation however doesn't take into account an empty value for the java.protocol.handler.pkgs system property.
So if an application is a launched with this system property value being empty:
java -Djava.protocol.handler.pkgs= Foo.java
Then this leads to the URL constructor attempting to class load a class of the form ".jar.Handler" (for example for the jar protocol). Since the fully qualified classname cannot start with a ".", this class loading attempt is bound to fail (and it does). In its current implementation, when that happens, the implementation then tries to load that class using the system classloader, which too will fail.
These classloading attempts for this malformed classname can be expensive, especially if the application is running in application classpath mode and the classpath consists large number of jars.
Not attempting to locate such a class when the package name prefix value is empty would be a good thing.
* the constructor reads the value of the system property:
* <blockquote>{@systemProperty
* java.protocol.handler.pkgs
* }</blockquote>
* If the value of that system property is not {@code null},
* it is interpreted as a list of packages separated by a vertical
* slash character '{@code |}'. The constructor tries to load
* the class named:
* <blockquote>{@code
* <package>.<protocol>.Handler
* }</blockquote>
* where {@code <package>} is replaced by the name of the package
* and {@code <protocol>} is replaced by the name of the protocol.
* If this class does not exist, or if the class exists but it is not
* a subclass of {@code URLStreamHandler}, then the next package
* in the list is tried.
The implementation in its current form matches this expected semantics. The implementation however doesn't take into account an empty value for the java.protocol.handler.pkgs system property.
So if an application is a launched with this system property value being empty:
java -Djava.protocol.handler.pkgs= Foo.java
Then this leads to the URL constructor attempting to class load a class of the form ".jar.Handler" (for example for the jar protocol). Since the fully qualified classname cannot start with a ".", this class loading attempt is bound to fail (and it does). In its current implementation, when that happens, the implementation then tries to load that class using the system classloader, which too will fail.
These classloading attempts for this malformed classname can be expensive, especially if the application is running in application classpath mode and the classpath consists large number of jars.
Not attempting to locate such a class when the package name prefix value is empty would be a good thing.
- relates to
-
JDK-8308184 Launching java with large number of jars in classpath with java.protocol.handler.pkgs system property set can lead to StackOverflowError
-
- Closed
-
- links to
-
Commit openjdk/jdk/8f5a3848
-
Review(master) openjdk/jdk/14693