Module-system requirements

David M. Lloyd david.lloyd at redhat.com
Wed Mar 11 13:23:47 UTC 2015


On 03/09/2015 03:56 PM, mark.reinhold at oracle.com wrote:
> 2015/2/15 10:12 -0800, Tim Boudreau <niftiness at gmail.com>:
>> mark.reinhold at oracle.com:
>>> 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.  ...
>>
>> 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?
>
> For JAR files on the legacy class path that approach will, of course,
> continue to work.
>
> I don't expect actual modules to be on the class path (about which more
> below), which raises a question: Will a framework such as Spring need to
> discover the classes bearing certain annotations in modules that aren't
> yet configured and loaded, or in loaded modules, or both?  In the former
> case it would inspect module artifacts, while in the latter it would
> inspect some reflective run-time representation of a loaded module, since
> the original module artifact might not be available.
>
> Either way, this use case suggests a new requirement for the Development
> section:
>
>    - _Annotation digests_ --- When packaging a module into an artifact it
>      must be possible to augment its definition with a summary of all of
>      the type- and package-level annotations that are present in the
>      module, together with an indication of the types and packages to
>      which each annotation applies.  This digest must be easily readable
>      from module artifacts, and at run time those parts of it related to
>      annotations retained for run time must be available through an
>      appropriate reflective API.
>
> Comments?

If we're looking to extend this into the domain of Java EE annotations 
(for example), we'd also have to add method and field annotations to the 
list.  And SE 8 type annotations might add some strange color to this as 
well.

>>> 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"
>>> section:
>>>
>>> - _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)
>
> That's looking ahead to a design decision, I think, but in fact the
> approach I intend to propose treats the legacy class path as the content
> of a special "unnamed" module, analogous to the unnamed package, which
> implicitly depends upon all other modules so that it works essentially
> as you describe.

This is more or less what we do as well as I've said before, the 
difference being that we don't implicitly depend on all other modules 
(and in general I think we need to exercise great caution before 
throwing the term "all modules" in to any requirement, as an installed 
module base might be arbitrarily large).
-- 
- DML


More information about the jpms-spec-observers mailing list