Hello folks,

I discovered a strange class cast exception when evaluating jBPM and its 
starter kit. My team and me want to use jBPM in a scenario where the workflow 
engine is controlling other external processes.

Due to certain project requirements we need to extend the functionality of 
class org.jbpm.graph.def.Node by subclassing it. Following the jBPM 
documentation I applied the necesarry changes to the sources in the starter 
kit, rebuilded and redeployed the jBPM service archive and the web application.

Here are the steps I performed:

Step 1: Changed file jbpm.cfg.xml to reference a different node types mapping 
file

  | <jbpm-configuration>
  | 
  |   <!-- 
  |     This configuration is used when there is no jbpm.cfg.xml file found in 
the 
  |     root of the classpath.  It is a very basic configuration without 
persistence
  |     and message services.  Only the authorization service installed.
  |     You can parse and create processes, but when you try to use one of the 
  |     unavailable services, you'll get an exception.
  |   -->
  |   
  |   <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.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="de/webde/geppi/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" />
  | 
  |   <long   name="jbpm.msg.wait.timout" value="5000" singleton="true" />
  |   <int    name="jbpm.byte.block.size" value="1024" singleton="true" />
  |   <string name="mail.smtp.host" value="localhost" />
  |   <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" />
  |   <bean   name="jbpm.mail.address.resolver" 
class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" />
  | 
  | </jbpm-configuration>
  | 

The important line is

  | <string name="resource.action.types" 
value="org/jbpm/graph/action/action.types.xml" />
  | 

Step 2: Added the alternative node mapping configuration

  | <node-types>
  |   <node-type element="start-state" class="org.jbpm.graph.node.StartState" />
  |   <node-type element="end-state" class="org.jbpm.graph.node.EndState" />
  |   <node-type element="node" class="de.webde.geppi.GeppiNode" />
  |   <node-type element="state" class="org.jbpm.graph.node.State" />
  |   <node-type element="task-node" class="org.jbpm.graph.node.TaskNode" />
  |   <node-type element="fork" class="org.jbpm.graph.node.Fork" />
  |   <node-type element="join" class="org.jbpm.graph.node.Join" />
  |   <node-type element="decision" class="org.jbpm.graph.node.Decision" />
  |   <node-type element="process-state" 
class="org.jbpm.graph.node.ProcessState" />
  |   <node-type element="super-state" class="org.jbpm.graph.def.SuperState" />
  |   <node-type element="merge" class="org.jbpm.graph.node.Merge" />
  |   <node-type element="milestone-node" 
class="org.jbpm.graph.node.MilestoneNode" />
  |   <node-type element="interleave-start" 
class="org.jbpm.graph.node.InterleaveStart" />
  |   <node-type element="interleave-end" 
class="org.jbpm.graph.node.InterleaveEnd" />
  |   <node-type element="page" class="org.jboss.seam.pageflow.Page" />
  |   <node-type element="start-page" class="org.jboss.seam.pageflow.Page" />
  | </node-types>
  | 

The important line switching the implementation from class 
org.jbpm.graph.def.Node to class de.webde.geppi.GeppiNode (Geppi is the system 
under development) is

  |   <node-type element="node" class="de.webde.geppi.GeppiNode" />
  | 

Step 3: Implemented class de.webde.geppi.GeppiNode and its corresponding 
hibernate ORM configuration file. 

Besides some additional console printing the current implementation of class 
de.webde.geppi.GeppiNode does not do anything different than class 
org.jbpm.graph.def.Node. The functional extension will be done later.

  | /**
  |  * 
  |  */
  | package de.webde.geppi;
  | 
  | import org.jbpm.graph.def.Node;
  | import org.jbpm.graph.exe.ExecutionContext;
  | 
  | /**
  |  * 
  |  */
  | public class GeppiNode extends Node {
  | 
  |     /**
  |      * 
  |      */
  |     private static final long serialVersionUID = -3137521269855001903L;
  | 
  |     /* (non-Javadoc)
  |      * @see 
org.jbpm.graph.def.Node#execute(org.jbpm.graph.exe.ExecutionContext)
  |      */
  |     public void execute(ExecutionContext executionContext) {
  |             // if there is a custom action associated with this node
  |             if (action != null) {
  |                     try {
  |                             System.out.println("+++++++++++++ Execute 
Action  +++++++++++++");
  |                             // execute the action
  |                             action.execute(executionContext);
  |                             System.out.println("+++++++++++++ Finished 
Action +++++++++++++");
  | 
  |                     } catch (Exception exception) {
  |                             // NOTE that Error's are not caught because 
that might halt the
  |                             // JVM and mask the original Error.
  |                             // search for an exception handler or throw to 
the client
  |                             raiseException(exception, executionContext);
  |                     }
  | 
  |             } else {
  |                     // let this node handle the token
  |                     // the default behaviour is to leave the node over the 
default
  |                     // transition.
  |                     leave(executionContext);
  |             }
  |     }
  | 
  | }
  | 

  | <?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 default-access="field" >
  |   <subclass name="de.webde.geppi.GeppiNode" 
  |             discriminator-value="G" 
  |             extends="org.jbpm.graph.def.Node"/>
  | </hibernate-mapping>
  | 

Step 4: Updated the Hibernate configuration to include a mapping for class 
de.webde.geppi.GeppiNode 

  | <?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>
  | 
  |     <!-- jdbc connection properties -->
  |     <property 
name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
  |     <property 
name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
  |     <property 
name="hibernate.connection.url">jdbc:hsqldb:mem:.;sql.enforce_strict_size=true</property>
  |     <property name="hibernate.connection.username">sa</property>
  |     <property name="hibernate.connection.password"></property>
  | 
  |     <property 
name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
  |         
  |     <!-- other hibernate properties 
  |     <property name="hibernate.show_sql">true</property>
  |     <property name="hibernate.format_sql">true</property>
  |     <property name="hibernate.use_sql_comments">true</property>
  |     -->
  | 
  |     <!-- ############################################ -->
  |     <!-- # mapping files with external dependencies # -->
  |     <!-- ############################################ -->
  | 
  |     <!-- following mapping file has a dependendy 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   -->
  |     <mapping resource="org/jbpm/graph/action/Script.hbm.xml"/>
  | 
  |     <!-- following mapping files have a dependendy on  -->
  |     <!-- 'jbpm-identity-{version}.jar', mapping files  -->
  |     <!-- of the pluggable jbpm identity component.     -->
  |     <!-- comment out the following 3 lines if you don't-->
  |     <!-- want to use the default jBPM identity mgmgt   -->
  |     <!-- component                                     -->
  |     <mapping resource="org/jbpm/identity/User.hbm.xml"/>
  |     <mapping resource="org/jbpm/identity/Group.hbm.xml"/>
  |     <mapping resource="org/jbpm/identity/Membership.hbm.xml"/>
  | 
  |     <!-- ###################### -->
  |     <!-- # jbpm mapping files # -->
  |     <!-- ###################### -->
  | 
  |     <!-- hql queries and type defs -->
  |     <mapping resource="org/jbpm/db/hibernate.queries.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"/>
  | 
  |     <!-- Geppi mapping files -->
  |     <mapping resource="de/webde/geppi/GeppiNode.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/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"/>
  | 
  |     <!-- 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"/>
  | 
  |     <!-- module.def mapping files -->
  |     <mapping resource="org/jbpm/module/def/ModuleDefinition.hbm.xml"/>
  | 
  |     <!-- bytes mapping files -->
  |     <mapping resource="org/jbpm/bytes/ByteArray.hbm.xml"/>
  | 
  |     <!-- file.def mapping files -->
  |     <mapping resource="org/jbpm/file/def/FileDefinition.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"/>
  | 
  |     <!-- msg.db mapping files -->
  |     <mapping resource="org/jbpm/msg/Message.hbm.xml"/>
  |     <mapping resource="org/jbpm/msg/db/TextMessage.hbm.xml"/>
  |     <mapping resource="org/jbpm/command/ExecuteActionCommand.hbm.xml"/>
  |     <mapping resource="org/jbpm/command/ExecuteNodeCommand.hbm.xml"/>
  |     <mapping resource="org/jbpm/command/SignalCommand.hbm.xml"/>
  |     <mapping resource="org/jbpm/command/TaskInstanceEndCommand.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"/>
  | 
  |     <!-- scheduler.exe mapping files -->
  |     <mapping resource="org/jbpm/scheduler/exe/Timer.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"/>
  |     
  |   </session-factory>
  | </hibernate-configuration>
  | 

The lines adding the additional mapping are

  |     <!-- Geppi mapping files -->
  |     <mapping resource="de/webde/geppi/GeppiNode.hbm.xml"/>
  | 
  | 

By the way, node.types.xml, GeppiNode.java and GeppiNode.hbm.xml were added in 
package de.webde.geppi in directory src/java.jbpm.

So far so good - Using the starter kits build file I could build and deploy the 
updated service archive.

But when starting the starter kit's JBoss I detected a strange error log on its 
console:

  | 13:57:26,300 INFO  [SchedulerThread] runtime exception while executing 
timers
  | org.hibernate.HibernateException: Could not parse configuration: 
hibernate.cfg.xml
  |         at 
org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1494)
  |         at 
org.hibernate.cfg.Configuration.configure(Configuration.java:1428)
  |         at 
org.jbpm.db.hibernate.HibernateHelper.createConfiguration(HibernateHelper.java:90)
  |         at 
org.jbpm.persistence.db.DbPersistenceServiceFactory.getConfiguration(DbPersistenceServiceFactory.java:68)
  |         at 
org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:90)
  |         at 
org.jbpm.persistence.db.DbPersistenceService.getSessionFactory(DbPersistenceService.java:74)
  |         at 
org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:78)
  |         at 
org.jbpm.persistence.db.DbPersistenceService.getSchedulerSession(DbPersistenceService.java:254)
  |         at org.jbpm.JbpmContext.getSchedulerSession(JbpmContext.java:529)
  |         at 
org.jbpm.scheduler.impl.SchedulerThread.executeTimers(SchedulerThread.java:104)
  |         at 
org.jbpm.scheduler.impl.SchedulerThread.run(SchedulerThread.java:71)
  | Caused by: org.dom4j.DocumentException: org.dom4j.DocumentFactory Nested 
exception: org.dom4j.DocumentFactory
  |         at org.dom4j.io.SAXReader.read(SAXReader.java:484)
  |         at 
org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1484)
  |         ... 10 more
  | 

To me a parsing exception looked odd since file hibernate.cfg.xml does not 
contain any syntax errors and the added line was correct.

To really find out what is going on I started a remote debugging session and 
discovered the following:

The root cause is a class cast exception I really do not understand:

  | ClassCastException: Cannot cast org.dom4j.DocumentFactory (id=169) to 
org.dom4j.DocumentFactory
  | 

It is originated in the static method getInstance() of class 
org.dom4j.DocumentFactory provided by the Dom4J library

  |     public static synchronized DocumentFactory getInstance() {
  |         if (singleton == null) {
  |             singleton = createSingleton();
  |         }
  |         return (DocumentFactory) singleton.instance();
  |     }
  | 

The class cast exception is thrown in the last line of this method. The stack 
trace looks like this:

  | Thread [JbpmCommandExecutor] (Suspended)    
  |     DocumentFactory.getInstance() line: 97  
  |     SAXReader.getDocumentFactory() line: 645        
  |     SAXReader.createContentHandler(XMLReader) line: 969     
  |     SAXReader.read(InputSource) line: 449   
  |     Configuration.doConfigure(InputStream, String) line: 1484       
  |     Configuration.configure(String) line: 1428      
  |     HibernateHelper.createConfiguration(String, String) line: 90    
  |     DbPersistenceServiceFactory.getConfiguration() line: 68 
  |     DbPersistenceServiceFactory.getSessionFactory() line: 90        
  |     DbPersistenceService.getSessionFactory() line: 74       
  |     DbPersistenceService.getSession() line: 78      
  |     DbPersistenceService.getMessagingSession() line: 245    
  |     JbpmContext.getMessagingSession() line: 521     
  |     DbMessageService.<init>() line: 49      
  |     DbMessageServiceFactory.openService() line: 32  
  |     Services.getService(String) line: 136   
  |     Services.getMessageService() line: 172  
  |     CommandExecutorThread.executeCommand() line: 122        
  |     CommandExecutorThread.run() line: 83    
  | 

Does anybody have an idea what exactly is going on here?
IMHO I think I got trapped in JBoss' class loader hell, but currently I have no 
clue how to solve this issue. I know I am guessing, but ...

Any help and hints are appreciated ... Thanks in advance ...

Cheers,
Ingo

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4025783#4025783

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4025783
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user

Reply via email to