Monday, December 29, 2008

jBPM 3.3.0.GA and JBoss AS 4.2.3.GA

The ops guys had already installed JBoss 4.2.3.GA on our servers. In an attempt to submit as few help desk requests as possible I decided to port jBPM 3.3.0.GA to JBoss instead of asking them to roll back.

The new docs say,

"The jbpm directory
"When jBPM is installed on a server configuration in JBoss, only the jbpm directory is added to the deploy directory and all components will be deployed under that directory. No other files of JBoss are changed or added outside that directory. "

I figured that would be a good place to start.

I copied the jbpm folder from the 3.3.0.GA distro to a clean JBoss 4.2.3.GA that I built from source.

I opened my browser and checked, "http://localhost:8080/jbpm-console." I tried logging in with "manager/manager." I got the error, "Login failed. Invalid user name or password. "

I added the following to $JBOSS_INSTALL/server/default/conf/login-congif.xml :

<application-policy name = "jbpm">
<authentication>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
flag="required">
<module-option name="dsJndiName">java:/JbpmDS</module-option>
<module-option name="principalsQuery">
SELECT PASSWORD_ FROM JBPM_ID_USER WHERE NAME_=?
</module-option>
<module-option name="rolesQuery">
SELECT g.NAME_ ,'Roles'
FROM JBPM_ID_USER u,
JBPM_ID_MEMBERSHIP m,
JBPM_ID_GROUP g
WHERE g.TYPE_='security-role'
AND m.GROUP_ = g.ID_
AND m.USER_ = u.ID_
AND u.NAME_=?
</module-option>
</login-module>
</authentication>
</application-policy>

When I restarted I could log in fine. I saw the processes that I had been working on.

Monday, December 15, 2008

Adding jBPM support to a Seam app

I created my app with seam-gen. While adding support for jBPM, I got the following error :

Caused by: org.dom4j.DocumentException: Error on line 29 of document  : The prefix "bpm" for element "bpm:jbpm" is not bound. Nested exception: The prefix "bpm" for element "bpm:jbpm" is not bound.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.dom4j.io.SAXReader.read(SAXReader.java:343)
at org.jboss.seam.util.XML.getRootElement(XML.java:24)
at org.jboss.seam.init.Initialization.initComponentsFromXmlDocument(Initialization.java:217)

The fix was to add the following to <components> declaration in the components.xml :


xmlns:bpm="http://jboss.com/products/seam/bpm"
Here's a nice tutorial from mastertheboss on adding jBPM support to a Seam app.

Thursday, December 4, 2008

Seam Tip Number 5

If you ever copy and paste a project directory be sure to change the seam-gen.properties file.

I got a new MacBook Pro. I copied my Eclipse workspaces over of course.

I made some changes to the entities in a project. I then opened a terminal and ran "seam generate-ui." I got a FileNotFound exception in build.xml line 1154 . Something was still pointing to the C:/ drive.

Inside the root Eclipse project directory there is a seam-gen.properties file. Changing that fixes anything.

jBPM 3.3.0.GA and Oracle 10g Express Server

I grabbed the jBPM 3.3.0.GA release. I got a process deployed under hsqldb to make sure everything worked. The next step is to switch out hsqldb for Oracle XE. I run Oracle XE under parallels.

The user guide chapter 7 lays out the changes.

One "gotcha: I had was the type mapping in the datasource. "Oracle9i" was the appropriate setting. It took me a couple of tries.

The datasource, located in /jbpm-3.3.0.GA/jboss-4.2.2.GA/server/default/deploy/jbpm, I ended up with :
<?xml version="1.0" encoding="UTF-8"?>

<!-- ===================================================================== -->
<!-- -->
<!-- JBoss Server Configuration -->
<!-- -->
<!-- ===================================================================== -->

<!-- $Id: oracle-ds.xml 71535 2008-04-01 07:05:03Z adrian@jboss.org $ -->
<!-- ==================================================================== -->
<!-- Datasource config for Oracle originally from Steven Coy -->
<!-- ==================================================================== -->


<datasources>
<local-tx-datasource>
<jndi-name>JbpmDS</jndi-name>
<connection-url>jdbc:oracle:thin:@IP_ADDRESS:1521:xe</connection-url>
<!--

Here are a couple of the possible OCI configurations.
For more information, see http://otn.oracle.com/docs/products/oracle9i/doc_library/release2/java.920/a96654/toc.htm

<connection-url>jdbc:oracle:oci:@youroracle-tns-name</connection-url>
or
<connection-url>jdbc:oracle:oci:@(description=(address=(host=youroraclehost)(protocol=tcp)(port=1521))(connect_data=(SERVICE_NAME=yourservicename)))</connection-url>

Clearly, its better to have TNS set up properly.
-->
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>USER_NAME</user-name>
<password>PASSWORD</password>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<!--valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name-->
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- sql to call when connection is created
<new-connection-sql>some arbitrary sql</new-connection-sql>
-->

<!-- sql to call on an existing pooled connection when it is obtained from pool - the OracleValidConnectionChecker is prefered
<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
-->

<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</local-tx-datasource>

</datasources>

The hibernate.cfg.xml, located in /jbpm-3.3.0.GA/jboss-4.2.2.GA/server/default/deploy/jbpm/jbpm-service.sar, I ended up with :

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

<!-- hibernate dialect -->
<!--
<property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
-->
<property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>

<!-- JDBC connection properties (begin) ===
<property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="hibernate.connection.url">jdbc:hsqldb:mem:jbpm</property>
<property name="hibernate.connection.username">sa</property>
<property name="hibernate.connection.password"></property>
==== JDBC connection properties (end) -->


<!-- DataSource properties (begin)
<property name="hibernate.connection.datasource">java:comp/env/jdbc/JbpmDataSource</property>
-->
<property name="hibernate.connection.datasource">java:/JbpmDS</property>
<!-- DataSource properties (end) -->

<!-- JTA transaction properties (begin) -->
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<!-- JTA transaction properties (end) -->

<!-- CMT transaction properties (begin) ===
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
==== CMT transaction properties (end) -->

<!-- ################################### -->
<!-- # common settings # -->
<!-- ################################### -->

<!-- Automatic schema creation (begin) ===
<property name="hibernate.hbm2ddl.auto">create</property>
==== Automatic schema creation (end) -->

<!-- Simple memory-only cache -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

<!-- logging properties -->
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>

<!-- ############################################ -->
<!-- # mapping files with external dependencies # -->
<!-- ############################################ -->

<!-- Additional mappings defined per module go here -->
<mapping resource="hibernate.extra.hbm.xml" />
<mapping resource="hibernate.identity.hbm.xml" />


<!-- ###################### -->
<!-- # jbpm mapping files # -->
<!-- ###################### -->

<!-- hql queries and type defs -->
<mapping resource="org/jbpm/db/hibernate.queries.hbm.xml" />
<!-- hql queries used in simulation for querying historical data
uncomment if you want to use the GetSimulationInputCommand
or maybe you also want to use the queries yourself
be patient: the queries need the stddev function to be enabled in your dialect
more information on this can be found here: http://www.camunda.com/business_process_simulation_news/mysql_and_stddev.html -->
<!--
<mapping resource="org/jbpm/sim/bam/hibernate.queries.hbm.xml" />
-->

<!-- graph.action mapping files -->
<mapping resource="org/jbpm/graph/action/MailAction.hbm.xml"/>

<!-- graph.def mapping files -->
<mapping resource="org/jbpm/graph/def/ProcessDefinition.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Node.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Transition.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Event.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/Action.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/SuperState.hbm.xml"/>
<mapping resource="org/jbpm/graph/def/ExceptionHandler.hbm.xml"/>
<mapping resource="org/jbpm/instantiation/Delegation.hbm.xml"/>

<!-- ############################################ -->
<!-- # another mapping file with external dependencies # -->
<!-- ############################################ -->
<!-- following mapping file has a dependency on -->
<!-- 'bsh-{version}.jar'. -->
<!-- uncomment this if you don't have bsh on your -->
<!-- classpath. you won't be able to use the -->
<!-- script element in process definition files -->
<!-- has to be defined below org/jbpm/graph/def/Action.hbm.xml -->
<!-- due to the inline collection-cache elements below -->
<mapping resource="org/jbpm/graph/action/Script.hbm.xml"/>

<!-- graph.node mapping files -->
<mapping resource="org/jbpm/graph/node/StartState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/EndState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/ProcessState.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Decision.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Fork.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/Join.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/MailNode.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/State.hbm.xml"/>
<mapping resource="org/jbpm/graph/node/TaskNode.hbm.xml"/>

<!-- context.def mapping files -->
<mapping resource="org/jbpm/context/def/ContextDefinition.hbm.xml"/>
<mapping resource="org/jbpm/context/def/VariableAccess.hbm.xml"/>

<!-- bytes mapping files -->
<mapping resource="org/jbpm/bytes/ByteArray.hbm.xml"/>

<!-- module.def mapping files -->
<mapping resource="org/jbpm/module/def/ModuleDefinition.hbm.xml"/>

<!-- file.def mapping files -->
<mapping resource="org/jbpm/file/def/FileDefinition.hbm.xml"/>

<!-- taskmgmt.def mapping files -->
<mapping resource="org/jbpm/taskmgmt/def/TaskMgmtDefinition.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/Swimlane.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/Task.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/def/TaskController.hbm.xml"/>

<!-- scheduler.def mapping files -->
<mapping resource="org/jbpm/scheduler/def/CreateTimerAction.hbm.xml"/>
<mapping resource="org/jbpm/scheduler/def/CancelTimerAction.hbm.xml"/>

<!-- graph.exe mapping files -->
<mapping resource="org/jbpm/graph/exe/Comment.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/ProcessInstance.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/Token.hbm.xml"/>
<mapping resource="org/jbpm/graph/exe/RuntimeAction.hbm.xml"/>

<!-- module.exe mapping files -->
<mapping resource="org/jbpm/module/exe/ModuleInstance.hbm.xml"/>

<!-- context.exe mapping files -->
<mapping resource="org/jbpm/context/exe/ContextInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/TokenVariableMap.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/VariableInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/ByteArrayInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/DateInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/DoubleInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/HibernateLongInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/HibernateStringInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/LongInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/NullInstance.hbm.xml"/>
<mapping resource="org/jbpm/context/exe/variableinstance/StringInstance.hbm.xml"/>

<!-- job mapping files -->
<mapping resource="org/jbpm/job/Job.hbm.xml"/>
<mapping resource="org/jbpm/job/Timer.hbm.xml"/>
<mapping resource="org/jbpm/job/ExecuteNodeJob.hbm.xml"/>
<mapping resource="org/jbpm/job/ExecuteActionJob.hbm.xml"/>
<mapping resource="org/jbpm/job/CleanUpProcessJob.hbm.xml"/>

<!-- taskmgmt.exe mapping files -->
<mapping resource="org/jbpm/taskmgmt/exe/TaskMgmtInstance.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/TaskInstance.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/PooledActor.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/exe/SwimlaneInstance.hbm.xml"/>

<!-- logging mapping files -->
<mapping resource="org/jbpm/logging/log/ProcessLog.hbm.xml"/>
<mapping resource="org/jbpm/logging/log/MessageLog.hbm.xml"/>
<mapping resource="org/jbpm/logging/log/CompositeLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ActionLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/NodeLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessInstanceCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessInstanceEndLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/ProcessStateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/SignalLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TokenCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TokenEndLog.hbm.xml"/>
<mapping resource="org/jbpm/graph/log/TransitionLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableDeleteLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/VariableUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/ByteArrayUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/DateUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/DoubleUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/HibernateLongUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/HibernateStringUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/LongUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/context/log/variableinstance/StringUpdateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskAssignLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/TaskEndLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneCreateLog.hbm.xml"/>
<mapping resource="org/jbpm/taskmgmt/log/SwimlaneAssignLog.hbm.xml"/>

<!-- ################################### -->
<!-- # cache settings # -->
<!-- # strategy="nonstrict-read-write" # -->
<!-- # can be used with hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider # -->
<!-- ################################### -->

<class-cache class="org.jbpm.context.def.VariableAccess" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.file.def.FileDefinition.processFiles" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.graph.action.Script.variableAccesses" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.Action" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.Event" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Event.actions" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.ExceptionHandler" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ExceptionHandler.actions" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.Node" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Node.events" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Node.exceptionHandlers" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Node.leavingTransitions" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Node.arrivingTransitions" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.ProcessDefinition" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ProcessDefinition.events" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ProcessDefinition.exceptionHandlers" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ProcessDefinition.nodes" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ProcessDefinition.actions" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.ProcessDefinition.definitions" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.graph.def.SuperState.nodes" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.graph.def.Transition" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Transition.events" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.graph.def.Transition.exceptionHandlers" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.graph.node.Decision.decisionConditions" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.graph.node.ProcessState.variableAccesses" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.graph.node.TaskNode.tasks" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.instantiation.Delegation" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.module.def.ModuleDefinition" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.taskmgmt.def.Swimlane.tasks" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.taskmgmt.def.TaskController" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.taskmgmt.def.TaskController.variableAccesses" usage="nonstrict-read-write" />

<class-cache class="org.jbpm.taskmgmt.def.Task" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.taskmgmt.def.Task.events" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.taskmgmt.def.Task.exceptionHandlers" usage="nonstrict-read-write" />

<collection-cache collection="org.jbpm.taskmgmt.def.TaskMgmtDefinition.swimlanes" usage="nonstrict-read-write" />
<collection-cache collection="org.jbpm.taskmgmt.def.TaskMgmtDefinition.tasks" usage="nonstrict-read-write" />


</session-factory>
</hibernate-configuration>

Wednesday, December 3, 2008

Unsigned JUnit 4 in JBoss Developer Studio

Running a JUnit4 test I got the following error :

junit.framework.JUnit4TestCaseFacade"'s signer information does not match signer information of other classes in the same package
Apparently other people have had the same problem with Europa.

The solution was easy.  I downloaded JUnit4 jars and created a new User Library with them.  I then added my new user library to the project and the run configuration.

To add the new library to the project :
  • I downloaded Junit4 and its' sources.
  • I put both jars in "/Users/[USER_NAME]/Java."
  • I control-clicked on the prject name and chose "Build Path -> Configure Build Path."
  • Under "Libraries" I removed the JUnit 4 library.
  • I clicked "Add Library -> User Library -> Next -> User Libraries -> New" and created a Library called "JUnit4 Local."
  • I added the jars I downloaded.

To add the new library to the run configuration :
  • Run Button -> Run Configurations
  • The most recently run test is highlighted.  Choose the one that needs to be changed.
  • Click the "Classpath" tab.
  • Expand "User Entries"
  • Remove the existing JUnit4 library.
  • Add the user library.