WebStarting Equinox OSGi Apps
Join the DZone community and get the full member experience.
Join For FreeJava WebStart is a nice and easy way of deploying Java applications with one click from the web. In this blog I describe how to webstart an OSGi (Equinox) based application using Eclipse as IDE. First you develop your OSGi bundles as usual, to run your application, just create an OSGi framework launcher and run it. To webstart this set of bundles, you need to take care about a few things:
- All bundles have to be deployed as signed JAR files
- You need a feature that contains all the necessary bundles
- When exporting the feature, make sure that PDE creates a JNLP (Java Network Lauching Protocol) file (a checkbox in the export wizard) for this feature
- Provide a root JNLP file for you application
- Deploy your application to a web server and make sure that the web server is aware of the application/x-java-jnlp-file mime type
To sign the JAR files, you just need to create a keystore and a key. Sun’s tutorial gives a good overview about that. So, first create a feature and put all your bundles and the OSGi runtime bundles needed by your application in the feature. When exporting the feature, make sure that you sign all JARs and that a JNLP file is created (The wizards provides 2 tabs for that). For testing you can specify a file URL as Site URL for Java WebStart. Make sure that your site URL for testing is the file location where you deploy your feature. Here is an example for a file based Site URL: “file:/c:/temp/pm-feature-export”. Now, we need a root JNLP file and make sure it is deployed together with our feature. To do that, create a directory within your feature named “rootfiles”. In this directory, create a file yourapp.jnlp. To make sure that your JNLP file is deployed properly, edit the build.properties of your project and include “root=rootfiles” as first entry. Now you can edit the JNLP file. Here is the file I use for my dynamic OSGI demo:
< ?xml version="1.0" encoding="UTF-8"?> <jnlp spec="1.0+" codebase="jnlp.codebase" xhref="pm.jnlp"> <!-- URL to the site containing the jnlp application. It should match the value used on export. Href, the name of this file --> <information> <!-- user readable name of the application --> <title>Person Manager (A dynamic Swing OSGi demo)</title> <!-- vendor name --> <vendor>Kai Tödter</vendor> <!-- vendor homepage --> <homepage xhref="http://max-server.myftp.org/trac/pm" /> <!-- product description --> <description>Person Manager is a demo application to demonstrate best practices when it comes to dynamic OSGi based applications</description> <icon kind="splash" xhref="splash.gif" /> </information> <!--request all permissions from the application. This does not change--> <security> <all -permissions /> </security> <!-- The name of the main class to execute. This does not change--> <application -desc main-class="org.eclipse.equinox.launcher.WebStartMain"> <argument>-nosplash</argument> </application> <resources> <!-- Reference to the launcher jar. The version segment must be updated to the version being used--> <jar xhref="plugins/org.eclipse.equinox.launcher_1.0.101.R34x_v20080819.jar" /> <!-- Reference to all the plugins and features constituting the application --> <!-- Here we are referring to the wrapper feature since it transitively refers to all the other plug-ins necessary --> <extension name="Wrapper feature" xhref="features/com.siemens.ct.pm.feature_1.0.0.qualifier.jnlp" /> <!-- Information usually specified in the config.ini --> <property name="osgi.configuration.area" value="@user.home/.pm/webstart" /> <property name="osgi.bundles" value="slf4j.api@start,slf4j.simple@start,org.springframework.bundle.osgi.extender@start,org.springframework.bundle.spring.context@start,org.springframework.bundle.spring.beans@start,org.springframework.bundle.spring.core@start,org.eclipse.equinox.ds@start,com.springsource.slf4j.org.apache.commons.logging@start,com.springsource.org.aopalliance@start,org.springframework.osgi.log4j.osgi@start,com.springsource.slf4j.api@start,org.eclipse.equinox.util@start,org.springframework.bundle.osgi.io@start,org.springframework.bundle.osgi.core@start,org.springframework.bundle.spring.aop@start,org.eclipse.osgi.services@start,com.springsource.slf4j.log4j@start,com.siemens.ct.pm.ui.views.treeview.ds@start,com.siemens.ct.pm.ui.views.tableview.ds@start,com.siemens.ct.pm.ui.actions.save@start,com.siemens.ct.pm.application@start,com.siemens.ct.pm.model@start,com.siemens.ct.pm.log4j@start,com.siemens.ct.pm.model.basic@start,com.siemens.ct.pm.ui.actions.person@start,com.siemens.ct.pm.ui.views.treeview.dm@start,org.jdesktop.application@start,com.siemens.ct.pm.model.minimal@start,com.siemens.ct.pm.ui.views.bundleview@start,com.siemens.ct.pm.ui.actions.vcard@start,com.siemens.ct.pm.extender@start,com.siemens.ct.pm.ui.views.treeview.pb@start,org.ops4j.peaberry@start,com.google.inject@start,org.apache.felix.ipojo@start,com.siemens.ct.pm.ui.views.treeview.ipojo@start,org.apache.felix.org.apache.felix.ipojo.annotations@start" /> <property name="osgi.noShutdown" value="true" /> <property name="eclipse.ignoreApp" value="true" /> <property name="org.osgi.framework.bootdelegation" value="*" /> </resources> <!-- Indicate on a platform basis which JRE to use --> <resources os="Mac"> <j2se version="1.6+" java-vm-args="-XstartOnFirstThread" /> </resources> <resources os="Windows"> <j2se version="1.6+" /> </resources> <resources os="Linux"> <j2se version="1.6+" /> </resources> </jnlp>
While I don’t explain all the details, I focus on the Equinox specific things: In the resources section, you need to specify the main JAR file, which is your preferred Equinox launcher. The you have to link to the JNLP file for your feature. This JNLP file was created by PDE for you. Then you want to specify a few Equinox-specific properties:
- osgi.configuration.area: the configuration area where OSGi stores runtime information
- osgi.bundles: The list of bundles you want to start. You don’t have to specify versions here, just use the schema: @start. You can also specify the start level of the bundles like @2:start
- osgi.noShutdown: Must be true, since you did not specify an Eclipse application
- eclipse.ignoreApp: Must be true for the same reason
- org.osgi.framework.bootdelegation: Value “*” helps to load JRE classes, e.g. if you use a Swing GUI
Having created a similar JNLP file for your application, you can deploy it locally and test it usinf file based Java WebStart. If everything is OK, change the WebStart Site URL (in both, your root JNLP file and the feature export wizard) to the web server real URL.
If want to take a detailed look at a running example, check our my dynamic OSGi demo. If you have Java 6 running and want to launch the demo using WebStart, just click here.
Opinions expressed by DZone contributors are their own.
Comments