This chapter covers:
- why
exports
directives do not suffice for reflection
- opening packages and modules to reflection
- updating reflection-based code to work with modules
- alternatives to the reflection API
- analyzing and modifying module properties
- creating module layers to dynamically load modules at run time
If you’re working on a Java application, chances are very good that you rely on Spring, Hibernate, JAXP, GSON, or the like. What are "the like"? Frameworks that use Java’s reflection API to inspect your code, search for annotations, instantiate objects, or call methods. Thanks to reflection, they can do all that without having to compile against your code.
Moreover, the reflection API allows frameworks to access non-public classes and non-public members. It has superpowers beyond what is possible with compiled code, that bounces off of package boundaries if classes or members are not public. The thing is, with modules, reflection doesn’t work out of the box, anymore.
Quite the opposite, reflection lost its superpowers and is bound to the exact same accessibility rules as compiled code: It can only access public members of public classes in exported packages. These frameworks, on the other hand, use reflection over fields and methods that very often aren’t public and on classes that you might not want to export because they are not part of a module’s API. What to do then? That’s what this chapter is all about!