If you are looking for Jitsi Meet, the WebRTC compatible video conferencing product click here.

previous | TOC | next

Implementing a Protocol

Creating the shell

Before we start really coding the protocol, we’ll have to take care of a few details such as creating our protocol packages, adding a build target in build.xml and creating our bundle manifest and activator class.

Java packages

In general, you are free to choose the package structure you’d like. In this tutorial, however, we’ll be using the same conventions that apply to protocol provider implementations maintained by sip-communicator.org. You might won’t to follow them yourself, especially if you would like to get your implementation adopted and shipped with Jitsi.

According to Jitsi conventions the package containing the Gibberish protocol implementation should be

 net.java.sip.communicator.impl.protocol.gibberish

and it must be located inside the src source tree. Actually, that’s exactly where you’ll find it if you download the sip-communicator source code.

Bundle activator.

The bundle activator is in a way the entry point to our protocol bundle. If you’re not familiar enough with OSGi bundles and how they work, you might won’t to have a look at the creating OSGi services tutorial. bundle. It’s start method is the first method of our package that will be executed. We’ll be doing some quite important stuff here but we’ll get back to it later. For now we would only make sure that we keep a reference to the currently valid bundle context so that we could have it at hand when necessary and be able to retrieve it through the getBundleContext() method. We’ll also add some logging so that we could later check in the log files whether our plugin has been loaded.

package net.java.sip.communicator.impl.protocol.gibberish;

import org.osgi.framework.*;
import net.java.sip.communicator.util.*;

public class GibberishActivator
    implements BundleActivator
{
    private static final Logger logger
            = Logger.getLogger(GibberishActivator.class);

    /**
     * The currently valid bundle context.
     */

    private static BundleContext bundleContext = null;

    /**
     * ...
     */

    public void start(BundleContext context)
        throws Exception
    {
        this.bundleContext = context;       
        logger.info("Gibberish protocol implementation [STARTED].");
    }
    /**
     * ...
     */

    public void stop(BundleContext context)
        throws Exception
    {
        logger.info("Gibberish protocol implementation [STOPPED].");
    }

    /**
     * ...
     */

    public static BundleContext getBundleContext()
    {
        return bundleContext;
    }
}

That should be enough for starters. You may notice that the actual GibberishActivator contains one or two extra utility methods that we use to retrieve instances of the currently valid protocol provider factory or other OSGi services.

If you’re being curious you may also have a look at existing protocol activators such as the IcqActivator and the SipActivator.

Manifest file

We need this file in order to describe our protocol OSGi bundle to Felix. Jitsi convention states that manifest files are kept in the top level directory of the corresponding bundle. In the case of our Gibberish example this would be:

 sip-communicator/src/net/java/sip/communicator/impl/protocol/gibberish

The manifest itself would look like any other OSGi bundle manifest and its name would be gibberish.provider.manifest.mf . It would contain the name of the Gibberish activator and also enumerate the packages used by our bundle. Right now it would look like this:

 
Bundle-Activator: net.java.sip.communicator.impl.protocol.gibberish.GibberishActivator
Bundle-Name: Gibberish Protocol Provider
Bundle-Description: A bundle providing support for the Gibberish protocol.
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
Import-Package: org.osgi.framework,
 net.java.sip.communicator.service.configuration,
 net.java.sip.communicator.service.configuration.event,
 net.java.sip.communicator.util,
 net.java.sip.communicator.service.protocol,
 net.java.sip.communicator.service.protocol.event

Note the spaces in the beginning of each line in the Import-Package section. It is very important not to forget them or your manifest file would not be parsed by the jre.

Here are some other examples of existing manifest files:

Build target.

We’ve setup our source code directory, now we need to make sure that the Gibberish provider bundle would be properly created every time we build the project. The last part of our build.xml file contains all the targets that build the Jitsi bundles. That’s where we need to create the one that would build our new bundle. Off we go:

<!-- BUNDLE-GIBBERISH -->
<target name="bundle-gibberish">
    <!-- Creates a bundle containing the Gibberish impl of the protocol provider.-->
    <jar compress="false" destfile="${bundles.dest}/protocol-gibberish.jar"
         manifest=
"src/net/java/sip/communicator/impl/protocol/gibberish/gibberish.provider.manifest.mf">

        <zipfileset dir="${dest}/net/java/sip/communicator/impl/protocol/gibberish"
            prefix="net/java/sip/communicator/impl/protocol/gibberish"/>

        <!-- zipfileset src="${lib.noinst}/gibberish_stack.jar" prefix=""/-->
    </jar>
</target>

Note that in a real protocol implementation we’d also have to include in the jar the protocol stack so that it is available when Jitsi is being run.That’s why I’ve left the comment containing what would have been an instruction to add all classes from a gibberish_stack.jar to our bundle jar.

We have one more thing to do here. We have to add our new target to the dependency list of the bundles target so that it gets called when the project is being (re)built:

<!--ALL BUNDLES-->
<target name="bundles"
    depends="bundle-util,bundle-configuration,bundle-configuration-slick,
    bundle-history,bundle-history-slick,
    ...[snip]...
    bundle-plugin-systray,bundle-gibberish"
/>

Felix run properties

Last we need to add our bundle to the list of autostarted bundles in the felix.client.run.properties file. We can put it with the rest of the protocol implementations like for example:

 
felix.auto.start.50= \
 reference:file:sc-bundles/fileaccess.jar \
 ...[snip]...
 reference:file:sc-bundles/protocol-jabber.jar \
 reference:file:sc-bundles/protocol-gibberish.jar \
 ...[snip]...

OK, that’s it. You are now set and ready to build and run the project. After you execture ant rebuild run you should see somewhere in the logging output the messages that indicate that our module has been loaded. In my case they look like this:

 22:29:15.053 INFO: impl.protocol.gibberish.GibberishActivator.start() Gibberish protocol \ 
 implementation [STARTED].

and if you were lucky you might have caught a glimpse of the Loading: label in the Jitsi splash screen, momentarily changing its status to Gibberish Protocol Provider.

If you close Jitsi, the log should also contain a line like:

 22:31:36.320 INFO: impl.protocol.gibberish.GibberishActivator.stop() Gibberish protocol \ 
 implementation [STOPPED].

Now let’s get to the real coding …

previous | TOC | next