Reflection (3 Part Series)
1 Making reflection fully work on Java 16 and later
2 Exporting all modules to all modules at runtime on Java 16 and later
3 How to create your own dependency injection framework in Java
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()
);
}
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()
.
Reflection (3 Part Series)
1 Making reflection fully work on Java 16 and later
2 Exporting all modules to all modules at runtime on Java 16 and later
3 How to create your own dependency injection framework in Java
原文链接:Exporting all modules to all modules at runtime on Java 16 and later
暂无评论内容