#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