In my RCP application, I bundle a Java 11 VM with JavaFX 14. At run-time, I get a continual flood of exceptions (quoted below) from attempts by the JavaModuleLayerModification to modify the exports and opens of JavaFX bundles as specified by a few declarations in e(fx)eclipse bundle manifests. I don't need these, so it would be nice either to be able to easily turn off this functionality or else stem the flood of exceptions. The exception is thrown seemingly every time the class loader is asked for a class that isn't in the JRE because the FXClassLoader never completes its module modifications and so tries every time to do them, and fails.
I think the root cause of the problem is that the JavaFX modules that the e(fx)eclipse is trying to modify are discovered as already being in the base layer, as I have packaged them in my JRE. So, the assertion that they are in the layer created by the JavaModuleLayerModification fails. It is simply not possible for e(fx)eclipse to modify these modules using the JPMS API.
The work-around I am doing in my application for now is to exclude the org.eclipse.fx.osgi bundle from the package build because it only provides this class loader hook and I don't need that. However, this will be a problem when eventually the bundle gains more functionality.
So, perhaps this issue can be addressed for the general case by any combination of:
- a system property (e.g.
-Dorg.eclipse.fx.osgi.modulemodification.disabled=true) to opt out of the JavaModuleLayerModification processing of reads/exports/opens directives in bundle manifests. By default it is enabled with false
- remember attempted module modifications that failed, to not try them again, thus cutting off the flood of exceptions on
stderr
- use the JPMS API to check whether the attempted module modification can be expected to work: the case here is an attempt to modify a module that already is in a layer, so can the
JavaModuleLayerModification class first check whether that is so?
- an elaboration of the previous item: in my application, is use
--add-exports and --add-opens on the command-line to export and open JavaFX internals to all unnamed modules (my application's OSGi bundles). These make the declarations processed by the JavaModuleLayerModification redundant, so perhaps it could check whether a modification it would attempt is redundant for such reason?
The exception:
FXClassLoader#collectModifications - Reads: []
FXClassLoader#collectModifications - Exports: [javafx.graphics/com.sun.javafx.scene=BUNDLE(@150), javafx.graphics/com.sun.javafx.application=BUNDLE(@164), javafx.graphics/com.sun.glass.ui=BUNDLE(@164)]
FXClassLoader#collectModifications - Opens: [javafx.graphics/javafx.scene=BUNDLE(@150)]
FXClassLoader#advancedModuleLayerBoostrap - Using advanced layer creation to apply patches
JavaModuleLayerModification#applyConfigurations - Exporting 'javafx.graphics/com.sun.javafx.scene=BUNDLE(@150)'
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at org.eclipse.fx.osgi.fxloader.jpms.ModuleLayerWrapper$ControllerWrapper.addExports(ModuleLayerWrapper.java:173)
at org.eclipse.fx.osgi.fxloader.jpms.JavaModuleLayerModification.applyConfigurations(JavaModuleLayerModification.java:110)
at org.eclipse.fx.osgi.fxloader.FXClassLoader.advancedModuleLayerBoostrap(FXClassLoader.java:483)
at org.eclipse.fx.osgi.fxloader.FXClassLoader.initModuleLayer(FXClassLoader.java:426)
at org.eclipse.fx.osgi.fxloader.FXClassLoader.getModuleLayer(FXClassLoader.java:293)
at org.eclipse.fx.osgi.fxloader.FXClassLoader.findClassJavaFX11(FXClassLoader.java:207)
at org.eclipse.fx.osgi.fxloader.FXClassLoader.postFindClass(FXClassLoader.java:144)
at org.eclipse.osgi.internal.loader.BundleLoader.searchHooks(BundleLoader.java:530)
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:493)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:425)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:171)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at java.xml/javax.xml.parsers.FactoryFinder.getProviderClass(FactoryFinder.java:108)
at java.xml/javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:183)
at java.xml/javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:147)
at java.xml/javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:271)
at java.xml/javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:147)
at org.eclipse.osgi.internal.framework.XMLParsingServiceFactory.createService(XMLParsingServiceFactory.java:59)
at org.eclipse.osgi.internal.framework.XMLParsingServiceFactory.getService(XMLParsingServiceFactory.java:51)
...
Caused by: java.lang.IllegalArgumentException: module javafx.graphics not in layer
at java.base/java.lang.ModuleLayer$Controller.ensureInLayer(ModuleLayer.java:216)
at java.base/java.lang.ModuleLayer$Controller.addExports(ModuleLayer.java:268)
... 168 more
In my RCP application, I bundle a Java 11 VM with JavaFX 14. At run-time, I get a continual flood of exceptions (quoted below) from attempts by the
JavaModuleLayerModificationto modify the exports and opens of JavaFX bundles as specified by a few declarations in e(fx)eclipse bundle manifests. I don't need these, so it would be nice either to be able to easily turn off this functionality or else stem the flood of exceptions. The exception is thrown seemingly every time the class loader is asked for a class that isn't in the JRE because theFXClassLoadernever completes its module modifications and so tries every time to do them, and fails.I think the root cause of the problem is that the JavaFX modules that the e(fx)eclipse is trying to modify are discovered as already being in the base layer, as I have packaged them in my JRE. So, the assertion that they are in the layer created by the
JavaModuleLayerModificationfails. It is simply not possible for e(fx)eclipse to modify these modules using the JPMS API.The work-around I am doing in my application for now is to exclude the
org.eclipse.fx.osgibundle from the package build because it only provides this class loader hook and I don't need that. However, this will be a problem when eventually the bundle gains more functionality.So, perhaps this issue can be addressed for the general case by any combination of:
-Dorg.eclipse.fx.osgi.modulemodification.disabled=true) to opt out of theJavaModuleLayerModificationprocessing of reads/exports/opens directives in bundle manifests. By default it is enabled withfalsestderrJavaModuleLayerModificationclass first check whether that is so?--add-exportsand--add-openson the command-line to export and open JavaFX internals to all unnamed modules (my application's OSGi bundles). These make the declarations processed by theJavaModuleLayerModificationredundant, so perhaps it could check whether a modification it would attempt is redundant for such reason?The exception: