Sunday, January 10, 2010

Connecting to GigaSpace VM's with UI

I am preparing for a GigaSpaces training later this month. Since I work sometimes on my MacPro and other times on a MacBook, I wanted to create a VM in which I can play with GigaSpaces. But since I'm using a very basic Debian VM, which has no X11, I have to run the UI on OSX.

On first try I could not get this working. The UI would not display the GSM's and GSC's started on the VM. Here's how I got it working with a little help from J.R. from Tricode:

The reason why the UI cannot see the GSM's and GSC's has to do with a multicasting problem. The XAP 7 documentation contains an item about configuring multicast. For me it was pretty simple.

  • On the VM: I changed the hostname in /etc/hostname to 'giga1' and added the ip and hostname to /etc/hosts: '192.168.1.110  giga1'.

  • On the UI host: I added the VM hostname and ipaddress to /etc/hosts: '192.168.1.110  giga1'


I ran the multicast test which was successfull are these changes. To run the multicast test run these commands. One on the VM and one on UI hosts:
gs>admin multicastTest -sender
gs>admin multicastTest -receiver -verbose

Here are some links for those who have more complex setups:
http://www.gigaspaces.com/wiki/display/XAP7/How+to+Configure+Multicast
http://www.gigaspaces.com/wiki/display/XAP7/How+to+Determine+Whether+Multicast+is+Availablehttp://www.gigaspaces.com/wiki/display/XAP7/How+to+Configure+an+Environment+With+Multiple+Network-Cards+%28Multi-NIC%29
http://www.gigaspaces.com/wiki/display/XAP7/How+to+Configure+Unicast+Discover

JBPM 4.3 with Spring

Just before 2010 the JBPM team released the 4.3 version. Some new features are the new jms activity and BPMN 2.0 support. But besides the new features the integration of JBPM with Spring is very much changed. Not for the best, if you ask me, but they did make it easier to get started with Spring. Reason for me to rethink what I wrote about in Integration JBPM with Spring.

In 4.3 if you generate a new configuration for Spring, you also get an application context ready to use.
ant -Dtx=spring create.cfg

This looks good. There is a problem however with getting the JBPM services, like RepositoryService, ExecutionService, available in Spring. (See issue JBPM-2710) The problem is caused by the Spring integration rework they did in JBPM 4.3. The old SpringConfiguration is replaced with a SpringHelper to create a SpringProcessEngine. When requesting a service this SpringProcessEngine only looks for available components in the Spring context which creates the cyclic dependency. Spring wants to construct a service, delegates the creation to the SpringProcessEngine which returns the bean under construction from Spring. Spring detects this and throws an exception.

Issue JBPM-2710 workaround


The solution to this problem is to have SpringProcessEngine first to look in the JBPM contexts and then in the Spring context. Because the SpringProcessEngine class is hardcoded in the ConfigurationImpl it is not possible to subclass it and do the right stuff. The first workaround I tried was to create a new Environment, using the SpringProcessEngine as an EnvironmentFactory, and get the services from this Environment. This does return valid services because the environment does search in the correct order. The problem however is that the Environment gets closed and therefore also closes the Hibernate Session causing 'session is closed' errors when you want to do multiple actions in a single unit.

It is possible to workaround this issue by using a Command to retrieve the services. I created a GetEnvironmentObject Command to achieve this. By passing the wanted class type to this command you can retrieve any object from the JBPM context so also the services.
RepositoryService rs = processEngine.execute(new GetEnvironmentObject(RepositoryService.class));

Making it even easier


In the application context generated by the JBPM Ant build, the JBPM components are configured like this:

<bean id="springHelper" />


<bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" />


Because of issue JBPM-2710 it is not possible to get the other JBPM services available in Spring. By using the auto configuration options of Spring 3, we can not only replace this with just 1 <context:component-scan ../> line but also workaround the JBPM-2710 issue and make all services available in Spring. Take a look at the JbpmAutoSpringConfiguration source. With this configuration class other Spring components can autowire to all JBPM services.

ProcessLookup Bean


When we're going to use JBPM at the customer I'm currently working, we probably want to be able to deploy new versions of processes at runtime. This means that components starting process instances must somehow be able to always start the latest version. With this in mind I created the JbpmProcessLookup bean. In the future I will probably add some methods some you can easily start the current or other versions of a process.

Sources and docs


I updated the sources and docs from the Integrating JBPM4 with Spring example for this blog.
Update 28-12-2011: I pushed all sources, binaries and docs about the jbpm-spring integration to this new git repository. This also contains the version 4.3.1 maven artifacts for this post. Note there was an update on this post and that this is not the latest version.

Any comments and feedback is welcome to jbpmspring AT diversit DOT eu.

Sunday, January 3, 2010

Integrating JBPM4 with Spring

At the Devoxx last november I attended the JBPM In Action univerity class. I was very impressed with JBPM and looking at all the tools available it also looked like a product which could really be used in production environments. Because I might have a project in which I could use JBPM, I decided to have a closer look at it. Straight after the Devoxx I downloaded JBPM and started working with the examples. The documentation is really good and it was easy to get started.

Since the customer I work for uses Spring in all it's projects, I searched for how to use JBPM in Spring. Although I found some references like this Server Side article, it appeared Tom had only explains this in his Spring Enterprise Recipes book, but not on any public site. So I had a go with it.

Integration:


I started with 3 goals in mind:

  1. To be able to use JBPM for other Spring component so JBPM resources are available and a process can be started by other components.

  2. For JBPM to be able to use Spring component in it's process.

  3. To be able to run Maven tests using JBPM in an in-memory HSQL db.

Looking at the JBPM Javadoc API I guessed the best place to integrate JBPM with Spring was via the Environment. I already drew some classes but when I wanted to implement and use them I noticed there are already some Spring classes available.
By using org.jbpm.pvm.internal.cfg.SpringConfiguration class to configure your JBPM ProcessEngine a Spring context is added to the environment. Disadvantage of this class is that is loads it's own Spring context via a 'jbpm.test.cfg.applicationContext' property if you use this class from your own code to initialize JBPM. However, this class does implement Spring's ApplicationContextAware interface, so by defining a 'configuration' bean in Spring with this class, the ApplicationContext automatically gets injected.

<bean id="configuration" class="org.jbpm.pvm.internal.cfg.SpringConfiguration" />


So this makes the Spring context available with a JBPM environment (and solves my 2nd goal). To make JBPM components available in Spring and to be able to start a Process for other Spring components, I created a JbpmProcessBean. This bean takes a resource name for an jdpl.xml file and automatically deploys the process when the Spring context is started.
<bean id="testProcess" class="eu.diversit.jbpm.spring.JbpmProcessBean">
<property name="resourceName" value="org/jbpm/examples/java/process.jpdl.xml" />
</bean>

To be able to deploy a process, the bean must have a ProcessEngine instance. A ProcessEngineFactoryBean provides a single ProcessEngine for the whole application. Because the factorybean uses the configuration bean the Spring environment is automatically also available within JBPM. The ProcessEngine is autowired to the JbpmProcessBean.
<bean id="processEngineFactoryBean" class="eu.diversit.jbpm.spring.ProcessEngineFactoryBean" />
<bean id="processEngine" factory-bean="processEngineFactoryBean" factory-method="createProcessEngine" />

So with these 3 small components, JbpmProcessBean, ProcessEngineFactoryBean and SpringConfiguration, we now have integrated JBPM with Spring so Spring components can use JBPM resources (via JbpmProcessBean) and JBPM can use Spring components (via SpringConfiguration).
The complete Spring configuration looks like this:
<context:annotation-config />
<bean id="configuration" />
<bean id="processEngineFactoryBean"    class="eu.diversit.jbpm.spring.ProcessEngineFactoryBean" />
<bean id="processEngine" factory-bean="processEngineFactoryBean" factory-method="createProcessEngine" />

Easy configuration:


Although this configuration is not that difficult, I wanted to make it even easier by using the new annotations available in Spring 3. An AnnotatedSpringConfiguration class was made which does just extend the SpringConfiguration class, no new functionality!, but adds some annotations so Spring is able to detect this component and automatically initialize it upon context startup. By default this component is registered with qualifier 'jbpmConfiguration'.
Annotations were also added to ProcessEngineFactoryBean so Spring knows it's a Spring component and that the createProcessEngine method constructs ProcessEngine beans.
Although JbpmProcessBean is a Spring component, this class must always be configured in the Spring context because you probably want a bean instance for every process you have. In the context you have to define the jpdl.xml resource for each process bean. (Alternatively you could subclass this class for each process and automatically deploy that subclass to Spring)  The initialize() and destroy() methods are annotated with resp. @PostConstruct and @PreDestroy so the process automatically gets deployed in the ProcessEngine and also gets undeployed when the context gets destroyed.
The JBPM-Spring integration components can now be used just by adding this component-scan (and library dependency of course) to your context:
<context:component-scan base-package="eu.diversit.jbpm.spring" />

Testing it:


To test this integration I reused the 'org.jbpm.examples.java' example which comes with JBPM4. A simple testcase reuses code from the original JavaInstanceTest but in stead of creating a Process instance in code this is done via a Spring context. The process variables are also defined in the Spring context to test the use of Spring components by the JBPM Process.

Look here for the code of the JbpmSpringBeanTest (the testclass tests both starting the process via a key of via an id). This is the Spring test context:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... (removed for readability) ...>

<bean id="testProcess" class="eu.diversit.jbpm.spring.JbpmProcessBean">
<property name="resourceName" value="org/jbpm/examples/java/process.jpdl.xml" />
</bean>

<bean id="hand" class="org.jbpm.examples.java.Hand" scope="prototype" />
<bean id="joesmoe" class="org.jbpm.examples.java.JoeSmoe" />

<!-- Embedded HSQLDB for testing -->

<jdbc:embedded-database id="jbpmDataSource" type="HSQL">
<jdbc:script location="classpath:db/jbpm.hsqldb.create.sql" />
</jdbc:embedded-database>

</beans>

The main Spring context, which you would use in your own project, looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... (removed for readability) ...>

<!-- Auto-detect configuration -->
<context:component-scan base-package="eu.diversit.jbpm.spring" />
</beans>

Both tests run successfully so both using a Jbpm process as a bean as Jbpm using Spring components works.

NB! Notice the 'scope="prototype"' attribute on the hand bean. Default Spring creates beans a singletons so JBPM will use the same bean instance for all processes or process-instances (!) in which the bean is used! This is ok as long as you don't keep any state within the bean itself. The Hand class however has an 'isShaken' property which is set when the hand is shook. If this bean is used as a singleton, this property is already set to 'true' before the 2nd (and all subsequent) process shakes the hand. The added 'timesShaken' (int) property shows this. If you run the test without the 'scope="prototype"' attribute on Hand, in the 2nd test the timeShaken will be 2.
By adding the 'scope="prototype"' attribute Spring will create a new bean instance every time one is requested.

Using HSQLDB with Maven tests:


JBPM needs a database to work. When running tests with Maven you don't always want to rely on an already available database. For development testing it would be handy if it would be possible to start and stop a database together with the test.

Spring 3 now provides Embedded database support to make this possible. Just adding jdbc:embedded-database to your (test)context will give you a datasource to that database.
<jdbc:embedded-database id="jbpmDataSource" type="HSQL">
<jdbc:script location="classpath:db/jbpm.hsqldb.create.sql" />
</jdbc:embedded-database>

The jdbc:script is run when starting the database so this is used to load the JBPM schema in the db. The default database type is HSQL, but I just added it so it's clear what kind of db is created.
Just adding this is not enough unfortunately. I had hoped it would just start a db and JBPM would be able to connect to it using the already configured url, but because the database is lazy so when it's not used by another component it is not started.

So to get this working we have to configure JBPM to use this Spring defined database. A Hibernate LocalSessionFactoryBean is added to the context and a dummy datasource is defined in the main Spring context:
<bean id="jbpmSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="jbpmDataSource" />
<property name="mappingResources">
<list>
<value>jbpm.repository.hbm.xml</value>
<value>jbpm.execution.hbm.xml</value>
<value>jbpm.history.hbm.xml</value>
<value>jbpm.task.hbm.xml</value>
<value>jbpm.identity.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
</props>
</property>
</bean>

<jee:jndi-lookup id="jbpmDataSource" jndi-name="java:comp/env/jdbc/myds" />

To let JBPM use this datasource we must remove the hibernate configuration from the JBPM config. The jbpm.cfg.xml points to a jbpm.default.cfg.xml (located in jbpm-pvm.jar) which contains the hibernate configuration and uses the jbpm.hibernate.cfg.xml. jbpm.default.cfg.xml is copied to jbpm.spring.cfg.xml and the hibernate configuration is removed from this configuration. In jbpm.cfg.xml jbpm.default.cfg.xml is replaced by jbpm.spring.cfg.xml.

Now I thought it would be necessary to (auto) inject the datasource into the SpringConfiguration (it has a setHibernateSessionFactory(..) method), but that was not necessary at all. Because we have JBPM already configured to use Spring components, JBPM will also look in Spring to get a HibernateSession instance and will get one from the LocalSessionFactoryBean. The test context replaces the (dummy) jndi datasource with the jdbc:embedded-datasource so JBPM now uses the embedded HSQLDB.

NB! JBPM has a jbpm.tx.spring.cfg.xml configuration which should configure JBPM to use Spring transactions but this didn't work in my tests. The jbpm.tx.hibernate.cfg.xml seems to work fine in this example.

Using JBPM-Spring integration

Update 28-12-2011:
I moved all maven sources and artifacts to this new git repository. The version 0.1.1 source and jar maven artifacts are available in the releases folder. Note however that other posts about this subject have been written and the latest version of the sources is 4.3.2.

All binaries and code shown in this article is freely available (Apache 2 license) via my maven repository : http://maven.diversit.eu/repository/.
The project is named 'eu.diversit.jbpm.jbpm-spring-integration' and the released version is 0.1.1.
Documentation is available via : http://maven.diversit.eu/docs/jbpm-spring-integration/

To use this in a project add a Maven dependency:
<dependency>
<groupId>eu.diversit.jbpm</groupId>
<artifactId>jbpm-spring-integration</artifactId>
<version>0.1.1</version>
</dependency>

And add the repository so the project can be found:
<repository>
<id>diversit</id>
<name>DiversIT Maven Repo</name>
<url>http://maven.diversit.eu/repository</url>
</repository>

The project will probably give you all needed dependencies for JBPM and Spring. I have to look into this if this is handy or that I should make the dependencies optional.
Either copy the context of the jsiApplicationContext.xml to your Spring context or import the jsiApplicationContext into your context. Don't forget to define you own jbpmDataSource for a production environment database! For testing you can use the jsiEmbeddedHSQLDB.xml context which defines an embedded HSQLDB as shown above.

Feedback:


In reasonably short time I was able to do this JBPM - Spring integration and realize all the goals I had. Since I could not find many examples of JBPM and Spring integration I'm curious to know if this information is usefull to anyone. So if you have any remarks (or compliments) about this article or the JBPM Spring Integration project or sources please send me some feedback to "jbpmspring AT diversit.eu" or leave a comment.