Chapter 6. Configuration
Prev |  | Next

## Chapter 6. Configuration

The simplest way to configure jBPM is by putting the `jbpm.cfg.xml` configuration file in the root of the classpath. If that file is not found as a resource, the default minimal configuration will be used that is included in the jbpm library. Note that the minimal configuration does not have any configurations for persistence.

The jBPM configuration is represented by the java class `org.jbpm.JbpmConfiguration`. Most easy way to get a hold of the JbpmConfiguration is to make use of the singleton instance method `JbpmConfiguration.getInstance()`.

If you want to load a configuraiton from another source, you can use the `JbpmConfiguration.parseXxxx` methods.

    static JbpmConfinguration jbpmConfiguration = JbpmConfinguration.getInstance();

The JbpmConfiguration is threadsafe and hence can be kept in a static member. All threads can use the JbpmConfiguration as a factory for JbpmContext objects. A JbpmContext typically represents one transaction. The JbpmContext makes services available inside of a context block. A context block looks like this:

    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
    try {
      // This is what we call a context block.
      // Here you can perform workflow operations

    } finally {
      jbpmContext.close();
    }

The `JbpmContext` makes a set of services and the configuration available to jBPM. These services are configured in the `jbpm.cfg.xml` configuration file and make it possible for jBPM to run in any Java environment and use whatever services are available in that environment.

Here's a typical configuration for the JbpmContext as you can find it in `src/config.files/jbpm.cfg.xml`:

    <jbpm-configuration>

      <jbpm-context>
        <service name='persistence' factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />
        <service name='message' factory='org.jbpm.msg.db.DbMessageServiceFactory' />
        <service name='scheduler' factory='org.jbpm.scheduler.db.DbSchedulerServiceFactory' />
        <service name='logging' factory='org.jbpm.logging.db.DbLoggingServiceFactory' />
        <service name='authentication' factory='org.jbpm.security.authentication.DefaultAuthenticationServiceFactory' />
      </jbpm-context>

      <!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar -->
      <string name='resource.hibernate.cfg.xml' value='hibernate.cfg.xml' />
      <!-- <string name='resource.hibernate.properties' value='hibernate.properties' /> -->
      <string name='resource.business.calendar' value='org/jbpm/calendar/jbpm.business.calendar.properties' />
      <string name='resource.default.modules' value='org/jbpm/graph/def/jbpm.default.modules.properties' />
      <string name='resource.converter' value='org/jbpm/db/hibernate/jbpm.converter.properties' />
      <string name='resource.action.types' value='org/jbpm/graph/action/action.types.xml' />
      <string name='resource.node.types' value='org/jbpm/graph/node/node.types.xml' />
      <string name='resource.parsers' value='org/jbpm/jpdl/par/jbpm.parsers.xml' />
      <string name='resource.varmapping' value='org/jbpm/context/exe/jbpm.varmapping.xml' />

      <int name='jbpm.byte.block.size' value="1024" singleton="true" />
      <bean name='jbpm.task.instance.factory' class='org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl' singleton='true' />
      <bean name='jbpm.variable.resolver' class='org.jbpm.jpdl.el.impl.JbpmVariableResolver' singleton='true' />

    </jbpm-configuration>

In this configuration file you can see 3 parts:

- The first part configures the jbpm context with a set of service implementations. The possible configuration options are covered in the chapters that cover the specific service implementations.

- The second part are all mappings of references to configuration resources. These resource references can be updated if you want to customize one of these configuration files. Typically, you make a copy the default configuration which is in the `jbpm-3.x.jar` and put it somewhere on the classpath. Then you update the reference in this file and jbpm will use your customized version of that configuration file.

- The third part are some miscallanious configurations used in jbpm. These configuration options are described in the chapters that cover the specific topic.

The default configured set of services is targetted at a simple webapp environment and minimal dependencies. The persistence service will obtain a jdbc connection and all the other services will use the same connection to perform their services. So all of your workflow operations are centralized into 1 transaction on a JDBC connection without the need for a transaction manager.

`JbpmContext` contains convenience methods for most of the common process operations:

      public void deployProcessDefinition(ProcessDefinition processDefinition) {...}
      public List getTaskList() {...}
      public List getTaskList(String actorId) {...}
      public List getGroupTaskList(List actorIds) {...}
      public TaskInstance loadTaskInstance(long taskInstanceId) {...}
      public TaskInstance loadTaskInstanceForUpdate(long taskInstanceId) {...}
      public Token loadToken(long tokenId) {...}
      public Token loadTokenForUpdate(long tokenId) {...}
      public ProcessInstance loadProcessInstance(long processInstanceId) {...}
      public ProcessInstance loadProcessInstanceForUpdate(long processInstanceId) {...}
      public ProcessInstance newProcessInstance(String processDefinitionName) {...}
      public void save(ProcessInstance processInstance) {...}
      public void save(Token token) {...}
      public void save(TaskInstance taskInstance) {...}
      public void setRollbackOnly() {...}

Note that the `XxxForUpdate` methods will register the loaded object for auto-save so that you don't have to call one of the save methods explicitely.

It's possible to specify multiple `jbpm-context`s, but then you have to make sure that each `jbpm-context` is given a unique `name` attribute. Named contexts can be retrieved with `JbpmConfiguration.createContext(String name);`

A `service` element specifies the name of a service and the service factory for that service. The service will only be created in case it's asked for with `JbpmContext.getServices().getService(String name)`.

The factories can also be specified as an element instead of an attribute. That might be necessary to inject some configuration information in the factory objects. The component responsible for parsing the XML, creating and wiring the objects is called the object factory.

## 6.1. Customizing factories

A common mistake when customizing factories is to mix the short and the long notation. Examples of the short notation can be seen in the default configuration file and above: E.g.

      ...
      <service name='persistence' factory='org.jbpm.persistence.db.DbPersistenceServiceFactory' />

If specific properties on a service need to be specified, the short notation can't be used, but instead, the long notation has to be used like this: E.g.

      <service name="persistence">
        <factory>
          <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
            <field name="dataSourceJndiName"><string value="java:/myDataSource"/></field>
            <field name="isCurrentSessionEnabled"><true /></field>
            <field name="isTransactionEnabled"><false /></field>
          </bean>
        </factory>
      </service>

## 6.2. Configuration properties

jbpm.byte.block.size: File attachments and binary variables are stored in the database. Not as blobs, but as a list of fixed sized binary objects. This is done to improve portability amongst different databases and improve overall embeddability of jBPM. This parameter controls the size of the fixed length chunks.

jbpm.task.instance.factory: To customize the way that task instances are created, specify a fully qualified class name in this property. This might be necessary when you want to customize the TaskInstance bean and add new properties to it. See also Section 11.10, “Customizing task instances” The specified class should implement org.jbpm.taskmgmt.TaskInstanceFactory.

jbpm.variable.resolver: To customize the way that jBPM will look for the first term in JSF-like expressions.

## 6.3. Other configuration files

Here's a short description of all the configuration files that are customizable in jBPM.

### 6.3.1. Hibernate cfg xml file

This file contains hibernate configurations and references to the hibernate mapping resource files.

Location: `hibernate.cfg.xml` unless specified otherwise in the jbpm.hibernate.cfg.xml property in the jbpm.properties file. In the jbpm project the default hibernate cfg xml file is located in directory `src/config.files/hibernate.cfg.xml`

### 6.3.2. Hibernate queries configuration file

This file contains hibernate queries that are used in the jBPM sessions `org.jbpm.db.*Session`.

Location: `org/jbpm/db/hibernate.queries.hbm.xml`

### 6.3.3. Node types configuration file

This file contains the mapping of XML node elements to Node implementation classes.

Location: `org/jbpm/graph/node/node.types.xml`

### 6.3.4. Action types configuration file

This file contains the mapping of XML action elements to Action implementation classes.

Location: `org/jbpm/graph/action/action.types.xml`

### 6.3.5. Business calendar configuration file

Contains the definition of business hours and free time.

Location: `org/jbpm/calendar/jbpm.business.calendar.properties`

### 6.3.6. Variable mapping configuration file

Specifies how the values of the process variables (java objects) are converted to variable instances for storage in the jbpm database.

Location: `org/jbpm/context/exe/jbpm.varmapping.xml`

### 6.3.7. Converter configuration file

Specifies the id-to-classname mappings. The id's are stored in the database. The org.jbpm.db.hibernate.ConverterEnumType is used to map the ids to the singleton objects.

Location: `org/jbpm/db/hibernate/jbpm.converter.properties`

### 6.3.8. Default modules configuration file

specifies which modules are added to a new ProcessDefinition by default.

Location: `org/jbpm/graph/def/jbpm.default.modules.properties`

### 6.3.9. Process archive parsers configuration file

specifies the phases of process archive parsing

Location: `org/jbpm/jpdl/par/jbpm.parsers.xml`

## 6.4. jBPM debug logs in JBoss

When running jPDL in JBoss and you want to see the debug logs of jBPM, replace the file `conf/log4j.xml` in the jboss server configuration take with the file `deploy/log4j.xml` in your jPDL distribution. In the suite, the full location of the file to be replaced is `[jpdl.home]/server/server/jbpm/conf/log4j.xml`.

## 6.5. Logging of optimistic concurrency exceptions

When running in a cluster, jBPM synchronizes on the database. By default with optimistic locking. This means that each operation is performed in a transaction. And if at the end a collision is detected, then the transaction is rolled back and has to be handled. E.g. by a retry. So optimistic locking exceptions are usually part of the normal operation. Therefor, by default, the `org.hibernate.StateObjectStateException`s the that hibernate throws in that case are not logged with error and a stack trace, but instead a simple info message 'optimistic locking failed' is displayed.

Hibernate itself will log the StateObjectStateException including a stack trace. If you want to get rid of these stack traces, put the level of `org.hibernate.event.def.AbstractFlushingEventListener` to FATAL. If you use log4j following line of configuration can be used for that:

    log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL

If you want to enable logging of the jBPM stack traces, add the following line to your jbpm.cfg.xml:

    <boolean name="jbpm.hide.stale.object.exceptions" value="false" />

.

## 6.6. Object factory

The object factory can create objects according to a beans-like xml configuration file. The configuration file specifies how objects should be created, configured and wired together to form a complete object graph. The object factory can inject the configurations and other beans into a bean.

In its simplest form, the object factory is able to create basic types and java beans from such a configuration:

    <beans>
      <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance"/>
      <string name="greeting">hello world</string>
      <int name="answer">42</int>
      <boolean name="javaisold">true</boolean>
      <float name="percentage">10.2</float>
      <double name="salary">100000000.32</double>
      <char name="java">j</char>
      <null name="dusttodust" />
    </beans>

    ---------------------------------------------------------

    ObjectFactory of = ObjectFactory.parseXmlFromAbove();
    assertEquals(TaskInstance.class, of.getNewObject("task").getClass());
    assertEquals("hello world", of.getNewObject("greeting"));
    assertEquals(new Integer(42), of.getNewObject("answer"));
    assertEquals(Boolean.TRUE, of.getNewObject("javaisold"));
    assertEquals(new Float(10.2), of.getNewObject("percentage"));
    assertEquals(new Double(100000000.32), of.getNewObject("salary"));
    assertEquals(new Character('j'), of.getNewObject("java"));
    assertNull(of.getNewObject("dusttodust"));

Also you can configure lists:

    <beans>
      <list name="numbers">
        <string>one</string>
        <string>two</string>
        <string>three</string>
      </list>
    </beans>

and maps

    <beans>
      <map name="numbers">
        <entry><key><int>1</int></key><value><string>one</string></value></entry>
        <entry><key><int>2</int></key><value><string>two</string></value></entry>
        <entry><key><int>3</int></key><value><string>three</string></value></entry>
      </map>
    </beans>

Beans can be configured with direct field injection and via property setters.

    <beans>
      <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
        <field name="name"><string>do dishes</string></field>
        <property name="actorId"><string>theotherguy</string></property>
      </bean>
    </beans>

Beans can be referenced. The referenced object doesn't have to be a bean, it can be a string, integer or any other object.

    <beans>
      <bean name="a" class="org.jbpm.A" />
      <ref name="b" bean="a" />
    </beans>

Beans can be constructed with any constructor

    <beans>
      <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
        <constructor>
          <parameter class="java.lang.String">
            <string>do dishes</string>
          </parameter>
          <parameter class="java.lang.String">
            <string>theotherguy</string>
          </parameter>
        </constructor>
      </bean>
    </beans>

... or with a factory method on a bean ...

    <beans>
      <bean name="taskFactory"
             class="org.jbpm.UnexistingTaskInstanceFactory"
             singleton="true"/>

      <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
        <constructor factory="taskFactory" method="createTask" >
          <parameter class="java.lang.String">
            <string>do dishes</string>
          </parameter>
          <parameter class="java.lang.String">
            <string>theotherguy</string>
          </parameter>
        </constructor>
      </bean>
    </beans>

... or with a static factory method on a class ...

    <beans>
      <bean name="task" class="org.jbpm.taskmgmt.exe.TaskInstance" >
        <constructor factory-class="org.jbpm.UnexistingTaskInstanceFactory" method="createTask" >
          <parameter class="java.lang.String">
            <string>do dishes</string>
          </parameter>
          <parameter class="java.lang.String">
            <string>theotherguy</string>
          </parameter>
        </constructor>
      </bean>
    </beans>

Each named object can be marked as singleton with the attribute `singleton="true"`. That means that a given object factory will always return the same object for each request. Note that singletons are not shared between different object factories.

The singleton feature causes the differentiation between the methods `getObject` and `getNewObject`. Typical users of the object factory will use the `getNewObject`. This means that first the object factory's object cache is cleared before the new object graph is constructed. During construction of the object graph, the non-singleton objects are stored in the object factory's object cache to allow for shared references to one object. The singleton object cache is different from the plain object cache. The singleton cache is never cleared, while the plain object cache is cleared at the start of every `getNewObject` method.

Prev | Up | Next
Chapter 5. Deployment | Home | Chapter 7. Persistence