DEV Community

Cover image for Exporting all modules to all modules at runtime on Java 16 and later
JJBRT
JJBRT

Posted on • Updated on

Exporting all modules to all modules at runtime on Java 16 and later

From Java 9 is not allowed by default an application to see all classes from the JDK, unlike all previous versions of Java, due to the new module system. So if we try to access some reserved module we obtain an error like this:
module <module-name> does not "opens <package-name>" to unnamed module.
Everyone knows that we can solve this exception by using the JVM parameters --add-exports or add-opens, but how we can do for example if we have more environments and we don't want to have to change JVM args across these environments?
In this situation Burningwave Core comes to our aid by providing us with the method org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll() that allows us to export all modules in all modules, thus solving our problem.
This method is called by default on the initialization of the class org.burningwave.core.assembler.StaticComponentContainer but this behavior can be changed by including in the base folder of your class path a file named burningwave.static.properties that contains a property named modules.export-all-to-all whose value is false thus leaving us the possibility to call this method manually (note that it is not necessary to put in the burningwave.static.properties file all the properties present in the relative link supplied before):

org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll();
//Now that we have called exportAllToAll () we can use any class of any module
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
ClassLoader classLoader = new URLClassLoader(new URL[] {}, null);
method.invoke(
    classLoader,
    org.burningwave.core.assembler.StaticComponentContainer.Resources.getClassPath(AllModulesToAllModulesExporter.class).getURL()
);
Class<?> fieldsHandlerClass = classLoader.loadClass(FieldsHandler.class.getName());
if (FieldsHandler.class != fieldsHandlerClass) {
    System.out.println(
        FieldsHandler.class.toString() + " and " + fieldsHandlerClass.toString() + " are loaded from the same bytecode but they are different instances:" +
        "\n\t" + FieldsHandler.class + " is loaded by " + FieldsHandler.class.getClassLoader() +
        "\n\t" + fieldsHandlerClass + " is loaded by " + fieldsHandlerClass.getClassLoader()
    );
}
Enter fullscreen mode Exit fullscreen mode

The Modules component also exposes other methods for greater granularity:

  • export(String moduleNameFrom, String moduleNameTo)
  • exportPackage(String moduleNameFrom, String moduleNameTo, String... packageNames)
  • exportPackageToAll(String name, String... packageNames)
  • exportPackageToAllUnnamed(String name, String... packageNames)
  • exportToAll(String name)
  • exportToAllUnnamed(String name)

Therefore, referring to the example above, if we want to limit the export to the package of our interest we have just to replace the call exportAllToAll() with exportPackageToAllUnnamed("java.base", "java.net").

From here you can download/clone the tutorial shared on GitHub that contains another example about to use the method org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll().

Discussion (5)

Collapse
gedmarc profile image
Marc Magon • Edited

The step should be to move forward, to correctly define your modules, and the adaptions to the language

All dynamic module management is temporary, JDK 17 was a warning hammer I feel - the JRT file system and Native system (or the new "JRE") are completely read only, intentionally.
I would like to see articles on adaption and moving forward, rather than these temporary work-arounds that are inevitably doomed due to a (finally) forward moving pure OOP language

:)

Collapse
jjbrt profile image
JJBRT Author

You say that "I would like to see articles on adaption and moving forward" but I think you also like this kind of articles otherwise you wouldn't have read it

: )

Collapse
gedmarc profile image
Marc Magon • Edited

Or I literally took the time to analyze and see what you were talking about after trying to post click-baits on github forums, and spent my most precious resource (time) on trying to ensure that you switch tracks from trying to keep the old ways of coding, to migrating to the new form of code.
Either or of course,
Let's try move forward, and put these old ways behind us - the future is bright!

Thread Thread
jjbrt profile image
JJBRT Author • Edited