Back when the
javax.lang.model API was being designed as part of JSR 269, while the API was primarily intended for use at compile-time with annotation processing, the expert group also wanted the API to be usable in other contexts as well, including at runtime.
JEP 119, javax.lang.model Implementation Backed by Core Reflection, proposed adding such an alternative runtime implementation of
javax.lang.model to JDK 8. Such an implementation has recently been pushed as sample code in the JDK 8 langtools repository.
At a high level, the sample code is at its core repeated uses of the adapter pattern, translating between the core reflection API and the
However, there were a number of design issues in what interface the
javax.lang.model implementation for core reflection should expose.
First, should a core reflection specialization of
javax.lang.model expose a more specific interface? There are some advantages to just implementing the base API defined in the existing interfaces; it is the simplest approach and would appear to maximize the ability to inter-operate with other implementations. However,
javax.lang.model depends on hidden state to define concepts like equality, so there is intrinsically limited inter-operation between disjoint implementations. Therefore, especially in sample code, it was viewed as worthwhile to experiment with a more specific API in the core reflection case.
To make the
javax.lang.model backed by core reflection more specific, for each
FooElement interface in
ReflectionFooElement subinterface was defined, as shown in the diagram below.
The subinterfaces are specialized in a few ways:
FooElement, a covariant override in the subinteface was defined to return a
List< ? extends FooElement>, a covariant override in the subinteface was defined to return a
getBar(FooElement arg)methods defined in the
Elementshelper interface, add a
getBar()method to the
getSourcemethod to the root
ReflectionElementinterface to return the underlying core reflection object being adapted and add covariant overrides in subinterfaces as appropriate.
ReflectionElementinterface implements the full
AnnotatedElementinterface, not just the subset of its methods found in the base
A cost of specializing the API is the need to define a new visitor interface as well. Covariant overrides cannot be used as in the element modeling interfaces since the visitor methods take elements in the argument position rather than the return position.
Generally, working on the core reflection specialization proceeded as expected.
Equality determinations were generally delegated to core reflection source object; in other words, two
ReflectionElement objects are equal if they are instances of the same interface and if their sources are
Writing the sample code highlighted several shortcomings of the core reflection API which have been addressed in Java SE 8, including the addition of an
Executable type to abstract over the commonalities of
The sample code also benefited from other reflection changes in Java SE 8, such as the introduction of a
java.lang.reflect.Parameter class and retrofitting
TypeVariable to extend
While significantly more testing would be needed to productize
javax.lang.model backed by core reflection, even as sample code it validates a number of the technological decisions made in JSR 269 and is an interesting demonstration of how one of the platform's reflective APIs can be bridged to another.