Writing External Components for Jabberwocky

In my last 2 post (here and here) I talked about setting up Jabberwocky and deploying some components into the container. In this post I would like to show you how you can develop your own XEP-0114 components for Jabberwocky.

Setup (again!)

Download the latest bundle here. Select the valentine version. The zip bundle contains the following files

  1. jabberwocky_support.jar, xmpp-gf-container.jar – the XMPP container JAR files
  2. uppercase.xar, weather.xar – sample applications. See this
  3. hellocomponent_2011-02-15_13.41.25.zip – this is the application that we will be developing in this blog; contains source and also hellocomponent.xar. This is a NetBeans project so use NetBeans to open it
  4. com-kenai-jabberwocky-xmppcontainer.nbm – this is a NetBeans plugin that adds Jabberwocky libraries into NetBeans. More of this later
  5. xep-0114.xml – a Jabberwocky application descriptor file. More of this later

Glassfish

Copy jabberwocky_support.jar and xmpp-gf-container.jar into $GLASSFISH_HOME/glassfish/modules directory. If you have installed previous version, you can overwrite them with these new files. There is a detailed post here on how to install and verify the installation.

NetBeans

Download NetBeans 6.9.1 and install com-kenai-jabberwocky-xmppcontainer.nbm plugin. Verify that the plugin have been installed by doing the following Tools | Libraries and look for ‘Jabberwocky API’ in the Libraries window. See figure below

Developing Components

The External Component

  1. Create a new class library project in NetBeans. File | New Project | Java | Java Class Library. Click Next and enter the details of your project. Call it hellocomponent for the sake of this exercise
  2. Now create a package call mycomp; right-click on Source Packages node, New | Java Package. Call it mycomp.
  3. Right click on mycomp node, New | Java Class to create a Java class. Call the class HelloComponent.java.
  4. Now you have to decide how you want to implement the external component; you can do this by either by implementing org.xmpp.component.Component interface or by extending org.xmpp.component.AbstractComponent class. I’ve written a series of blogs on these 2 methods and their trade-offs. See this and this. So I won’t be going into any details here.

    If you are extending AbstractComponent, extend from com.kenai.jabberwocky.xmppcontainer.AbstractComponent (will refer to it as Jabberwocky component from now onwards) instead of org.xmpp.component.AbstractComponent. The reason is that Jabberwocky component is designed to run in the Jabberwocky container. If you try to deploy you component by extending AbstractComponent, Jabberwocky will prevent your component from being loaded.

    Jabberwocky component is method and feature compatible with AbstractComponent. This is so that if you are migrating an existing component that is based on AbstractComponent to Jabberwocky container, just change the package to com.kenai.jabberwocky.xmppcontainer. The Jabberwocky component class is bundled with the NetBeans plugin (com-kenai-jabberwocky-xmppcontainer.nbm) that you install in the previous section. So when you perform code completion in the editor, Jabberwocky component class and the original AbstractComponent class will be display in the popup; be sure to select the former.

    There are however some differences between the two:

    • compMan (ComponentManager) member in AbstractComponent has been renamed to componentManager in Jabberwocky component class
    • You cannot add (ComponentManager.addComponent()) or remove (ComponentManager.removeComponent()) other external component when you are running in Jabberwocky. These methods are basically noop and no exception are thrown. I’ve not figure out the implication of this. Will relook at this later.
    • Call ComponentManager.setProperty() will not persist your property across container reboots. Property persistence is quite easy to implement but I’m not sure how useful this is.

Component Descriptor

Create an xml file call xep-0114.xml with the following structure

<subdomain name=’greetings’ domain=’batcomputer’ port=’5275′>
   <component-class name=’mycomp.HelloComponent’/>
      <properties>
         <property name=’language’ value=’malay’/>
      </properties>

</subdomain>

  1. The subdomain specifies the name subdomain name, the domain name and the port number. In the example above, the subdomain name is greetings, the domain name is batcomputer and the port is 5275. You can omit the port attribute if it is 5275. So if you are addressing fred from this subdomain, the JID would be fred@greetings.batcomputer.
  2. The component-class tag specifies the fully qualified class name of your class that implements the Component interface or extends the Jabberwocky component class. In the current implementation, a descriptor can only support one component.
  3. properties tag encloses a series of property tags. These values can be read by your component using ComponentManager.getProperty(). I have an example of using this in the latest bundle. properties tag is an optional tag.

Packaging

Once you have your component and a descriptor, you need to package them into a XAR (XMPP ARchive) file. XAR is really a JAR file create using jar. The following diagram shows the structure of a XAR package

The name of this bundle is call hellocomponent.xar. The archive contains 2 directories (classes, lib) and a XML (descriptor file). Your component classes goes into the classes directory. This directory is mandatory. Do not JAR or ZIP your packages. Any libraries dependencies goes into the lib directory. You can omit lib directory if you do not have any libraries. Finally the component descriptor is located at the root of the package. JAR the directory and files and change the suffix from .jar to .xar.

Hopefully by the next iteration of the NetBeans plugin, I’ll automate this process so that when you perform a build, NetBeans will also create the XAR archive for you.

Deploying the XAR Archive

Lets assume that you are going to deploy hellocomponent.xar to

  • subdomain: greetings
  • domain: batcomputer (or whatever is the name of your domain)
  • shared secret: hello

First and foremost, go into your XMPP server and create a subdomain with the corresponding shared secret. If you are using openfire, I’ve talked about the setup here (scroll right to the end of the post).

Now you need to setup Jabberwocky container so that it knows about the domain, subdomain and share secret of the subdomain. I’ve also talked about it here as well. Look at ‘Configuring Domain and Subdomain’. You need to start Glassfish before you can do this.

Finally you deploy hellocomponent.xar with the following command

asadmin deploy hellocomponent.xar

Test the component by starting a chat with fred@greetings.batcomputer. Any name will do. If your component fails tostart up, check Glassfish’s log files. They can be found in $DOMAIN_DIRECTORY/logs/server.log. The default logging level is at INFO. You can change to log level to FINER for more details. See Glassfish Administration Guide.

Note: I’ve used Glassfish 3.0.1, NetBeans 6.9.1 and JDK 1.6 u23 to develop and test. Any other combination (especially Glassfish 3.1) of the above, YMMV.

Send me feedback. Till next time.

3 Responses to Writing External Components for Jabberwocky

  1. Stefano says:

    Hi,
    following your suggestion I am trying to deploy my component to GlassFish.

    Just a question: I have the GlassFish server and the GlassFish Eclipse plugin installed and working (not using NetBeans). Is there a way to create a project in Eclipse that will be automatically deployed in the GlassFish server?

    I wouldn’t have to manually re-deploy everything for each change I make..

    Thanks,
    Stefano

Leave a comment