Eric D. Schabell

Wednesday, March 24, 2010

jBPM migration strategies - Introduction

For some time now I have been looking to put together my views and experience on how to position your current jBPM v3.2.x implementations for migration to a newer version. This article will outline some of the best practices within the four layers identified in general jBPM projects.

These ideas will be put forth based on the simple diagram provided here which outlines a typical enterprise business process implementation. It is not necessary to have all the various components in an implementation to be able to make use of the guidelines detailed in this article. The extensive list of components is provided to allow for discussion on the typical interactions I have encountered in my jBPM travels. In this introduction these layers will be outlined and future articles will cover them in more detail.

The idea behind each layer will be to identify best practices and ways to keep your implementations as jBPM version agnostic as possible. I believe this can be achieved, to a point, with proper knowledge and design time application of this knowledge. Each section will dive deeper into that specific area and try to provide you with the knowledge to design and implement your jBPM projects in such a way as to future proof them. You will be as ready as you can be to migrate to the next version.

The choice to focus on jBPM v3.2.x is due to the fact that this is currently the supported enterprise version provided in the JBoss SOA-P product. This is what many enterprises are currently using, throughout the world.

Process initialization layer
The first layer covers the details of providing flexible initialization of your processes within enterprises where you might have serious performance wishes, many different processes that can be initiated and allow for prioritising which process will be started when.

Process definition layer
This layer contains the process definition itself, a narrow layer that simply needs to be migrated to some future version of jBPM. Will this layer be jPDL, XPDL or some form of BPMN?

Process implementation layer
Here we dive into the underlying code layer that is best known as Handlers. The actual Java implementation that you may extended with abstraction layers, business logic and helper utilities. There is much to be cautious of here when looking to migrate your processes to a future version of jBPM, but there are some simple practices that will make migration less work than you think!

Process interaction layer
There is much to be won with a good strategy for accessing business logic, back-end systems, back-office systems, user interfaces, other applications or whatever your business processes need to use to get their jobs done. Here you will find a series of components passing review with suggestions for each one on the best way to position your projects for easy migration. A bit of prevention will go a long way in your IT budget!

General best practices
For as far as they have not been covered, I will provide some best practices with regards to any jBPM project. These will zoom in to a lower level than the above layers and can be applied across them all. If you get nothing out of these articles, I hope you will be able to make use of these gems of knowledge learned through harsh lessons in the trenches of jBPM projects.

Please feel free to provide feedback and suggestions for areas that might be missing. I am not trying to cover all possible use cases for jBPM projects, but to provide a reference architecture that is recognisable for the majority of enterprise jBPM users.

The next article in this series examines the process definition layer...

Tuesday, March 16, 2010

jBPM 3 hints - finding a process instance in your deep dark jBPMContext

While writing some unit testing of the jBPM exception framework I needed to deal with two separately deployed process instances, one for the unit test and one for dealing with the exception I was causing.

My problem was how to obtain the exception process instance when all I know is the process name? I also had it easy from the unit testing point of view, I do not need to worry about multiple running instances of the exception framework as this is under my unit test control (at least I feel like I have some control over it!).

Below you see how you can locate your process instance and context within that instance. I will show you some helper methods that might come in handy for you (all logging done with log4j and assumes you understand what you see below):
/** Used to get the process id of the specific process I want. */
public long getExceptionProcId () {
  JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance();
  long procId;
  
  // Open the transaction.
  JbpmContext jbpmCtx = jbpmConf.createJbpmContext();

  try {
    // Get our process instance back.
    GraphSession graphSession = jbpmCtx.getGraphSession();
    ProcessDefinition processDefinition = 
      GraphSession.findLatestProcessDefinition("Exception Framework");
    assertThat("No process definition found.", 
      processDefinition, is(not(nullValue())));

    // Now, we search for all process instances of this process definition.
    List processInstances = 
      graphSession.findProcessInstances(processDefinition.getId());
    ProcessInstance procInst = (ProcessInstance) processInstances.get(0);
    procId = procInst.getId();
  } finally {
    // Close context.
    jbpmCtx.close();
  }   

  return procId;
}
With the above you can make use of the processId to recall your process instance as follows:
JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance(); 
JbpmContext jbpmCtx = jbpmConf.createJbpmContext();
  try {
    long processInstanceId = getExceptionProcId();
    ProcessInstance procInst = jbpmCtx.getProcessInstance(processInstanceId);
    assertThat("No exception process instance returned.", 
      procInst, is(not(nullValue())));
    assertThat("Exception process in unexpected state.", 
      procInst.hasEnded(), is(true));
  } finally {
    // Close context.
    jbpmCtx.close();
  } 
Another nice one to help you find what processes have been deployed in your current jBPMContext:
// find all our processes that have been deployed and log them.
JbpmConfiguration jbpmConf = JbpmConfiguration.getInstance();
JbpmContext jbpmCtx = jbpmConf.createJbpmContext();

  try {
    List listProcs = 
      jbpmCtx.getGraphSession().findAllProcessDefinitions();
    if (getLogger().isDebugEnabled()) {
      for (ProcessDefinition processDefinition : listProcs) {
 getLogger().debug("Process definition is: " 
          + processDefinition 
          + " with version: " 
          + processDefinition.getVersion() 
          + ".");
      }
    }
  } finally {
    jbpmCtx.close();
  }

Sunday, March 14, 2010

JBoss BRMS install example repository gives OutOfMemoryError: PermGen space

When setting up a demo of JBoss BRMS 5.0.1 (don't think it will really matter which BRMS 5.x you use) in a JBoss EAP 4.3 product I was confronted with an error.

After server start-up you login to http://localhost:8080/jboss-brms which asks you if you want to install the sample repository in your new system. When I said yes, it would run a bit and then give me an error like this:
22:05:00,094 ERROR [STDERR] Exception in thread "http-127.0.0.1-8080-5" 
22:05:00,094 ERROR [STDERR] java.lang.OutOfMemoryError: PermGen space
22:05:00,152 ERROR [ContainerBase] Servlet.service() for servlet guvnorService threw exception
java.lang.OutOfMemoryError: PermGen space
 at java.lang.Throwable.getStackTraceElement(Native Method)
        etc.........

To fix this you need to tweak the jboss-as/bin/run.sh by adding near the top of the file the following line:
# Set a sane PermSize.
JAVA_OPTS="$JAVA_OPTS -XX:MaxPermSize=256m"

Restart EAP 4.3 and the installation of your sample repository will run fine.

Friday, March 12, 2010

Tweaking the log4j BasicConfigurator

This is not magic that I am posting, but something I don't want to sort out again in the future. My current project was involving some extensive debugging of my unit tests, with long log lines on the console causing me to have to full-screen or scroll too much (forced to work on windows and lots of mouse clicks really get my goat).

By digging into the log4j BasicConfigurator.class (with my buddy Maurice, credit to the mastermind!) it has a default setup as follows:

root.addAppender(new ConsoleAppender(new PatternLayout("%r [%t] %p %c %x - %m%n")));

This will generate logging output like this:
4513 [main] DEBUG org.jbpm.graph.def.GraphElement  - event 'process-start' on ProcessDefinition(Exception Handling) for Token(/)
4654 [main] DEBUG org.jbpm.graph.def.GraphElement  -  event 'process-start' on ProcessDefinition(Exception Framework) for Token(/)

I adjusted this in my unit tests as follows:
((PatternLayout) ((Appender) Logger.getRootLogger().getAllAppenders()
  .nextElement()).getLayout())
  .setConversionPattern("%r [%t] %p %c %x -%n%n  %m%n%n");

This will give you output like this:
4513 [main] DEBUG org.jbpm.graph.def.GraphElement  -

  event 'process-start' on ProcessDefinition(Exception Handling) for Token(/)

4654 [main] DEBUG org.jbpm.graph.def.GraphElement  -

  event 'process-start' on ProcessDefinition(Exception Framework) for Token(/)

Monday, March 8, 2010

Fedora 12 NetworkManager update breaking GSM connection

My latest Fedora 12 update broke my Mobile Broadband GSM connection. I kept seeing this in my message log:


6516 Mar  8 12:22:49 localhost NetworkManager:   (hso0): device state change: 3 -> 4 (reason 0)
6517 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) scheduled...
6518 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) started...
6519 Mar  8 12:22:49 localhost NetworkManager:   (hso0): device state change: 4 -> 6 (reason 0)
6520 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) complete.
6521 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) scheduled...
6522 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) started...
6523 Mar  8 12:22:49 localhost NetworkManager:   (hso0): device state change: 6 -> 4 (reason 0)
6524 Mar  8 12:22:49 localhost NetworkManager:   Activation (hso0) Stage 1 of 5 (Device Prepare) complete.
6525 Mar  8 12:22:49 localhost modem-manager: (ttyHS2) opening serial device...
6526 Mar  8 12:22:49 localhost modem-manager: Modem /org/freedesktop/ModemManager/Modems/0: state changed (disabled -> enabling)
6527 Mar  8 12:22:50 localhost modem-manager: Modem /org/freedesktop/ModemManager/Modems/0: state changed (enabling -> enabled)
6528 Mar  8 12:22:50 localhost modem-manager: Modem /org/freedesktop/ModemManager/Modems/0: state changed (enabled -> disabled)
6529 Mar  8 12:22:50 localhost NetworkManager:   (hso0): device state change: 4 -> 3 (reason 0)
6530 Mar  8 12:22:50 localhost NetworkManager:   (hso0): deactivating device (reason: 0).
6531 Mar  8 12:22:50 localhost NetworkManager:   stage1_enable_done(): GSM modem enable failed: (32) SIM PIN required
6532 Mar  8 12:22:50 localhost NetworkManager:   (hso0): device state change: 3 -> 9 (reason 0)
6533 Mar  8 12:22:50 localhost NetworkManager:   Activation (hso0) failed.
6534 Mar  8 12:22:50 localhost NetworkManager:   (hso0): device state change: 9 -> 3 (reason 0)
6535 Mar  8 12:22:50 localhost NetworkManager:   (hso0): deactivating device (reason: 0).

The key here was the line:
  stage1_enable_done(): GSM modem enable failed: (32) SIM PIN required

Some looking around and it appears that the last update to NetworkManager broke it:

Name : NetworkManager
Arch : x86_64
Epoch : 1
Version : 0.7.998
Release : 2.git20100106.fc12

A simple downgrade will fix this to back you up to the previous version, here is mine:

Name : NetworkManager
Arch : x86_64
Epoch : 1
Version : 0.7.996
Release : 6.git20091021.fc12

To do this you use the following command:

$ sudo yum downgrade NetworkManager

Restarted and the GSM card worked as advertised!

============== UPDATE 02 April 2010 =========================
See Bugzilla on this for solution of upgrading the NetworkManager and ModemManager packages
to the versions found in the test repo:

https://bugzilla.redhat.com/show_bug.cgi?id=560742
http://download.fedora.redhat.com/pub/fedora/linux/updates/testing/12/

Sunday, February 28, 2010

Drools JBoss Rules 5.0 Developer's Guide review

This book from Packt Publishing is the best one I have run across in 2009. Often they are a bit off the mark on order, cohesion and readability, but this one is spot on for business rules developers.

I think that this will become the bible for JBoss BRMS developers as it covers all the details you need to get your projects rolling.

After a very short introduction (as it should be, we are developers and want to get started), this book dives into the basic rules syntax and validation. You are then walked through the process of how to load facts into a knowledge session which is all about data transformation.

When dealing with rules we often have to make sure that the business users are not left out in the cold. The author take a good look at Domain Specific Language (DSL) implementation in Drools, decision tables and dealing with Drools Flow. These are all supported with examples and code to feed the developer learning how to make use of these elements of a rules implementation.

A walk through stateful sessions is followed by Complex Event Processing (CEP) with Drools Fusion and supported with a fraud detection example. This is really interesting and feeds me at the technical depth I expect from a developers guide.

There is an entire chapter spent on the details within Drools Flow and this is followed up with a sample application to walk you through all the details of setting up and executing a rules project. Testing is touched on briefly, along with some integration topics (Spring and the JSR94 standard). Finally, the book finishes up with a look at performance, providing you with insights to help you optimize your rules projects.

This book is well written, contains good technical depth and is very thorough. There is not much left for you to look for on JBoss with regards to your rules projects. You need this book on your development shelf if you are working with JBoss and rules in your organization.

JBoss Drools Business Rules review

I read this book early in 2009 when I was diving deeper into the JBoss Business Rules Management System (BRMS) and found it to be a good overview.

It is light on the technical depth, but this is not a problem and all crucial parts of the system are covered. It appeals to both business types and technical types trying to get a grasp of the Drools project components.

The book begins with a good introduction to rules and business rules in an organization, provides help with setting up your Drools environment and provides a tour of the following components in your business rules infrastructure:
  • Guvnor, the guided rule editor
  • JBoss IDE, the developers rule editing environment
  • Testing your rules
  • Managing your rules from Excel
  • Domain Specific Languages (DSL)
  • RuleFlow, graphical rule design
Furthermore, the book takes you through deploying rules in a real life situation and details how the rule engine works all the way down to the RETE algorithm.

This book is a very good place to start your JBoss Business Rules experience, whether you have done rules development before or not. It will get you up to speed on rules, is easy to read, well structured and before you know it you will be designing your first rules package.

Thursday, February 18, 2010

JBoss Developer Studio 3.0.0.RC1 optimizations

For those lucky customers out there that have been evaluating or playing with the customer releases of the up-coming 3.0.0 release, you might have noticed the default setup is a bit slow to start.

I was playing with my eclipse.ini file parameters and got mine to start 5x faster with these settings, maybe they will help you too:

--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.0.200.v20090519
-vmargs
-Xms256m
-Xmx1024m
-XX:-UseParallelGC
-XX:+AggressiveOpts
-XX:-UseConcMarkSweepGC
-XX:MaxPermSize=512m
-Dosgi.bundles=reference:file:org.eclipse.equinox.simpleconfigurator_1.0.101.R35x_v20090807-1100.jar@1:start,org.eclipse.equinox.transforms.xslt@1:start,org.jboss.tools.equinox.transforms.xslt@1:start

JBoss Developer Studio performance optimizations (amazing speed improvements)

Working in a virtualized environment and very sick of the slow JBDS startups, we went looking for some help in the settings. Here is what we found:

The tricks is to use the optimization done in JDK 1.6 (VMarg2) and the new agresivity of the Just In Time compiler (JIT) for VMarg3. Add theses VM arguments to eclipse.ini (file is located in your Eclipse directory, one to each line)
 
-XX:-UseParallelGC 
-XX:+AggressiveOpts 
-XX:-UseConcMarkSweepGC

What are these doing:
VMarg1 -XX:-UseParallelGC Use parallel garbage collection for scavenges. (Introduced in 1.4.1) this will create more threads running in parallel, so the second processor will be put in use
VMarg2 -XX:-UseConcMarkSweepGC Use concurrent mark-sweep collection for the old generation. (Introduced in 1.4.1) The Eclipse GUI will feel more responsive as memory will be reclaimed without blocking VM executions.
VMarg3 -XX:+AggressiveOpts Turn on point performance compiler optimizations that are expected to be default in upcoming releases. (Introduced in 5.0 update 6.)

JBoss Developer Studio / Eclipse debug ignores breakpoints fix

This week I ran into some of my Java projects where the debugging was ignoring breakpoints in my JBoss Develoepr Studio / Eclipse IDE's. I thought this was maybe just something in JBoss Developer Studio (JBDS), but it appears to be an issue with Eclipse too. 
This was the fix for me, in JBDS /Eclipse:
 
Window -> Preferences -> Java -> Installed JRE's:
  • edit JRE being used
    • edit 'Default VM Arguments' line
    • -XX:+UseParallelGC
Fixes it for me!

Friday, February 5, 2010

jBPM v3.2.x Hibernate persistence bug - missing javax.jcr.Node

While trying to show hibernate persistence with jBPM v3.2.x I ran into a problem with a missing dependency. Details of the simple POJO class I was persisting, the hibernate mappings, error message encountered and solution tracing are provided below for those interested:

package com.sample.model;

// Sample person object for persistence checking.
public class Person {

 private Integer ssn;
 private String lastname;
 private String firstname;

 public void setFirstname(String firstname) {
  this.firstname = firstname;
 }
 public String getFirstname() {
  return firstname;
 }
 public void setLastname(String lastname) {
  this.lastname = lastname;
 }
 public String getLastname() {
  return lastname;
 }
 public void setSSN(Integer ssn) {
  this.ssn = ssn;
 }
 public Integer getSSN() {
  return ssn;
 }
}

The hibernate mappings were put into the person.hbm.xml file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.sample.model" auto-import="false" default-access="field">
  <class name="Person">
   <id name="ssn" column="SSN"><generator class="native" /></id>
   <property name="lastname" column="LASTNAME" />
   <property name="firstname" column="FIRSTNAME" />
  </class>
</hibernate-mapping>

// First the errors I was getting in my logging (just the last bits):
...
DEBUG GraphElement - event 'process-start' on ProcessDefinition(main_flow)
 for Token(/)
DEBUG VariableContainer - create variable 'person' in 'TokenVariableMap[/]' 
with value 'com.sample.model.Person@1dfc547'
DEBUG Converters - adding converter 'D', 'org.jbpm.context.exe.converter.DoubleToStringConverter'
DEBUG Converters - adding converter 'C', 'org.jbpm.context.exe.converter.CharacterToStringConverter'
DEBUG Converters - adding converter 'B', 'org.jbpm.context.exe.converter.BooleanToStringConverter'
DEBUG Converters - adding converter 'Y', 'org.jbpm.context.exe.converter.BytesToByteArrayConverter'
DEBUG Converters - adding converter 'A', 'org.jbpm.context.exe.converter.DateToLongConverter'
DEBUG Converters - adding converter 'R', 'org.jbpm.context.exe.converter.SerializableToByteArrayConverter'
DEBUG Converters - adding converter 'I', 'org.jbpm.context.exe.converter.IntegerToLongConverter'
DEBUG Converters - adding converter 'H', 'org.jbpm.context.exe.converter.ShortToLongConverter'
DEBUG Converters - adding converter 'G', 'org.jbpm.context.exe.converter.FloatToDoubleConverter'
DEBUG Converters - adding converter 'F', 'org.jbpm.context.exe.converter.FloatToStringConverter'
DEBUG Converters - adding converter 'E', 'org.jbpm.context.exe.converter.ByteToLongConverter'
DEBUG HibernateLongIdMatcher - no current context so valueClass 
cannot be stored as a long-id-ref to a hibernate object
DEBUG HibernateStringIdMatcher - no current context so valueClass 
cannot be stored as a string-id-ref to a hibernate object

The path to the missing interface we traced from jbpm-jpdl.jar -> org.jbpm.context.exe -> jbpm.varmapping.xml file contains the following mapping:

<!-- JSR 170 JCR Node -->
    <jbpm-type>
      <matcher>
        <bean class="org.jbpm.context.exe.matcher.JcrNodeMatcher" />
      </matcher>
      <variable-instance class="org.jbpm.context.exe.variableinstance.JcrNodeInstance" />
    </jbpm-type>    

This leads to org.jbpm.context.exe.matcher.JcrNodeMatcher.class which imports the class not included in jBPM:

/*
 * Snipped the license code.
 */
package org.jbpm.context.exe.matcher;

import javax.jcr.Node;        <<<<<<<<<<<<<< MISSING!!!!

import org.jbpm.context.exe.JbpmTypeMatcher;

public class JcrNodeMatcher implements JbpmTypeMatcher {

  private static final long serialVersionUID = 1L;

  public boolean matches(Object value) {
    return (Node.class.isAssignableFrom(value.getClass()));
  }

}

My solution: added external jar to projects classpath, jcr-1.0.jar which provides the needed interface interface. Hope this saves you some time!

Thursday, February 4, 2010

Upgrade Fedora 11 to Fedora 12 howto

A few simple steps to upgrade:

# As root you would like to have a clean start to the
# upgrade, so get an update out of the way.
#
$ yum update rpm

$ yum -y update

$ yum clean all

# Should a new kernel install/update require it,
# reboot before continuing with the rest.
#
# Then install the preupgrade package.
#
$ yum install preupgrade

# For console upgrade, use:
#
$ preupgrade-cli "Fedora 12 (Constantine)"

# If you like gui's to upgrade, use this.
#
$ preupgrade

This is exactly the same process as I previously described with Fedora 10 to Fedora 11 upgrade.

Tuesday, February 2, 2010

Update Fedora 12 to Firefox 3.6 howto

I got tired of waiting for the main Fedora 12 repositories to provide Firefox 3.6. I dug around a bit and the following will get you a Firefox 3.6 version installed on your Fedora 12, so what are you waiting for?







$ sudo yum --enablerepo=rawhide update firefox