niftiness at gmail.com
Mon Feb 16 06:12:18 UTC 2015
> As I wrote in my reply to David, I think resources (in the traditional
> ClassLoader::getResource sense) should be treated as being strictly
> internal to modules. If a module needs to make the information in one
> of its resources available to other modules then it should do so via a
> properly-exported class, or a service provider. Just because JAR files
> are miniature filesystems which anybody can dissect doesn't mean that we
> need to conceive of Java modules in the same way.
There's a common case that I'd like to understand how you solve without at
least META-INF or its equivalent visible to other modules: It's fairly
common to see applications that dynamically compose things they find on the
classpath. Spring and a few other things accomplish this through
classpath-scanning, which is a fairly horrible pattern (you can wind up
visiting every class on the classpath, or a large subset, just to look for
a runtime annotation that is not there for the vast majority).
An alternative approach I've used many times, which I think a few
frameworks do as well (dagger?) is: Write an annotation processor that
generates a flat file in META-INF that lists the classes that have the
annotation in question; runtime code loads all such files on the classpath
and uses that to initialize things that should be present at runtime. It's
really the same pattern as ServiceLoader.
Is it safe to assume that, whatever happens, that approach will still work,
whether by special-casing META-INF/** or some equivalent?
Having said that, I do agree that the module system must provide some
> kind of escape hatch or "promiscuous mode", as you call it, so here's
> a stab at an additional requirement for the "Modularizing Java SE"
> - _Overrideable encapsulation_ --- It must be possible to force a
> module to export one or more of its packages to all other modules,
> or to some specific modules, even if its definition does not do so.
One sort of low-hanging-fruit approach to this would be:
- Modules do not use the traditional $CLASSPATH
- The contents of $CLASSPATH are treated by the system as a single module
(so everything can see each other, and legacy code behaves as expected)
More information about the jpms-spec-observers