10.1. Integrating a Third-Party LibraryAlas, not all Java code is structured as Eclipse plug-ins. There is a vast array of useful Java code available in standard Java JAR files. Whether it is third-party libraries or in-house legacy function, reusing this code is extremely attractive and efficient. Fortunately, integrating these libraries into Eclipse is reasonably straightforward. The process of taking non-Eclipse code libraries and transforming them into Eclipse plug-ins is referred to as bundling. 10.1.1. Bundling SmackWriting your own XMPP messaging library is quite a challenge. Fortunately, the folks at Jive Software (http://jivesoftware.org) wrote and open-sourced their Smack messaging library. We use this throughout the Hyperbola examples and have found it to be stable and easy to use. First, get Smack from the smack directory on the CD that accompanies this book or from http://jivesoftware.org/smack/. At the time of this writing, the latest version was 1.5.0. Expand the archive somewhere convenient. Create a plug-in project using File > New > Project... > Plug-in Development > Plug-in from existing JAR archives. On the next page, identify the JARs you want in the plug-in. Click on Add External... and locate and select both smack.jar and smackx.jar from the Smack 1.5.0 install. Click Next to get the page shown in Figure 10-1. Figure 10-1. New plug-in project for bundling the Smack libraries
Fill in the project name and plug-in id. As discussed previously, the plug-in id and project name should match and the plug-in id should be based on the plug-in originator's Java package naming conventions. Here, the plug-in's code is coming from Jive Software, whose package naming convention for Smack is org.jivesoftware.smack. Use that as the project name. As you fill in the project name, the plug-in id is automatically completed by the wizard. Update the plug-in version to "1.5" to match Smack's version and fill in the provider. Note Some see this use of org.jivesoftware.* (i.e., Jive Software's spot in the plug-in id namespace) and their name as the provider as bad form. Others feel that using your own id (e.g., org.eclipsercp.smack) and name seems to claim credit for the Smack code and implies that the code is being forked. There is likely no right answer here. Eclipse itself does both. The Eclipse teams have tended to use the originator's package naming (e.g., org.apache.ant) if the code is being included verbatim. If the code is being modified or adapted, then the Eclipse namespace is used (e.g., org.eclipse.tomcat). The best bet is to ask the originator to deliver her code as bundles! When the wizard is finished, you should have a Smack plug-in project that looks like the one in Figure 10-2. Figure 10-2. Smack project after creation
The option to unzip the JAR archives is useful if you want to ship the new plug-in as a JAR itself. Otherwise, the JARs would simply be copied into the plug-in and the plug-in would have to be shipped as a directory. Aside from creating the project and exploding the JARs, the wizard generates a MANIFEST.MF file. The generated file is shown below. Notice the various values you entered are embedded in the manifest. Notice also there is a list of exported packages. These are all the packages the wizard discovered in the Smack JAR. org.eclipsercp.hyperbola/MANIFEST.MF
Bundle-Name: Smack Plug-in
Bundle-SymbolicName: org.jivesoftware.smack
Bundle-Version: 1.5
Bundle-ClassPath: .
Bundle-Vendor: Jive Software
Export-Package: .,
org.jivesoftware.smack,
org.jivesoftware.smack.debugger,
org.jivesoftware.smack.filter,
org.jivesoftware.smack.packet,
org.jivesoftware.smack.provider,
org.jivesoftware.smack.util,
...The Export-Package header lists those packages available to other plug-ins. Since the main point of bundling is to make the library classes available to others, exporting them is a good thing. Note that without the exports, the Smack code would be usable inside the Smack plug-in, but not visible outside. Notice that the bundling did not import any of the other files that were included in the Smack download. If you want the other files in the project, run the import wizard and select the File system import option. Then browse to the expanded Smack directory and choose the files to import into the existing Smack plug-in project. 10.1.2. Testing the BundlingIt's a good idea to test your newly bundled Smack just to be sure everything is in order. The easiest way to do this is to create another plug-in that uses Smack and then ensure that you can compile against it and run with it. The Smack API is very convenient, so let's just create an RCP application that sends a message using the new Smack plug-in. First, create a new plug-in project and call it smack.testing. Make it an RCP application, and on the templates page, select Hello RCP. This is similar to the procedure you followed in Chapter 4, "The Hyperbola Application," to create the Hyperbola shell. When the wizard is done, the smack.testing plug-in editor is left open. On the Dependencies page, add org.jivesoftware.smack to the Required Plug-ins list and save the file. We don't really care about a UI for our little test, so open the generated Application class and replace the run() method with the little Smack example below: smack.testing/Application
public Object run(Object args) throws Exception {
try {
XMPPConnection con = new XMPPConnection("eclipsercp.org");
con.login("reader", "secret",
Long.toString(System.currentTimeMillis()));
Chat chat = con.createChat("eliza@eclipsercp.org");
chat.sendMessage("Hi There!");
Message message = chat.nextMessage(5000);
System.out.println("Returned message: "
+ (message == null ? "<timed out>" : message.getBody()));
} catch (XMPPException e) {
e.printStackTrace();
}
return IPlatformRunnable.EXIT_OK;
}As you type the code, notice that code completion works and classes are resolved by the Java editor. This is a good signthe smack.testing plug-in can see the Smack classes. Ultimate proof comes when you save the Application class and it compiles without errors. To run the test, right-click on the project and from the context menu, select Run As > Eclipse Application. If all goes well, the test code connects to the eclipsercp.org chat server as the user "reader" and sends a message to "eliza". Eliza is actually a chat robot that responds to your messages in various ways. You should see her response in the regular Eclipse Console view. Depending on your UI setup, you may have to open it using Window > Show View > Other... > Basic > Console. Returned message: HI THERE! Here, Eliza has simply changed your message to uppercase and sent it back. Even if you get a timeout, the test has proven itselfyou were able to write a plug-in that compiled and ran with the bundled Smack library. Bundling Smack was relatively easy. Other libraries may be more complicated depending on what they are doing and how they work. The typical problems encountered revolve around Eclipse's strong notion of component, classloading, and how the classpath is managed. Many libraries assume that all classes are available on the classpath, but Eclipse puts constraints on what classes are visible and from where. The most common programming patterns that can cause problems when bundling are the following:
There are also some general issues to consider when bundling existing libraries:
If you are having problems bundling librariesfor example, you are seeing a lot of ClassNotFoundExceptions and NoClassDefFoundErrorssee Chapter 20, "Integrating Code Libraries," for instructions on how to fix these problems. |