Saturday, May 10, 2014

First steps with Apache ACE

Introduction


"Apache ACE is a software distribution framework that allows you to centrally manage and distribute software components, configuration data and other artifacts to target systems." (from https://ace.apache.org/)
Well, that sounds good enough to try it out, at least for me.
I like the idea to centrally configure deployments with different version and have a way to automatically distribute those.

Starting ACE


Setting up Apache ACE was pretty easy. The Getting started guide contains all the necessary steps.
My MacBook was the ACE server and my Raspberry Pi a target.

Using the Web GUI is easy and straightforward (nice one guys ;-) ).
But that's for little children. I wanna find a way to automate everything with scripts.

The Client Shell API

Basically there are two ways to talk to the server remotely. One is the Client Shell API and the other way is via REST API. For now I'll stick with the Shell API

1st step: connecting to the server as shell client

Before we can write a script we have to connect to the server.
With some help from the iQSpot people (see here) I figured it out.
They suggest starting the client like this:

java -Dagent.discovery.serverurls="http://server:port"
     -Dorg.apache.ace.server="server:port"
     -Dorg.apache.ace.obr="server:port"
     -Dorg.osgi.service.http.port=-1
     -jar client.jar
 
Unfortunately, that didn't work for me (even after adding some missing backslashes).
The default is that you should be in the directory of client.jar. "-jar client.jar" wasn't the problem.
The startup searches for the client/conf directory, so when you see this exception:

java.lang.IllegalArgumentException: Bad arguments; either not an existing directory or an invalid interval.
    at org.apache.ace.configurator.Configurator.<init>(Configurator.java:89)
    at org.apache.ace.configurator.Activator.init(Activator.java:33)
    at org.apache.felix.dm.DependencyActivatorBase.start(DependencyActivatorBase.java:76)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2146)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
    at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1291)
    at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:304)
    at java.lang.Thread.run(Thread.java:722)

You're probably starting the client from a different directory.
To get rid of that exception we have to set a property:
-Dorg.apache.ace.configurator.CONFIG_DIR=
All in all the command to start the client looks like this:

java -Dagent.discovery.serverurls="http://server:port"\
     -Dorg.apache.ace.server="server:port"\
     -Dorg.apache.ace.obr="server:port"\
     -Dorg.osgi.service.http.port=-1\
     -Dorg.apache.ace.configurator.CONFIG_DIR="apache-ace-2.0.1-bin/client/conf"\
     -jar apache-ace-2.0.1-bin/client/client.jar


Now we can start the client.
But to pass a script to the shell we need two more arguments. Thanks again to the iQSpot people. They already pointed out those arguments:
  • -Dgosh.args="–-args"
  • -Dace.gogo.script.delay=delay
  • -Dace.gogo.script=/path/to/script.gogo
What do those three do?
Everything you'll pass as "gosh.args" will be executed immidiately. If pass "--help" for example and start the client you'll see the help output.
The delay is helpful when you want to give your client some time to synchronize with the server.
"ace.gogo.script" should be obvious ;-)
We end up with the following command:

java -Dagent.discovery.serverurls="http://server:port"\
     -Dorg.apache.ace.server="server:port"\
     -Dorg.apache.ace.obr="server:port"\

     -Dorg.osgi.service.http.port=-1\
     -Dorg.apache.ace.configurator.CONFIG_DIR="apache-ace-2.0.1-bin/client/conf"\
     -Dace.gogo.script.delay="3000"\
     -Dace.gogo.script="script.foo"\

     -jar apache-ace-2.0.1-bin/client/client.jar

Now we have to find out, what we should put into "script.foo".
 

Shell commands


Every (basic) command is described here.
The steps are quite simple: cw, ca, cf, ca2f, cd, cf2d
If you don't like or get the abbreviations (it took me a while) there is also a nice picture in the REST API documentation:
What the picture is missing is cw or "create workspace". When using the Shell API you need a workspace, which you can commit later.

The script

 

So, what should skript.foo do? Let's assume we have to upload some generated artifacts from our CI server 
The steps are
  1. create workspace
  2. add the new Jars as artifacts from certain directory
  3. create a new feature
  4. add artifacts to feature
  5. create a new distribution
  6. add new feature and existing ones to distribution
  7. add feature to existing target 
I have to admit that it took me quite a while to figure everything out because I'm not very experienced with Apache Felix GoGo.
Creating the workspace is easy: w = (cw)
Now we can call the workspace with $w. Adding the Jars was more difficult. Let's assume the directory is ./toAdd. Then the command looks like this: 

each ([(ls toAdd)]) {$w ca (($it toURL) toString) false}

You "toAdd" can be changed to any path and you could use some wildcards, like ls toAdd/*.jar
I guess if you're used to GoGo the command won't be a surprise. If you're not used to it, I would like to explain the different parts to you:
each takes a list and a function. ls toAdd returns a File array. That's why we need the brackets. They convert the array into a list. After that comes the function, indicated by the braces.
$w ca is the method to create an arfifact. $it is the iterator over the list that is provided by each.
Then we call the methods toURL and toString because reflection makes it possible ;-)

Third step: add all artifacts to feature

each ($w la "(Bundle-SymbolicName=org.camunda.*)") {symbolicName=($it getAttribute "Bundle-SymbolicName"); $w ca2f "(Bundle-SymbolicName="$symbolicName")" "(name=test-feature)"}

Again, we use a for-each-loop.
$w la lists all the bundles that match the passed pattern. (Here, I want to add all camunda bundles, no advertisement ;-))
Then I save the symbolic name in a variable, so it's easier for me later to reference it.
org.apache.ace.client.repository.RepositoryObject has a getAttribute method, which we use here.
Also, please note the semicolon.
We use the symbolic name as part of the first argument for ca2f (create artifact2feature).
The String contains three parts
  • "(Bundle-SymbolicName="
  •  $symbolicName
  • ")"
I don't know why, but we don't ne a "+" for string concatenation. The second argument is the name of the feature. I just assume it to stay the same: "test-feature"
Creating a distribution and a feature2distribution are nothing special.

All in all we end up with the following:

w = (ace:cw)
$w cf test-feature
$w cd test-distro

each ([(ls toAdd)]) {$w ca (($it toURL) toString) false}

each ($w la "(Bundle-SymbolicName=org.camunda.*)") {symbolicName=($it getAttribute "Bundle-SymbolicName"); $w ca2f "(Bundle-SymbolicName="$symbolicName")" "(name=test-feature)"}

$w cf2d "(name=test-feature)" "(name=test-distro)"

$w commit


That should do the trick so far.
Stay tuned for my next steps with ACE ;-)

Tuesday, May 6, 2014

Glassfish 4, Commons Mail and "UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed"

I know there are a bazillion posts/threads/etc. about the exception mentioned in the title and now there are a bazillion + one ;-)
Unfortunately I couldn't find the solution I want to present to you anywhere else.

First some context:
My class extends an Activiti class and uses Apache Commons Mail to send an email.
The email contains some text and has a file (txt/pdf/docs) attached.
Everything runs inside a Glassfish 4 and the Jars are deployed as OSGi bundles.

When calling email.send() the server threw the feared UnsupportedDataTypeException:

Caused by: javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
    boundary="----=_Part_0_397989068.1398665205325"
    at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:891)
    at javax.activation.DataHandler.writeTo(DataHandler.java:317)
    at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1574)
    at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1840)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1119)
    ... 120 more


Like I mentioned the Internet is full of solutions but none of them worked for me.
Because the Glassfish showed me that all of my bundles were correctly linked and resolved the problem had to be another place.

My colleague then told me I should try to change the TCCL. After some try-and-error it worked (I tried the one from commons.mail, the one from javax.activation and one I forgot ;-)).

The solution was to import javax.mail in my bundle and change the TCCL to the javax.mail classloader:

Thread.currentThread().setContextClassLoader(javax.mail.Message.class.getClassLoader());
email.send()

I am not sure why only the javax.mail classloader works. For me it is some arcane dependency/classloading/visibility problem.
Nevertheless, I hope this post helps some Glassfish/OSGi users.

Finally, I would like to thank my colleague @spost1970 for helping me find a solution.

Saturday, April 26, 2014

Integrating Apache Aries blueprint into Glassfish 4

After experimenting with Glassfish 4 lately I would like to let you know what I am up to. It's nothing big (yet) ;-)

A little bit of background

Glassfish comes with integrated OSGi support (Apache Felix) but without Blueprint (as far as I know). So putting a Blueprint container into Glassfish became my task.

The nice thing about Glassfish is that it combines Java EE (especially EJBs) and OSGi and that, in contrast to JBoss, it has a nice OSGi web console.
If you want to get to know more about the OSGi-JEE combination the keyword for your favourite search engine is "fighterfish".

Most of the credit goes to Yong Tang and his blog entry. He describes the integration of Aries Application but also describes the basic parts necessary for my task.

The problem


So, before we start, what is the problem? If you're familiar with Glassfish you certainly know there is an autodeploy/bundles directory. Why don't I just drop the necessary bundles into the autodeploy/bundles directory?
When using the autodeploy directory Glassfish doesn't start the bundles so you'll have to do it by hand every time you empty the osgi-cache directory and, of course, initially.
But there's a more convenient way.

Let's get it on


What's the better way?
Just drop the jars
  • Aries Blueprint Api(v1.0.0)
  • Aries Blueprint(v1.1.0)
  • Aries Proxy (v1.0.0) 
  • Aries Util(v1.0.0)
into glassfish/modules/autostart.
To make sure all dependencies are there add slf4j api (v1.7.2), logback core(v1.0.13) and logback classic (v1.0.13) (or whichever logging framework you prefer). You don't need any additional configuration because we didn't create a subdirectory.

See, piece of cake. The trick is to find the right directory. Now the Blueprint extender will do its job right after start up.
glassfish/modules/autostart
glassfish/modules/autostart
glassfish/modules/autostart
glassfish/modules/autostar
glassfish/modules/autostar

Wednesday, January 22, 2014

Activiti/camunda BPM: custom behavior and BPMN extension elements using Blueprint

Introduction 

 

In the last few weeks I have been working on a problem regarding OSGi-Blueprint and Activiti. Because it wasn't as easy as I would have hoped I want to share my solution with you. I will start by explaining my environment, show you the problem and then I will explain my first attempt. After that I will present my solution. Finally I will show some ideas how to make it better and things that I did not test.

Just a short hint about the writing: when I reference a class or some XML it's written in italic, e.g. Object. When you see "process engine", I am talking about the whole thing, but when you see ProcessEngine it's the actual class.

My environment

 

I use the Activiti-framework in version 5.12.1, Apache Aries in version 1.0.0 with a little modification and my own ProSt bundles. ProSt can be found here. The README.md explains why and what I changed in Aries.

I haven't tried, yet, but I am pretty sure that camunda BPM suffers the same problem because
both share the same MailActivityBehavior and BlueprintELResolver classes and use <extension-elements> for injection. So if you prefer camunda and see "activiti" somewhere you just have to replace it with "camunda" in your head ;-)

The problem 

 

In general, I just wanted to send an e-mail during my process-execution. Sounds pretty easy, right?

My SendMailWithAttachmentBehaviour class extends the previously mentioned MailActivitiBehavior class. The process definition contains all the necessary information to send the e-mail, e.g. from, to and subject. Only the attachment is missing, which I get from the execution environment.

Because I use Blueprint I cannot use the activit:class or type="mail" attributes in the process definition. I have to declare the class this way:
activiti:deleExpression="${sendMailWithAttachmentBehavior}"

A little hint: the name in the braces has to match the one used as bean id in the blueprint.xml.

The other ways do not work with OSGi because of class visibility etc.

The easy part was to extend the BlueprintELResolver class (ProStBlueprintELResolver) and add a way to add custom behavior classes at the moment.

So, what happens when the process engine tries to resolve the expression?
When the bundle is loaded Blueprint creates a dynamic proxy and registers it at the ProStBlueprintELManager.
After the process reaches the ServiceTask which delegates to the ${sendMailWithAttachmentBehaviour} the process-engine asks its ExpressionLanguageResolvers if they know something with the name "sendMailWithAttachmentBehaviour". Logically the proxy is found.
After that the process engine tries to set the extension-elements at the class.
First it tries to find setter methods and if it cannot find setters it tries field injection. (see ClassDelegate.applyFieldDeclaration())
Both ways do not work.
But why?
Of course a proxy does not have any fields. But why is it not possible to just add the setters to the SendMailWithAttachmendBehaviour class?
The call is proxy.getClass().getMethods() and according to the documentation this will return all the methods of the interfaces that the proxy was created with. ActivityBehavior does not declare the setSubject() etc. methods because they are only needed for e-mails.

First attempt

 

At first I thought the solution was quite obvious. I would just export a second interface containing the setters like this:

<bean id="sendMailWithAttachment" class="de.blogspot.wrongtracks.prost.example.behaviour.SendMailWithAttachmentBehaviour" />
  
<service ref="sendMailWithAttachment">
  <interfaces>
<value>org.activiti.engine.impl.pvm.delegate.ActivityBehavior</value>
<value>de.blogspot.wrongtracks.prost.example.behavior.ExtensionElementsMailSetter</value>
  </interfaces>
</services>
But wait, if you take a look at the (old) context.xml you can see that my reference listener just listens for ActivityBehavior and not the other interface. That's why the created proxy won't contain the methods from the other interface. Too bad...

The solution

 

I found the solution accidentally while reading the Apache Aries Blueprint documentation. This chapter points out that you can also listen for service references.
I changed the methods to accept a ServiceReference instead of a ActivitiyBehavior and when the expression should be resolved I use the BundleContext to get the service. At that point it is not a proxy, it is the implementation.

Then everything works just fine. I don't even need the setter interface anymore.
You can see the solution when you look at the new context.xml and the previously mentioned ProStBlueprintELResolver. (the previously showed link pointed to an old version so nothing would be spoiled ;-) )

That's it, that is my solution to add custom behavior to the process engine and use extension elements in the BPMN XML.

How could we improve the whole thing?

 

Strangely, I have no idea how the whole thing could be improved. I would like to hear your ideas. Also, I would like to know if you think that the way presented here is good or bad or something in between.

What didn't I try?

 

You should note that I have not tried to find out how JavaDelegates behave in the same situation. I just did not have time and I wanted to show you my solution as soon as I finished it.

Wednesday, November 20, 2013

JBoss 7.2: From Aries to Gemini and back again

I have been using the combination of JBoss 7.2 and Apache Aries for a while now.
Recently, I had to face a problem, which I had been ignoring for quite a while successfully.

When you use Aries blueprint you cannot use setters with non-void return values. Aries expects setters to have "void" as their return type.
Because fluent interfaces are quite popular at the moment that was a problem for me.
The Aries people already have an open issue to fix/improve this and maybe the blueprint specification also wants setters to have that return type. I don't want to start a discussion about this here.

Nevertheless, I wanted to use the setter. I could have written a subclass with a slightly different setter, which just calls the setter I really want to use. But that would've meant to write a new setter for every existing one. So that was not an option.

Another option was to change the Aries source code by myself (what I should have done in the first place). But I didn't know how complex that would be so I chose the third option.

The option I chose was to replace Aries with Gemini. At some point during my research I found a post, which stated that Gemini could handle non void return values for setters.
After I managed to collect all of Gemini's dependencies and place them in JBoss' bundle directory I thought I reached my goal. But when I started the server it didn't go past the registration of my EJBs. The server log just showed a NPE some seconds before when trying to release some lock.

I wasn't sure what to do because the NPE wasn't really helpful and I couldn't imagine what the problem was. My only idea was to remove the Jar containing the EJBs.
After that the server started but the Blueprint-Extender didn't start automatically. That wasn't much of a deal. I opened up the management console and started the bundles all by hand. Everything seemed to be fine. Even dropping the EJB-Jar in the deployment directory worked.
Unfortunately, after stopping and starting the server again I was staring at the same exception and the JBoss refused to do its work.
What followed was some try-and-error with more error than try. I still don't know what the problem is.

This was really disappointing (it still is). I decided to take the option I refused before and to change Aries' code. Fortunately I had the Gemini-Jars in another local JBoss so I could just go back to the one I had used before.
And who could've guessed? I just had to change one line in org.apache.aries.blueprint.utils.ReflectionUtils:

if (name.length() > 3 && name.startsWith("set") && 
resultType == . && argTypes.length == 1)
 
I just had to remove the Void.TYPE and everything worked.
I guess next time I'll try to change the code first ;)

Friday, July 12, 2013

Comparison of different BPMN-modelling tools

Recently, I stumbled upon the problem that the Activiti-engine wouldn't accept a BPMN-XML-file which I modeled with camunda Modeler.
No error message or warning was displayed, but I could see in the log-file that parsing started.
The process just didn't arrive in the repository.

Because of that, I was wondering, how good the interoperability of the different engines and tools is at the moment.
BPMN is standardised and should work on every tool and engine. But as usual, reality shows us, that it's different.

This blog post covers several modelling tools and how good they work together. In a later blog post I'll feed the different BPMN-files to different engines.

I chose the tools for no special reasons.
Activiti and camunda because I work with Activiti (and camunda forked it).
SemTalk because I do have a license for it (it's the only commercial tool I chose).
The rest is more or less randomly in the list and because they are available for free.

I compared:
  • Activiti Modeler 1.0 (Activiti Version 5.13)
  • camunda Modeler 2.0.12
  • Yaoqiang Version 2.2.2
  • Bizagi 2.5.1.1
  • Bonita BPM Studio 6.0.0
  • MS Vision 2010/ SemTalk 4.2.0.4230
  • Activiti Designer  5.12.0
You can find my results in a PDF, which I placed here.

To give a short explanation of the colours used:
  • green -> everything was alright
  • yellow -> it worked with some problem
  • red -> it didn't work or there were some major problems
  • grey -> it couldn't be tested or was unnecessary.
Bizagi is completely grey, because it has no im- or export for BPMN-XML.

This is the example process I used:
I wanted the example process to be very simple. It includes the basics, which I think should be supported.
It was modeled with every tool and opened with every tool. When testing if editing works, I added a task to the second pool.

Next to the result-table in the PDF, I took some notes during the tests, which I want to share:
  • Activiti Modeler can't display pools or lanes
  • Activiti Modeler can't display message flows
  • Activiti Modeler needs a Tomcat server (or similar), because it's part of Activiti Explorer
  • Yaoqiang would work better with some guides
  • camunda Modeler needs Eclipse, because it's a plug-in
  • modelling a flow (arrow) in SemTalk is too complicated
  • Yaoqiang, because of it's page layout, becomes confusing with big diagrams
  • Bizagi, Bonita and Yaoqiang validate the model
  • To show message passing, Bonita forces you to explicitly model sender and receiver
  • for Activiti Modeler, every file hat to be a .bpmn20.xml and not just .bpmn 
  • Activiti Designer can't display message flows

I don't want to name a winner, because I depends on what you're working on.
Some modelling tools are embedded (like Activiti Modeler and Bonita) and some are standalone (like Yaoqiang) and there are different use-cases and environments in which you would prefer one or the other tool.

But I got to admit, that I am a little bit disappointed by Activiti Modeler. It can't work with any of the the BPMN-files the other tools exported.

I hope my results will be helpful for people who have to chose a modelling tool and I hope that some of the tool-developers will try to improve their tools because of my results. Have fun ;)

Update: I added the results for Activiti Designer to the PDF. It works slightly better than the Modeler but could be better.

Tuesday, June 4, 2013

Using the Activiti-Engine as bundle in JBoss AS 7.2

Introduction


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.

 

Motivation 

 

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

 

Environment


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">
       <properties>

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

    </subsystem>

    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  
    <<jboss-root>>/standalone/deplyoments

    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">
                <properties>
                    <property name="org.osgi.framework.startlevel.beginning">
                        2
                    </property>
                </properties>
                <capabilities>
                    <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"/>
                </capabilities>
            </subsystem> 


    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. 

    Summary 

     

    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