Pattern 7 - Open modules for reflection

Reflection is an important feature in the Java programming language, allowing the ability to inspect and modify types dynamically at runtime. This is another feature that has been put to good use by frameworks such as Spring, Hibernate, and others. These frameworks use reflection to examine your classes for annotations and interface implementations to infer information about how to treat your code. You might use reflection in your own code to achieve this dynamic functionality.

How does reflection fit into the concepts of modularity we've learned so far? Like we've seen before, the default behavior of strong encapsulation that protects types in a module from static access offers similar protection for reflective access as well. A Java type can be accessed through reflection if it's in a module that exports it, and the type calling the reflection API is in a module that reads the other module.

This results in a potential problem because of how reflection has been traditionally used in Java, especially in many of the frameworks like we've mentioned earlier. Frameworks like Spring expect to scan through your entire code base looking for classes that are annotated with certain key annotations. A lot of reflection API usage in Java code bases over the years have been implemented with an implicit understanding that the classes being reflected on are available for them to access. Once you move those types into modules, all the encapsulated types are effectively sealed off and not available for reflection. One easy solution is to expose everything! So, every module exposes all types that need to be accessed reflectively. But this is not a good idea because of the concept of the module API we've discussed earlier. The type that a module exposes using the exports clause is the module API. By exposing an otherwise private type just because it contains an annotation for the Spring framework, Hibernate, JPA, or any other such framework that uses reflection, we are adversely impacting the API of the module and the purpose of string encapsulation is defeated.

To address this issue and to still provide an option of using reflection with such frameworks, the platform has introduced a concept called open modules. These are a type of Java modules that still encapsulate types like we are familiar with, but with one major difference. The encapsulated types in these open modules are available for reflective access at runtime, without you having to allow compile-time access that an exports declaration would have provided.

How do you make a Java module an open module? Very simple. Just add the open keyword in front of the module definition in module-info.java:

    open module <module-name> { 
    } 

With this, the contents of the module are still encapsulated (except for any packages that you export in the module definition). But all the packages in the module are now available for access at runtime using reflection by any module that reads this module.

Remember that the open keyword doesn't make the module open for reflective access for all modules. A module that needs to access any such types using reflection will still need to read the module that contains the type using the requires keyword.

Not only entire modules, but even individual packages can be marked as open with the  opens keyword followed by the specific package you'd like to open for reflection. This provides more fine-grained control when you know that there are only certain classes in the module that need to be reflected upon:

    module modulename { 
      opens package.one; 
      opens package.two to anothermodule; 
      exports package.three; 
    } 

In the preceding example, the package package.one is available for reflection by all modules that read module modulename. The package package.two is available for reflective access only by module anothermodule, if it chooses to require it. And package package.three is available for both reflective and compile-time access because it is exported.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.20.68