I am very new in OSGi and Apache Felix. At the moment I am developing a Desktop application by Maven, and I want to develop an application through plugins.
Consider Intellij Idea IDE, I am developing this kind of GUI application. The ready product will be bare one, i.e it will have MenuBar, ToolBar, StatusBar. But some other components I want to add to the application by choosing the jar file via FileChooser. After file chosen an application will install it itself. e.g. I want to add some new features through external jar file like new tool buttons or features etc.
And OSGi seems very good and proper framework to implement this feature. But in almost all OSGi books new bundle installed only through command line with tools (frameworks) like Apache Felix, Equinox etc.
I have created Github repository https://github.com/Valeme/osgi-shape-app. This is Maven project, and it has two modules. First one GUI app (osgi-shape module) which is written in JavaFX and the second one is plugin, after its installation some shapes should be drawn in the content of osgi-shape-app.
This is menu item example.
MenuItem loadExt = new MenuItem("Load extension");
loadExt.setOnAction(event -> {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Bundle ");
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("jar", "*.jar"));
File selectedFile = fileChooser.showOpenDialog(stage);
System.out.println("selectedFile = " + selectedFile);
/*
Here I want to install jar file.
*/
});
The plugin (bundle jar) will implement Component
interface. and here is an Ellipse example.
public class MyEllipse extends Ellipse implements Component {
public MyEllipse() {
super(300, 300, 60, 80);
setFill(Color.RED);
}
@Override
public Shape getComponent() {
return this;
}
}
I have included Apache Felix as a dependency in pom.xml file, now I want to install selected bundle (jar file) programmatically. I am stuck here.
How to do this?
If I understand well, in your app you want a menu item, that opens a file dialog, where you can choose a jar file that you install programatically.
You can install any bundle programmatically in OSGi with the BundleContext. See the following functions:
The functions above return a Bundle instance. After installing the bundle, you want to at least activate the bundle so it can register its OSGi services. You can do it by calling bundle.start() function.
There are more complex use-cases, where you should refresh the packages of your framework, but I think in your case (runtime installable plugins) you will hardly want to have plugins that other plugins or the app itself want to wire to.
You might want to prevent the users to pick up any JAR files. To have a restriction, I would introduce a custom Bundle-Capability in your case. If one wants to implement a plugin, he/she must add a Provide-Capability MANIFEST header to his bundle. E.g:
Provide-Capability: myappplugin;myappplugin=zipcompressor
Before installing the bundle, you can read the MANIFEST file of the JAR file with plain Java API, and process it with either bndlib or felix-utils so you can get the information if the JAR-Bundle has the necessary capability and inform the user if it does not.
Later you will want to introduce new attributes in that capability, e.g.: the necessary application version range the plugin wants to work with.
This is a couple of days work if you are familiar with OSGi.