Please review the change to access the annotations from module-info
Joe Darcy
joe.darcy at oracle.com
Wed Apr 28 13:31:48 PDT 2010
Hello.
Mandy Chung wrote:
> Joe,
>
> Thanks for the feedback to the ModuleInfo API. This change also
> implements the reflection methods to access the annotations in the
> java.lang.reflect.Module class (i.e. implementation of
> AnnotatedElement methods).
>
> The webrev is at:
> http://cr.openjdk.java.net/~mchung/jigsaw/annotations/webrev/
>
> Most of the work is done in the java.lang.module.ModuleInfoAnnotation
> class that does the following:
> - parses a raw annotation from the module-info.class
> - stores the element value pairs
> - creates an Annotation object using the core reflection
> - it supports for both ModuleInfo and Module API to access
> annotations. The Annotation objects created for the
> ModuleInfo.getAnnotation() method doesn't support elements of Class type.
>
> I added a constructor of CoreReflectionFactory to take a Module
> parameter so that its module class loader will be used to load classes
> when instantiating an Annotation object. Is there any issue with
> that? The factory will only be used to parse class signatures.
Some comments from a first pass over the code:
In ModuleInfo.java, I recommend adding an "@see
java.lang.reflect.AnnotatedElement#isAnnotationPresent" to the
isAnnotationPresent method.
In ModuleInfoReader.java, if you want to start using some new language
features, the following line is an ideal candidate for the diamond operator:
70 private Map<String, ModuleInfoAnnotation> annotationTypes = new
LinkedHashMap<String, ModuleInfoAnnotation>();
With diamond
70 private Map<String, ModuleInfoAnnotation> annotationTypes = new
LinkedHashMap<>();
Later in that file, this looks like a candidate for strings in switch:
135 if (name.equals(MODULE))
136 readModule();
137 else if (name.equals(MODULE_PROVIDES))
138 readModuleProvides();
139 else if (name.equals(MODULE_REQUIRES))
140 readModuleRequires();
141 else if (name.equals(MODULE_PERMITS))
142 readModulePermits();
143 else if (name.equals(MODULE_CLASS))
144 readModuleClass();
145 else if (name.equals(RUNTIME_VISABLE_ANNOTATION)) {
146 readAnnotations();
147 } else {
148 in.skip(length);
switch(name) {
case MODULE:
readModule(); break;
case MODULE_PROVIDES:
...
}
In src/share/classes/java/lang/module/ModuleSystem.java, this method body
43 // Module names must be legal Java identifiers
44 //
45 public static final String checkModuleName(String nm) {
46 if (nm == null)
47 throw new IllegalArgumentException();
48 int n = nm.length();
49 if (n == 0 || !Character.isJavaIdentifierStart(nm.charAt(0)))
50 throw new IllegalArgumentException();
51 for (int i = 1; i < n; i++) {
52 char c = nm.charAt(i);
53 if (!Character.isJavaIdentifierPart(c) && (c != '.'))
54 throw new IllegalArgumentException(nm
55 + ": Illegal
module-name"
56 + " character"
57 + " at index " + i);
58 }
59 return nm;
60 }
could be replaced by a call to SourceVersion.isIdentifier:
http://download.java.net/jdk7/docs/api/javax/lang/model/SourceVersion.html#isIdentifier(java.lang.CharSequence)
An advantage of the isIdentifier method is that it does the right thing
in regard to code points; see the code in
http://hg.openjdk.java.net/jdk7/jdk7/langtools/file/71c2c23a7c35/src/share/classes/javax/lang/model/SourceVersion.java
for the codepoint-correct loop if you can't call this method.
/src/share/classes/java/lang/reflect/Module.java
Is there a reason the annotation handling code here looks different from
the analogous code in java.lang.reflect.Constructor?
Should Module extend AccessbileObject?
src/share/classes/java/lang/module/ModuleInfoAnnotation.java
53 * Represents an annotation in module-info.class. This class is
54 * based on the com.sun.tools.classfile library.
55 *
56 * @see com.sun.tools.classfile.Annotation
I don't think the official javadoc of a java.lang.* class should
reference a com.sun.* class.
As to how this class is structured, I'm not familiar with the origin of
provenance of com.sun.tools.classfile.Annotation. However, perhaps the
time has come to have a unified "arms length annotation maker" to
subsume the functionality in
langtools/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java
and a similar class in javac.
src/share/classes/java/lang/module/UnsupportedElementTypeException.java
44 */
45 public class UnsupportedElementTypeException extends RuntimeException {
46
47 private static final long serialVersionUID = 269;
48
49 private transient List<String> classnames; // cannot be serialized
I assume you used javax.lang.model.type.MirroredTypeException[s] for
inspiration here :-) A difference is that the classname
UnsupportedElementTypeException should be able to be serialized since it
is just a list of strings; the MirroredTypeExceptions cannot be
serialized because the Type objects are tied up in a lot of internal
javac state. (And if UnsupportedElementTypeException is made fully
serializable, it should define a good serial form for the classname.)
As a general comment, I would encourage shell regression tests to be
rewritten as java tests.
-Joe
More information about the jigsaw-dev
mailing list