http://java.dzone.com/articles/jxse-and-equinox-tutorial-part
————————————————————————————————————————————————————————
Abstract
This extended series of tutorials will cover the various ways that the JAVA P2P framework JXSE (formerly popularly known as JXTA, and currently the most up-to-date JAVA implementation of the JXTA specifications) can be made to work with Equinox (the engine on which Eclipse runs). It would be tempting to replace Equinox with OSGI, and indeed many of the issues covered here will work fine with alternative OSGI implementations such as Apache Felix or Knopflerfish, but I will concentrate on Equinox because it will allow us to do a few things with JXSE that requires a bit more handwork on other OSGI platforms. Besides this, I have tested the code on Equinox alone, so I don't want to get ahead of myself. This tutorial is work in progress, so the document will be re-edited a few times.
This tutorial not meant to cover the principles behind P2P in general, and JXTA/JXSE in particular. If you are interested in this, I'd recommend the (free) book Practical Jxta II by Jérôme Verstrynge, or to go through the online manuals for JXTA 2.5, JXSE 2.6 and 2.7. This first tutorial is aimed to get you started with JXSE 2.7x in an Equinox environment. The reader is expected to have a good understanding on developing plugins with the Eclipse IDE. If you are new to Eclipse I would advise you to read the excellent articles on developing plugins by Lars Vogel and brush up on OSGI and Equinox while you're at it.
A Bit of History
If you have been looking into P2P platforms for JAVA and have stumbled upon the official web sites, you may have seen that its dead silent over there, and has been for about three years. You may even be tempted to believe that JXTA is a dead project, and I could only concur. So what's the story..., and why revive this ghost through this tutorial? I will try to answer these questions as best as I can, but it may be prudent to first tell a bit about my own involvement in the JXTA project.
I have been involved in JXTA since 2002 (!), although I was hardly ever one of the more visible contributors to the project. In fact, I consider(ed) myself to be a typical JXTA user; in awe about the wonderful things that the team at SUN and the community around them was trying to achieve, but furthermore mainly interested in the results, as I was trying to use JXTA in a project I was (and am) working on. I decided to port this project to Eclipse/ Equinox in 2004 and that is when I started to encounter problems with the 2.4x release of JXTA that I eventually managed to get working. As I was not very happy with the many third-party libraries that were needed by JXTA by then, and which were evolving at a more rapid pace than the JXTA team could follow -most notably the Jetty Server- I tried to port these third party libraries to stand-alone OSGI plugins and use the official plugins of these third party libraries if possible. The results were offered to the community through the java.net project jxta-eclipse when the 2.4x version finally worked. Sadly, the 2.5x release that was released about a year later forced me to redo a lot of this work, and I never really got it to work flawlessly.
At the same time, the team at SUN was finding it hard to keep a steady pace, most likely due to the uncertainties of the future of their company, and personal issues made me loose focus on the developments of JXTA until the announcement of the 2.6x release, which initially was mainly intended to update jxta-eclipse to this new release. I was however struck by a new vibe in the JXTA community, headed by a few enthusiastic individuals such as Jérôme Verstrynge, and so I offered to lend a hand in reviewing the updated documentation, testing and debugging the 2.7x version. There were some early attempts to improve the integration with OSGI, and as I was getting to par with declarative services, I offered to help to make a more serious contribution to the JXTA code in order to make JXSE 2.8x completely OSGI ready...
.. then Oracle bought SUN, cancelled JXTA and dead silence remained.
Again some personal issues forced me to abandon my attempts to get the 2.7x integration with Equinox up and working, but early 2013 I finally got time to fulfill my promises and started working on a major revamping in order to offer JXSE as OSGI declarative services. I am currently about to commit my work so far on EclipseLabs and want to use this moment to officially revive JXSE, and hopefully get more help from others in the coming months.
So what have I done? In chronological order:
-
Changed net.jxta in order to create a full decoupling with the third-party libraries. JXTA works with the latest Jetty, Netty, javax and other relevant plugins, so the jars are no longer needed
-
Changed net.jxta to work with the Derby and H2 plugins, declarative services. In progress
-
Developed an RCP that replaces the Swing-based monitoring application. In progress.
-
Added UI tooling to show the properties of the Network Manager, the configurator and the JXSE modules in property viewers and so on. In progress.
-
Development of JXSE Plugin Projects to quickly deploy JXSE functionality in separate bundles, which can then be monitored by the RCP.
-
Development of the code of Practictal Jxta II to work with JXTA RCP as JXSE Plugins. In progress
-
Development of functionality to generates a basic JXTA plugin through an XML file located in the JXTA-INF directory. In progress.
As I hope to complete the majority of the development work in the coming weeks, I hope to have a fully functioning update site with the relevant jars up in the air in the coming months or so, and the source code available on Eclipselabs. Hopefully, by the end of the year, we can have come to a situation that developing JXTA applications in OSGI has finally become easy (ier)!
This document reflects these developments. I hope to cover the following issues:
-
Setting up a basic JXSE 2.7x bundle with a minimum of effort.
-
Improving the bundle by removing the required jars and replacing them with the relevant bundles
-
Further improvements by using dedicated JXSE bundles
-
Creating a JXSE Plugin Project from existing code
-
Creating a JXSE Plugin Project from scratch
-
Generating a JXSE Plugin Project skeleton with JXTA-INF components
The remaining section will cover the first topic. The reader has to have a good working knowledge of Eclipse and Equinox, but I will fill in the gaps as good as I can.
Oh yes, before I forget: JXSE 2.7x works fine! You may experience the usual problems with NAT traversals and firewall access, but that's part of working with JXTA. It is being used, both professionally as by many hobbyists, so the JAVA implementation of the JXTA specs deserve more attention than it's currently getting.
JXSE and Equinox
This first tutorial is aimed to get you started with JXSE 2.7x in an Equinox environment. For the purposes here, it is important (and many even experienced Eclipse users still often don't realize this) to know that you are developing plugins (or bundles) on an Eclipse IDE, which are deployed on a target, which by default is the same set of plugins that your IDE is using. If you want to be sure that the plugins you develop are as light-weight as possible, then your target needs to contain the bare minimum of plugins available, which is an OSGI implementation, such as Felix, Knopflerfish or Equinox, which is the OSGI implementation that Eclipse runs on. The down side of this choice is that you have to add a lot of plugins yourself, when they are needed. For instance, the J2EE developer IDE of eclipse has Jetty installed by default. If we want to use this functionality on a bare-bone OSGI target, we will have to add the plugins ourselves. We will opt for this choice, both for pedagogical reasons as well as that it allows us to develop light-weight JXSE projects, which can easily be ported to servers or mobile apps.
For this tutorial, we will therefore set up Eclipse (Kepler) with a bare Equinox target on Windows. We will use the standard Eclipse IDE (download here), and download the latest SDK release of Equinox, which contains, amongst others, the source files for the code.
-
Unzip the IDE to a preferred location (e.g. C:Program FilesEclipseKepler)
-
Unzip Equinox to a different location (e.g. C:ProjectsTargetEquinox)
-
Create a shortcut on your desktop to the eclipse.exe of the IDE for easy launching. It is wise to give administrator rights to this link (right-mouse click → properties → compatibility→ check 'run this program as an administrator') in order to prevent some strange errors during development. Apply this to all users if required.
-
Start eclipse and choose an appropriate workspace. This is where you will develop your plugins.
The next step is to set up the target platform:
-
Select Window → Preferences → Plug-in Development → Target Platform. You will see that it is set to the 'Running Platform' which is the IDE you've just installed.
-
'Add' a new target definition by pressing the appropriate button. Start with the default option ('Nothing') and press 'Next'.
-
Give your target definition a new name (e.g. JXSE Target)
-
'Add' a new directory by pressing the appropriate button and selecting the directory option. Then browse to the location where you unzipped Equinox. Pressing 'Finish' will add Equinox to your target definition and tell you how many plugins are available. If this is zero, then you probably have included a parent directory. The correct location always has a subdirectory called 'plugins'. You can change this by selecting the directory and pressing the 'Edit' button.
-
Complete the wizard by pressing the 'Finish' button and activate the new target by checking the appropriate checkbox.
-
Press OK to end the session.
We have now set up eclipse with a basic Equinox target. Now we have to add JXSE 2.7 x to our projects. In order to do so, you can download the latest jar file from the JXTA Project website and get the relevant library dependencies from sourceforge. The 2.7.jar file can be downloaded here. We will be using code from Practical Jxta II by Jérôme Verstrynge, as this is the most up-to-date book on the subject. Besides this, it's free!
We now have a bunch of jar files which contains all the functionality to make a working JXTA application. The default way to make a full-fledged JXTA plugin would be to create a new plugin project, add a lib directory where you put all the jars, include these to the classpath of your plugin project and start coding, right?
Wrong! Sadly this approach does not work with Equinox (I believe it would in Felix and Knopflerfish, though). The problem is that a jar-file called Bouncycastle.jar, which provides some functionality for encryption and security, will not work properly. One distinct feature of Equinox bundles is that they run in their own classloaders while bouncycastle needs to run in the root classloader. We can solve this problem by creating a fragment bundle for this jar file, which effectively 'OSGI-ifies' this jar. But if we are going to strip the library anyway, we can immediately tackle some of the other jars. Most of these are bundles themselves, or are available as bundles. If these can be used, it is possible to use the most recent bundles (provided, of course, that these still work with JXSE 2.7x). This actually is the case with the following jars in the library we downloaded earlier:
The most recent versions can be downloaded from the respective websites, or from Orbit. Some of the other libraries are not needed (Felix, for instance, as we are working with Equinox) and some are optional. We can therefore improve the JXTA performance tremendously if we try to reduce the dependencies to these legacy jars. Obviously, you do not need to all this work yourself, but can use the alternative dependencies that I've assembled myself. These can now be added to your target definition in order to enable their functionality! The plugins are fairly recent (as of time of writing), and should work without too much ado. You can unzip the folder next to the Equinox target, and include it to your target definition:
-
Select Window → Preferences → Plug-in Development → Target Platform. Select your target and press 'Edit'
-
'Add' a new directory by pressing the appropriate button and selecting the directory option. Then browse to the location where you unzipped the dependency bundles. Pressing 'Finish' will add Equinox to your target definition and tell you how many plugins are available. If this is zero, then you probably have included a parent directory. The correct location always has a subdirectory called 'plugins'. You can change this by selecting the directory and pressing the 'Edit' button.
-
Complete the wizard by pressing the 'Finish' button and 'reload' the target by checking the appropriate button.
-
Press OK to end the session.
With this we are ready to start programming!
Your first JXSE 2.7X Bundle Project
For the first JXSE bundle project we will be using an example project from Practical Jxta II. Create a new plugin project:
- Select File → New → Plugin Project (through 'Other' if it isn't immediately visible).
- Fill in the required details. Include an activator that starts upon launching.
- When the project is created, include a new file called 'lib' in the project, and copy the jxse-2.7.jar you downloaded earlier, and the org.mortbay.jetty.jar from the library dependencies to this location. Don't forget to refresh the project after this is done.
- Add the jars to the plugin's classpath by selecting the 'Runtime' tab in the manifest editor. Press the 'Add' button, browse to the lib folder and select the jars.
- Create dependencies to the bundles of the additional target we included earlier. The resulting MANIFEST-MF file should look something like this:
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Jxta test Bundle-SymbolicName: org.myorganisation.jxta.example1 Bundle-Version: 1.0.0.v20130816 Bundle-Activator: org.myorganisaton.jxta.example1.Activator Bundle-Vendor: MyOrganisation Require-Bundle: org.eclipse.core.runtime, org.jboss.netty.httptunnel;bundle-version="0.92.0", derby;bundle-version="10.8.2000002", org.h2;bundle-version="1.3.170", javax.servlet;bundle-version="3.0.0", org.jboss.netty;bundle-version="3.2.5" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Bundle-ClassPath: lib/jxse-2.7.jar, ., lib/org.mortbay.jetty.jar
Next we add two files from the examples that are covered by Practical JXTA II.
-
Copy the file 100_Starting_And_Stopping_JXTA.java from the folder A_JXTA_Connection_And_Local_Configuration into your project's source location (with the Activator,java)
-
Do the same for Tools.java in Z_Tools_And_Others
-
Refresh your project and fix the errors. The package names are wrong and some of the imports.
-
Include the example in the Activator as follows:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; .... public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; _100_Starting_And_Stopping_JXTA_Example.main(null); }
We are almost there! We only need to create a run configuration in order to get everything working:
-
Select a new debug (or run) configuration: Run → Debug Configuration
-
Add a new launch configuration based on an OSGI Framework. Give it a distinctive name and select the plugin you just made from the 'Workspace' node.
-
Press 'Add Required Bundles' to create a working launch configuration
-
Add the org.eclipse.equinox.console and the three org.apache.felix.gogo bundles
-
Validate the launch configuration. If all went well, you should get the message that 'No problems were detected'
-
Launch the configuration by pressing the appropriate button.
If all went well, you should see a lot of messages appear in the console, and three pop-up messages should come up telling you that the Jxta Network is started, connected and stopped. Congratulations, you have just successfully deployed your first JSE Bundle Project! From hence on, it should be fairly easy to integrate the examples from Practical JXTA II in your Equinox projects!
NOTE: In the above situation, the NetworkManager is started in the Activator's start method. This can give timeout exceptions during bundle start up. If you experience this, then it may be better to introduce an executor service which runs the example code:
public class Activator implements BundleActivator, Runnable{ private ExecutorService executor; public Activator( ) { super(); executor = Executors.newSingleThreadExecutor(); } public void start( ... ){ executor.execute(this); ... } public void stop( ... ){ executor.shutdown(); ... } @Override public void run() { _100_Starting_And_Stopping_JXTA_Example.main(null); System.err.println( "Container started successfully"); } }
An Added Bonus
Most developers who have worked with JXTA in the past may be pleasantly surprised that Equinox resolves one issue that has long plagued JXTA development, which is that you cannot deploy multiple JXTA projects in one development environment, as JXTA will complain that 'only one world peergroup is allowed to be active'. The fact that Equinox bundles all use their own classloaders is often a major pain for Eclipse newbies, but here it actually is an advantage: you can run multiple JXSE projects in one IDE!
In order to demonstrate this, you can copy the project you just made in the workspace, give it a different name in the manifest editor and, for demonstration purposes remove the
MyNetworkManager.stopNetwork();
in the example code.
NOTE: It is better, of course, to modify the code in such a way that stopNetwork() method is called in the stop() method of the Activator. |
Launch the projects by including the new project in the launch configuration (this is normally done automatically) and running it. You will see that both projects start without any exceptions.
Conclusion
This tutorial has given us a start to developing JXSE 2.7x applications with Equinox (and Eclipse). Seasoned Eclipse developers may already see some room for improvements, and indeed I will tackle these issues at a later stage. For now, new developers in JXTA can get started with the book Practical JXTA II and seasoned developers will have an idea to port their code to Equinox (and other OSGI platforms, as it should work there as well..besides the concurrent development of JXSE projects, that is!
In the next post , I will discuss further improvements by breaking the dependency on the outdated Jetty jar and the swing-based tools that are used in Practical JXTA II.