How to Export All Modules to All Modules at Runtime in Java
In this article, take a look at a solution as to how to export all modules to all modules at Runtime in Java 9.
Join the DZone community and get the full member experience.
Join For FreeDue to the new module system, Java 9 does not allow an application by default to see all classes from the JDK, unlike all previous versions of Java. 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 what if we have more environments, and we don't want to have to change JVM arguments 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.
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: It is not necessary to put in the burningwave.static.properties
file all the properties present in the relative link supplied before):
Modules.exportAllToAll();
//Now that we have called exportAllToAll () we can use any class of any module
Class<?> bootClassLoaderClass = Class.forName("jdk.internal.loader.ClassLoaders$BootClassLoader");
Constructor<? extends ClassLoader> constructor =
ClassLoader.getPlatformClassLoader().getClass().getDeclaredConstructor(bootClassLoaderClass);
constructor.setAccessible(true);
Class<?> classLoadersClass = Class.forName("jdk.internal.loader.ClassLoaders");
Method bootClassLoaderRetriever = classLoadersClass.getDeclaredMethod("bootLoader");
bootClassLoaderRetriever.setAccessible(true);
ClassLoader newBuiltinclassLoader = constructor.newInstance(bootClassLoaderRetriever.invoke(classLoadersClass));
System.out.println(newBuiltinclassLoader + " instantiated");
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, in reference to the example above, if we want to limit the export to the package of our interest, we have to replace the call exportAllToAll()
with exportPackageToAllUnnamed("java.base", "java.net")
.
From here you can download/clone the tutorial shared on GitHub.
Published at DZone with permission of Jim Jerald Burton. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments