X

Geertjan's Blog

  • May 18, 2009

Incorporating an OSGi Dictionary Service in a NetBeans Platform Application

Geertjan Wielenga
Product Manager
Build 137 of Netigso provides exactly what I was looking for. I can now create a dictionary application that uses an OSGi service for checking the entered words:

Isn't that cool? Swing + OSGi on the NetBeans Platform. Marriage made in heaven?

And here's the whole application structure:

Here's the whole story in code.

  1. Create an OSGi bundle that defines an interface:
    package org.demo.dictionary.iface;
    public interface DictionaryInterface {
    public boolean checkWord(String word);
    }

  2. Next, define an OSGi bundle that implements the interface:
    package org.demo.dictionary.service;
    import org.demo.dictionary.iface.DictionaryInterface;
    public class DictionaryService implements DictionaryInterface {
    String[] WORDS = {"see", "you", "in", "san francisco"};
    public boolean checkWord(String word) {
    for (int i = 0; i < WORDS.length; i++) {
    if (WORDS[i].equals(word)) {
    return true;
    }
    }
    return false;
    }
    }

    For the above to be possible, the first OSGi bundle needs to be on the classpath of the second OSGi bundle. Otherwise you don't have access to the interface you're implementing. That's a service offered by the NetBeans Platform application, acting as a container for the OSGi bundles, making the OSGi bundles available to each other, only requiring you to explicitly set the dependency, using the standard NetBeans Platform tools for doing so.

  3. Next, again in the second bundle, use the Module Installer, as discussed in yesterday's blog entry, to create a BundleActivator and then register the service in the BundleContext:
    package org.demo.dictionary.service;
    import org.demo.dictionary.iface.DictionaryInterface;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    public class Installer implements BundleActivator {
    public void start(BundleContext c) throws Exception {
    c.registerService(DictionaryInterface.class.getName(), new DictionaryService(), null);
    System.out.println("Registered the dictionary service!");
    }
    public void stop(BundleContext c) throws Exception {
    }
    }

    The Module Installer automatically registers the BundleActivator in the OSGi bundle's Manifest, just like the OSGi Bundle wizard registered the other required keys in the Manifest, so that there is nothing at all I needed to do manually in the Manifest.

  4. Finally, create a NetBeans module. Include a TopComponent with some UI for entering the word that should be checked. Under the JButton, define the following code, taking particular note of the line in bold, which is where the service from the OSGi BundleContext is retrieved into the world of the NetBeans Platform:
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         DictionaryInterface dict = Lookup.getDefault().lookup(DictionaryInterface.class);
    if (dict != null) {
    if (dict.checkWord(jTextField1.getText())) {
    jTextArea1.setText("Correct!");
    } else {
    jTextArea1.setText("Wrong!");
    }
    } else {
    jTextArea1.setText("No service available!");
    }
    }

Again, the above implies that you've set a dependency on the first OSGi bundle. But not on the second OSGi bundle! That means that the client is loosely coupled from the service. I.e., you could remove the service and replace it with another one, without changing any code in the client. Or you could use Lookup.getDefault().lookupAll if you anticipate that multiple dictionary services will be available to the application.

Now simply run the application and, to the end user, the NetBeans module handles the OSGi dictionary service exactly as if it were provided by a NetBeans module. Thanks to the Apache Felix OSGi Tutorial for the code used in this blog entry.

Join the discussion

Comments ( 3 )
  • Varun Nischal Monday, May 18, 2009

    Your are writing amazing blog series, its so difficult now to resist myself from not trying all this ;)

    Amazing!


  • JJ Monday, May 18, 2009

    Really great post.

    Thanks.


  • jocke Tuesday, May 19, 2009

    Thanks for a great blog. I think it would be cool with an entry about the new jet parsing api and embedded languages. I'm locking for away to embed javascript into an XML file for my plugin openlaszlo-framework.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha