RFR: JDK-8210009: Source Launcher classloader should support getResource and getResourceAsStream
Peter Levart
peter.levart at gmail.com
Wed Sep 5 08:43:41 UTC 2018
Hi Jon,
A few comments at the end...
On 09/04/2018 10:52 PM, Jonathan Gibbons wrote:
> Please review a change to add support for the getResource* group of
> methods
> to the internal class loader used by the Source Launcher, introduced
> in JEP 330.
>
> The overall issue has been discussed on OpenJDK lists, [1,2]
>
> The implementation consists of providing findResource and findResources,
> along with a couple of minor additional classes to implement
> URLStreamHandler
> and URLConnection.
>
> There is one implementation detail worthy of note. The "new URL" should
> be inside a doPrivileged block, but overall, the Source Launcher does not
> work when a security manager in installed. This is being tracked as
> JDK-8210274,
> and the appropriate doPrivileged call will be added as part of that fix.
>
> -- Jon
>
> JBS: https://bugs.openjdk.java.net/browse/JDK-8210009
> Webrev: http://cr.openjdk.java.net/~jjg/8210009/webrev.01/
In the protocol (schema) name:
618 private final String PROTOCOL = "sourcelauncher_" +
getClass().getSimpleName() + hashCode();
...which looks like "sourcelauncher_MemoryClassLoader-12345", the
underscore is not an allowed character. The syntax of schema name is:
alpha *( alpha | digit | "+" | "-" | "." )
URL does not check for that, but when you perform say url.toURI() you
get URISyntaxException.
If the intent was to append hashCode() to make the schema name unique
per MemoryClassLoader instance (is there a reason for that?), then
hashCode() does not guarantee that. Although the probability of a clash
is very low.
Was the intent of randomizing protocol name preventing things like
making url3 below succeed in returning "wrong" resource?
MemoryClassLoader cl1 = ...
MemoryClassLoader cl2 = ...
URL url1 = cl1.getResource(path1);
URL url2 = cl2.getResource(path2);
URL url3 = new URL(url1, url2.toString());
findResource() may be called concurrently from multiple threads, so lazy
initialization of 'handler' field should be performed carefully using
local variables:
URLStreamHandler handler = this.handler;
if (handler == null) {
this.handler = handler = new MemoryURLStreamHandler();
}
...then use local var 'hander' for constructing URL, or you risk
reorderings which might pass null as handler parameter to URL
constructor. This is still publication via data race, but should be safe
as the only MemoryURLStreamHandler's state is a synthetic final field
referencing outer MemoryClassLoader instance.
I haven't tried to run the test, but how does this work:
56 String[] names = {
57 "p/q/CLTest.class",
58 "p/q/CLTest$Inner.class",
59 "p/q/CLTest2.class",
60 "java/lang/Object.class",
61 "UNKNOWN.class",
62 "UNKNOWN"
63 };
...and then:
80 URL u = cl.getResource(name);
81 if (u == null) {
82 if (!name.contains("UNKNOWN")) {
83 error("resource not found: " + name);
84 }
Shouldn't resource name "p/q/CLTest2.class" raise an error?
Regards, Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20180905/4563a4be/attachment-0001.html>
More information about the compiler-dev
mailing list