JDK-8208191 : package-info handling in RoundEnvironment.getElementsAnnotatedWith
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 12
  • Submitted: 2018-07-25
  • Updated: 2018-07-25
  • Resolved: 2018-07-25
Related Reports
CSR :  
Description
Summary
-------

Change the `RoundEnvironment.getElementsAnnotatedWith` family of methods to obey their specs to *not* scan the contents of a package or module by virtue of examining a `package-info` or `module-info` file, respectively.

Problem
-------

The implementations of the `RoundEnvironment.getElementsAnnotatedWith` family of methods does not obey the specification for treatment of `package-info` and `module-info` files:

> Elements in a package are not considered included simply because a
> package-info file for that package was created. Likewise, elements of
> a module are not considered included simply because a module-info file
> for that module was created.

The current implementation scans a package or module if a `package-info` or `module-info` files is among the root elements of a round.

Solution
--------

Change the implementation to obey the specification. The straightforward portion of the implementation change is to have the scanner not scan the contents of package and modules. A second portion of the changes concerns handling of `Class` type tokens to indicate which annotations types to look for.

The `getElementsAnnotatedWith` methods with a `java.lang.Class` parameter need some way to bridge between the core reflection world and the compile-time reflection world of `javax.lang.model`. The way to do this is to construct a `TypeElement` for an annotation type corresponding to the `Class` object for the annotation type argument by mapping from the name of the annotation type to a type element via `Elements.getTypeElement(name)`. The behavior of `Elements.getTypeElement(name)` was redefined in JDK 9 to account for modules since a name can correspond to multiple types post-modules. In addition, a two-argument form of `Elements.getTypeElement(name)` was added in 9 taking a module argument as well as a name. The revised implementation first tries the one-argument form of `Elements.getTypeElement` and if that is unsuccessful, fails over to the two-argument version trying using a module argument matching the name of the runtime module of  the annotation `Class` token. 

First attempting the one-argument form increasing behavioral compatibility with the pre-modules system. The two-phase approach is reasonable; however, the runtime and compile-time module arrangement may differ, including from the compiler operating in single-module mode (http://openjdk.java.net/jeps/261) treating types it compiles as being in the same named module even if one the class path outside of the module-inferred directory structure. The hazard of runtime vs compile-time differences in modules for annotation types is intrinsic to allowing the model-breaking convenience of using `Class` objects as tokens. Similar issues are present when using the `AnnotatedConstruct` methods taking a `Class` object. 

Specification
-------------

No specification change.