Using FXMLLoader in OSGi is not completely trivial. This article explains, how to do it. The osgisnippets project contains a project bundle_set5fxml, which is used for that.
Loading an fxml file is done like that:
So let's just try that and see what happens:
The fxml file references the class ClickmeController, which is inside the set5fxml bundle. Obviously FXMLLoader doesn't use a bundle class loader and thus cannot load the controller class. There's a method FXMLLoader.setDefaultClassLoader():
The class loader passed into setDefaultClassLoader must be a bundle class loader, so it should be one from a class which is loaded from this bundle. (See below for more information.) So that worked well enough:
There are a few other things, which must done to make it work. Apache Felix does not export the JavaFX packages by default, so the relevant packages must be added to the list of extra system packages. This is done in the class OSGiFwLoader:
Also the bundle must import the required packages. In the osgisnippets project this is done in the file build.default.properties:
Coming back to the class loader given to FXMLLoader.setDefaultClassLoader: In the sample bundle, the ClassLoader of the Activator class is used. This works, because the Activator class is part of the bundle and thus loaded by the bundle class loader. What happens, if the class loader of the BundleActivator class is used? An error is logged and the underlying exception with stack trace is this one:
In osgisnippets and its guitool application, the classes of the OSGi framework (Apache Felix) are loaded by the system class loader. The felix jar is in the classpath of the guitool application. The BundleActivator interface is part of the felix jar and its class loader is the system class loader. However, the system class loader doesn't know about the bundles and it can't find the ClickmeController class. To summarize: Make sure, the class loader passed into FXMLLoader.setDefaultClassLoader() is actually a bundle class loader.
FXMLLoader API doc:
Introduction to FXML:
- Apache Felix: http://felix.apache.org/
Source code of OSGi snippets is at the project site: