jigsaw EA feedback for apache lucene
uschindler at apache.org
Thu Sep 10 11:14:46 UTC 2015
> -----Original Message-----
> From: jigsaw-dev [mailto:jigsaw-dev-bounces at openjdk.java.net] On Behalf
> Of Alan Bateman
> Sent: Thursday, September 10, 2015 12:23 PM
> To: Sundararajan Athijegannathan; Robert Muir
> Cc: jigsaw-dev at openjdk.java.net
> Subject: Re: jigsaw EA feedback for apache lucene
> On 10/09/2015 06:52, Sundararajan Athijegannathan wrote:
> > :
> > ClassLoader.getResource for a .class resource is checked to detect if
> > it runs on jdk9. This returns a "jrt:" URL in jdk9 EA build - but,
> > returns null with jigsaw build. Also,
> > RuntimeMXBean.isBootClassPathSupported() returns false.
> > So, isSupportedJDK will be false.
> > Better solution would be to check if "jrt" nio file system is
> > available & use the same to check and/or read .class files of JDK
> > classes.
> That will work but it might be better to look at
> java.lang.reflect.Module#getResourceAsStream as this will work for
> resources in both named and unnamed modules (for unnamed modules
> then it works like ClassLoader#getResourceAsStream). The summary on this
> is that the ClassLoader#getResourceXXX methods will locate resources on
> the class path as before, it's just that they don't locate resources in named
OK. So you would first to find out the module of a class and then ask the module for the resource. Is there a way to get the module from the binary (string a la Class#forName()) class name without actually loading the class?
The second problem for such checkers is: Unfortunately this needs Java 9 at compile time... On solution for this would be to wrap the checker's internal loading mechanism with a class solely compiled for Java 9 at runtime, if Java 9 was detected - that provides the missing resources - older Java versions would use the approach as currently implemented.
But the big question is, that I was not able to understand after reading all the JIGSAW specs:
Is there a reason why the (system-) classloader does not return any resources from foreign modules anymore? I agree that some internal properties files and so on are not needed to be available, but if a caller can do Class#forName() on a specific class that is public on top, why should it not also do a getResource() call on the class's bytecode - this makes no sense to me? Many frameworks like Google Guice, Spring,... rely on that because they may need to create proxy classes and therefore need to have the bytecode. So to me this seems like a major break!
In my opinion, it should be possible to access the bytecode of classes if the class itself is available in Class#forName(). This was an assumption you were always able to count on. Java 9 does not simplify this, it makes tool building more complicated. I was so happy that you added "jrt:" URLs, but this is now also gone. The reason why this should work with Classloader is the defined way to lookup stuff. If I need a special case to load the bytecode for already visible classes, this makes tool development horrible. Since Java 1.0 this was a very easy thing. Class#forName() and Class#getResource() used the same lookup mechanis hidden by the class loader. You were able to rely since Java 1.0 on the fact that if you can load a class with ClassLoader#forName(), you can also load its bytecode with the same classloader.
Maybe you should just hide private resources, but if the classloader detects that you do a getResource() on resource filename with ".class", it should use the same access checks of the module system and return the stuff as stream or jrt:// URL. Otherwise return null when Class#forName() would throw ClassNotFoundException.
More information about the jigsaw-dev