#ModuleAnnotations - some thoughts and an alternative implementation

Peter Levart peter.levart at gmail.com
Sun Jul 17 22:36:12 UTC 2016


Hi,

The proposal for #ModuleAnnotations says:

/"  - Extend `javax.lang.model` and `java.lang.reflect` to provide access//
//    to module annotations.  Repeating annotations are supported, subject//
//    to the usual rules for repeatable annotation types. *(This 
proposal*/*/
/**/    will not add similar support to 
`java.lang.module.ModuleDescriptor`;/**/
/**/    that would add yet more complexity, and we haven't seen a use 
case/**/
/*/*    for it.)*"/

A possible use case might be here:

http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-June/008077.html

...in particular in the following message:

http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-June/008102.html

...where it says that one option would be to have a "labeling system" 
for modules. To find out to what "groups" they belong to.

But there's a more fundamental problem that prevents adding support for 
annotations to ModuleDescriptor - a chicken-egg problem. Annotations are 
types and they reference types. These types can be declared in the 
module that uses them in its module descriptor. Until a 
java.lang.reflect.Module is instantiated for a module that might contain 
the types that appear in its module descriptor, those annotations can 
not be materialized in a form that we are used to - as instances of 
annotation interfaces.

Unfortunately, annotations on ModuleDescriptor would be useful precisely 
in cases where there's no Module instantiated yet. For example, to 
identify a group of module descriptors such as in above-mentioned use-case.

Would it be worth exploring the possibility to present module 
annotations on ModuleDescriptor in a more symbolic and reflective way? 
Where annotation instances would be represented as generic key/value 
records, java.lang.Class instances would be represented just as class 
names and enum instances just as some generic untyped equivalent?

Anyway, current implementation of annotations on 
java.lang.reflect.Module uses a clever trick - it defines a class 
derived from module-info.class in the VM just to be able to use the 
existing java.lang.Class infrastructure for annotations (similarly to 
how Package does for its annotations) with additional hack where each 
such module-info class has to be defined in its own class loader as just 
a single name is used for multiple module classes.

Here's an alternative implementation that does not need to define the 
class in the VM:

http://cr.openjdk.java.net/~plevart/jdk9-jake/Module.annotations/webrev.02/

It instead modifies AnnotationParser to use a special 
AnnotationParser.ConstantPool interface which is implemented by two 
classes: a classical reflection ConstantPool backed by VM and a 
lightweight Java-only implementation which is used to parse 
module-info.class. So while parsing module-info.class, the 
RuntimeVisibleAnnotations attribute is extracted and memorized in 
ModuleDescriptor. Together with the lightweight ConstantPool 
implementation, they are used in Module to parse the annotations when 
1st requiested.

It is more involved than current implementation, but it is also lighter 
and might be extended to support - let's call them 
annotation-descriptors - on ModuleDescriptor.

What do you think?

Regards, Peter



More information about the jigsaw-dev mailing list