Module-system requirements

David M. Lloyd david.lloyd at redhat.com
Wed Mar 11 21:46:11 UTC 2015


On 03/11/2015 08:23 AM, David M. Lloyd wrote:
> 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.

Actually this is not true after all.  Other than possibly examining 
constructor annotations to decide if a class is a CDI managed bean that is.

> 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-experts mailing list