Tuesday, June 4, 2013

Using the Activiti-Engine as bundle in JBoss AS 7.2


I am quite new to OSGi and when trying to deploy and use the Activiti-Engine as OSGi bundle in JBoss (I'll usw "JBoss" as abbreviation for JBoss AS 7.2) I have had some problems. 
The only example about OSGi and Activiti I was able to find was the one from Activiti in Action which uses Apache Karaf. Of course those environments differ a lot.
So I wanna share my knowledge with you.




Before we start, I'd like explain why I want to use the combination of Activit, OSGi and JBoss. I won't argue about the pros and cons of using OSGi, there is enough literature about that.

The fact that Activiti scans every new bundle if it contains a process definition will become very helpful for future processes.
Also, updating a process definition by replacing a single bundle and not replacing e.g. a whole WAR-file, seems like an advantage.

But, why do I want to use JBoss and not e.g. Karaf?

When JBoss changed to version 7 they restructured their whole server to use OSGi/JBoss modules. So, OSGi is a part of JBoss.
Last time I checked, JBoss was the only fully JEE 6 compliant server with OSGi integration and because I need EJBs for client - server communication I need JBoss. (At this point, I have no idea how to combine EJBs and OSGi but I'll try to figure that out, soon)

Those are my reasons so let's see how we can get those three running.


Let's start



To make sure that everyone can easily repeat my steps, I'll start with the environment/versions:
  • JBoss AS 7.2
  • OSGi 4.2 (included in JBoss)
  • Activiti 5.12.1
Please notice, that I use JBoss AS 7.2, which you have to compile yourself at the moment. With version 7.1.1 I have had a problem.
I had the server running locally under Linux Mint 14.1.


Bundle dependencies 

The example from Activiti in Activiti uses a feature.xml to resolve all the dependencies and install them from a Maven repository. Unfortunately, this involves some Karaf "magic". That's why I had to download all dependencies manually. (I also tried

mvn org.apache.felix:maven-bundle-plugin:wrap/bundleall
on the activiti-engine and -osgi project, but that didn't work out for me)

We need the following JARs (I added links to make downloading them easier):

Downloading yourself Apache Aries seems a little bit odd because the JBoss documentation states that there is blueprint support. Nevertheless, I couldn't find, nor activate it, so I was forced to include it myself.

Another interesting thing is, that I couldn't start the included h2 database (com.h2database.h2). That's why I downloaded it, too. Please notice, that you will only need the h2-bundle if you want to use a h2-database (makes sense, doesn't it ;) )

We could throw all those bundles into the <<jboss-root>>/standalone/deployments directory (if you're using JBoss in standalone-mode), but I think a better approach is to place the more general JARs in the <<jboss-root>>/module directory. 
    I placed the three aries-bundles, the h2-bundle and the two slf4j-bundles there.
    For every bundle you have to repeat the following steps:
    If the bundle name is e.g. com.a.b.c.jar create in <<jboss-root>>/module the directory com/a/b/main and place the bundle in the main directory. (Don't worry about the <<jboss-root>>/module/system -directory.)

    After that, alter the standalone.xml and add a new capability under the OSGi-Subsystem, e.g.:

    <subsystem xmlns="urn:jboss:domain:osgi:1.2" activation="eager">

          <capability name="com.a.b.c" startlevel="1"/>


    Pick whichever startlevel you think is appropriate.

    In fact, you can pick any directory-structure you want to, as long as the path in the standalone.xml is correct. That means you could place the h2-bundle e.g. in <<jboss-root>>/module/org/foo/bar/main and JBoss would still be able to find it. Only the last directory has to be named "main".

    After you've done that, take the other bundles an put them into  

    An that's all. These steps should get Activiti running as OSGi-bundle.
    My whole osgi-subsystem configuration looks like this:

    <subsystem xmlns="urn:jboss:domain:osgi:1.2" activation="eager">
                    <property name="org.osgi.framework.startlevel.beginning">
                    <capability name="javax.servlet.api:v25" startlevel="1"/>
                    <capability name="javax.transaction.api" startlevel="1"/>
                    <capability name="org.osgi.core" startlevel="1"/>
                    <capability name="org.osgi.enterprise" startlevel="1"/>
                    <capability name="org.slf4j" startlevel="1"/>
                    <capability name="org.slf4j.impl" startlevel="1"/>
                    <capability name="org.apache.aries.util" startlevel="1"/>
                    <capability name="org.apache.aries.proxy" startlevel="1"/>
                    <capability name="org.apache.aries.blueprint" startlevel="1"/>
                    <capability name="org.h2" startlevel="1"/>
                    <capability name="org.apache.felix.log" startlevel="2"/>
                    <capability name="org.jboss.osgi.logging" startlevel="2"/>
                    <capability name="org.apache.felix.configadmin" startlevel="2"/>

    And in my deployments-directory you can find those jars:
    • activiti-bpmn-converter-5.12.1.jar
    • activiti-bpmn-model-5.12.1.jar
    • activiti-engine-5.12.1.jar
    • activiti-osgi-5.12.1.jar
    • com.springsource.javax.transaction-1.1.0.jar
    • com.springsource.org.apache.commons.lang-2.4.0.jar
    • joda-time_2.1.0.jar
    • org.mybatis.mybatis_3.1.1.jar


    Blueprint activation


    The Activiti-OSGi bundle contains the basic classes Blueprint needs. But we have to register all those services. That's why we need a Blueprint content.xml.

    Thanks to Tijs Rademakers we can copy that from here. It's the example code from/for Activiti in Action.
    We can also use the book-osgi-app in JBoss.
    Just run mvn package on the book-engine, book-process and book-task projects.

    After packaging those three, I had to make a minor change in the MANIFEST.MF and content.xml of the book-engine-project.
    In the content.xml you have to replace the jdbc-url with whatever fits to your database.
    In the MANIFEST.MF I had to remove the Import-Package versions for everything related to activiti, because the generated MANIFEST requires version [5.9, 6) and my activiti-bundles don't contain any version information.

    Now place those three bundles into the deployment-directory and everything should work as expected.
    To test the deployment, I wrote a simple bundle with an activator to look up the Deployment-Service and see, if a process defnition could be found. 



    Get all the bundles, place some in the modules-directory and some in the deployment-directory, copy some content.xmls and everything should work. Sounds easy, but it took
    me a while to figure it out ;)

    So have fun with Activiti, OSGi and JBoss!
    In case you find any mistake, feel free to point them out.


    Copyright @ 2013 Wrong tracks of a developer.

    Designed by Templateiy