Posts tagged ‘Jbpm’

JBPM Maven Plugin 1.0 released

I finally had some time this week to play with maven plugin development that ended with a full release of version 1.0.0 of a Maven plugin for JBPM. Even though JBPM 3.2 Eclipse plugin come with a totally rewritten deployment feature (compared to the old buggy one bundled with version 3.0), it stills an independent task, out of an automated deployment cycle, but the major problem is that  Process deployment is handled by a “servlet” (yes it is) provided with the jbpm-console web-app, which is in my opinion, a little bit constraining as it means for example requiring an application server running somewhere and integrated in the company move-to-production cycle to handle Business process deployment. This plugin, which will be a part of a major project aiming at Maven-JBPM integration (for which I hope I’ll have some free time to develop and promote), aims at including Business process deployment into any of a “proudly” strict clean Maven Build life cycle.

The Maven-JBPM integration experimental project site is available. It also includes an improved version of the JBPM Archetype I’ve already released. Using the plugin in conjunction with the archetype make it really easy to work with JBPM projects. Both are available in my newly experimental public repository : http://maven.khaled-labidi.net/repo

Before making the source code available, I should take few time to fix all those missing javadocs, and make the project’s checkstyle report less ashaming

But beyond the plugin itself, I was particulary marked by two points:

1- The way JBPM deals with resource loading. I started facing this when I set up a dedicated Jboss configuration to deploy and run JBPM applications (like the jbpm-console). I wanted to put the jbpm-jpdl and jbpm-identity jars into $JBOSS_HOME/bpm/lib (bpm is the name of the created configuration) and then freeing any application from carrying these jars in WEB-INF/lib, and making a kind of JBPM run platform with a cut-down version (3.2.3 for instance). The only varying thing should be the configuration files (jbpm.cfg.xml , hibernate.cfg.xml, etc) depending on each particular application needs. That was a nightmare. I solved it using two ways, both of them totally unacceptable for me :

  • The first one was by “pushing” the “break-standard” button of Jboss AS, by changing the flag attribute UseJBossWebLoader to “true” in $JBOSS_HOME\bpm\deploy\jboss-web.deployer\META-INF\jboss-service.xml. I don’t like this solution because it’s driving into an adoption of the Unified Class Loading philosophy and its consequences like loosing isolation, depending on “who’s deployed first”, etc. Norman Richards had already pointed this out.
  • The second way was by hacking the JBPM library itself, and rebuilding my own with a different way of loading resources. In fact, JBPM is using the so called “current” class loader to load resources, that is, the class loader that loaded the JBPM classes. This makes the “current” depending on where the JBPM libraries are, and for my case, it was the “common” class loader (aka “noAnnotationURLClassLoader” in Jboss world)  which is going to be the parent of all application-dedicated classloaders. All in all, JBPM resources (the jbpm.cfg.xml file) will not be visible by the JBPM library because the latter is loaded by a class loader which is the parent of the classloader loading the resource (Parent-blindness principle in Java classloading). For fun, packing the xml file into a Jar and throwing it into $JBOSS_HOME\bpm\lib solves the JBPM ClassLoader problem, but not mine. So, it was all about changing the class org.jbpm.util.ClassLoaderUtil and turns its method getClassLoader() from returning ClassLoaderUtil.class.getClassLoader() to returning Thread.currentThread().getContextClassLoader(). I was not the only one hacking around, some other guys pointed out the problem and they even made a change proposal to JBPM team. The change seems to be planned for 3.3 release, I understand that they worry about things that could be broken, but I don’t understand why making the ClassLoader to be used configurable? I think that when making a sort of library or a framework used by other applications, it should be a good design practice to use the Thread context class loader. This concept introduced by SUN in J2SE 1.2 aimed at having a top-down tunnel through the stratified class loaders hierarchies and resources repositories for higher-level libraries like JNDI allowing them to load other components and resources needed by applications at runtime. One elegant and meaningful way to do and explains this, is the Log4j API via this peace of code:

private static ClassLoader getTCL() throws IllegalAccessException,InvocationTargetException {
// Are we running on a JDK 1.2 or later system?
Method method = null;
try {
method = Thread.class.getMethod("getContextClassLoader", null);
} catch (NoSuchMethodException e) {
// We are running on JDK 1.1
return null;
}
return (ClassLoader) method.invoke(Thread.currentThread(), null);
}

The runtime behaviour of log4j is controlled by the log4j.xml resources which is application-dependent. I’m actually experimenting a changed version of JBPM 3.2 using the same mechanism of classloading.

2- The second point that marked me is the problem of making a maven project’s resources (configuration files, dependencies, etc) available to a particular plugin running inside that project. Once again, JBPM class loading was a problem. Of course, using my modified version of JBPM solved the issue, but I wanted the plugin to run with the standard JBPM library (otherwise I’ll be the only one using it). Googling took me almost to the same idea : trying to control the class loader of the Mojo, creating a new Thread with a newly created and set instance of URLClassloader, etc. All of this stuff is courageous, but for me it’s not elegant and it’s even horrifying as I wanted to write simple and clean Mojos. It was the first time I write Mojos, and I didn’t want to be definitely disgusted. Hopefully, I discovered the power of Plexus component configuration and after hours and hours reading through core Maven source code, I found the way I wanted to solve the problem by writing my own Plexus component configurator coupled to the magic of the @configurator and @requiresDependencyResolution mojo annotation. May be I’ll make a dedicated post about tips and tricks of developing mojos without playing with threads or ClassLoaders.

Jbpm archetype for Maven

Update:

The archetype is updated and available from this dedicated site.

Working with Jboss JBPM in conjunction with maven could be made simpler and easier when using this little useful maven archetype to generate starting-block jbpm projects. I built this artifact on top of the skeleton project generate under Eclipse by the Jboss JBPM Eclipse plugin, but with much more enhancement.

Features

  • Junit tests are upgraded to junit 4, and use the hamcrest assertions
  • All required configuration files are included and default DataBase is MySQL 5
  • There are 2 junit tests : one for testing the process from a local process definition XML, and one for making the same test but loading the process from a Database (this means the process should be deployed in prior)
  • Maven dependencies are included, even a C3PO pool connection manager
  • No more “default” package. The desired package name for java classes could be chosen when generating the project and the filtering mechanism will applied to java classes packages declarations as well as “class” attribute for Action elements in the process definition.
  • It works smoothely with JBPM 3.2.3 (latest stable release) and integrates seamlessly with M2Eclipse maven plugin under Eclipse Ganymede.
  • Generated projects are targeting jdk 1.5

prerequisites

  • Maven 2.0.9
  • Jboss JBPM 3.2.3 Eclipse plugin
  • M2Eclipse maven plugin for Eclipse (Optional)

Download

The archetype can be downloaded from here.

Installation

The installation is a straight-forward one line maven command

D:\workspace\archetype-jbpm>mvn clean package install archetype:update-local-catalog
[INFO] Scanning for projects…
[INFO] Searching repository for plugin with prefix: ‘archetype’.
[INFO] ————————————————————————
[INFO] Building Archetype-JBPM
[INFO] task-segment: [clean, package, install, archetype:update-local-catalog]
[INFO] ————————————————————————
etc

Usage

The archetype can be used either naturally from the command line, and it goes like this:

mvn archetype:create -DarchetypeGroupId=net.labidi -DarchetypeArtifactId=archetype-jbpm -DarchetypeVersion=1.0.0 -DgroupId=mycompany -DartifactId=myjbpmproject

or it can be used from M2Eclipse plugin, which is the way I prfer to use (How many people are out there coding JBPM process from outsides IDEs ?)

Creating from local archetype catalog with M2Eclipse

Creating from local archetype catalog with M2Eclipse

choosing project coordinates. Package name is auto-filled

choosing project coordinates. Package name is auto-filled

Generated JBPM Maven project under eclipse

Generated JBPM Maven project under eclipse

Maven Dependencies under M2Eclipse

Maven Dependencies under M2Eclipse

Exept Junit, all other dependencies are provided-scoped. This because JBPM project are basically aimed to be deployed under an application server whose container provides almost of theses packages (except jbpm-jpdl, jbpm-identity and c3po, they need to be deloyed once for all into the aplication server)