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.
To include this library in our project we need to add the following dependency to our pom.xml:
The method org.burningwave.core.assembler.StaticComponentContainer.Modules.exportAllToAll()
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()
);
}
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()
.
Top comments (4)
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
:)
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
: )
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!
But there are people who also need solutions like the one proposed in this article