5 Replies Latest reply on Jun 17, 2013 4:39 PM by gmlopezdev

    InvocationTargetException when creating StatefulKnowledgeSession

    tim.kutz

      Hello -

       

      I've been wrestling with this for about a day and a half, now.  My environment is jBPM 5.2.0.Final, running on JBoss 5.1.0.GA, with Java 1.5.0_12, under 64-bit Windows 7.  It's entirely possible that I am missing some portion of configuration, but I'm not able to determine what it is, exactly, that I'm missing.

       

      I am attempting to create a new StatefulKnowledgeSession, and start a process with it, using the JPAKnowledgeService, as described in the documentation.  The code I am using to do this is as follows:

       

      KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

      kbuilder.add(ResourceFactory.newClassPathResource("ImmunizationProcess.bpmn"), ResourceType.BPMN2);

      kbuilder.add(ResourceFactory.newClassPathResource("SchoolFormProcess.bpmn"), ResourceType.BPMN2);

      kbuilder.add(ResourceFactory.newClassPathResource("LegacySubscriptionProcess.bpmn"), ResourceType.BPMN2);

      kbuilder.add(ResourceFactory.newClassPathResource("SubscriptionMasterProcess.bpmn"), ResourceType.BPMN2);

       

        kBase = kbuilder.newKnowledgeBase();

       

        // create the entity manager factory and register it in the environment 

       

      EntityManagerFactory emf =     Persistence.createEntityManagerFactory( "org.jbpm.persistence.jpa" );

      env = KnowledgeBaseFactory.newEnvironment();

      env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

      env.set( EnvironmentName.TRANSACTION_MANAGER, jtaManager);

       

      kSession =  JPAKnowledgeService.newStatefulKnowledgeSession( kBase, null, env );

       

      When it reaches this last line, it throws an InvocationTargetException, which I've managed to narrow down to the constructor call on SingleSessionCommandService, which appears to not exist:

       

      Caused by: java.lang.reflect.InvocationTargetException

                at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

                at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

                at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

                at java.lang.reflect.Constructor.newInstance(Constructor.java:494)

                at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommandService(KnowledgeStoreServiceImpl.java:129)

                ... 85 more

       

      The persistence.xml I've put in place for the JPA persistence looks like this:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

        <persistence

        version="1.0"

        xsi:schemaLocation=

          "http://java.sun.com/xml/ns/persistence

           http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd

           http://java.sun.com/xml/ns/persistence/orm

           http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"

        xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xmlns="http://java.sun.com/xml/ns/persistence">

       

        <persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">

          <provider>org.hibernate.ejb.HibernatePersistence</provider>

          <jta-data-source>java:DefaultDS</jta-data-source>

          <mapping-file>META-INF/JBPMorm.xml</mapping-file>

          <class>org.drools.persistence.info.SessionInfo</class>

          <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>

          <class>org.drools.persistence.info.WorkItemInfo</class>

       

          <properties>

            <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>

            <property name="hibernate.max_fetch_depth" value="3"/>

            <property name="hibernate.hbm2ddl.auto" value="update"/>

            <property name="hibernate.show_sql" value="true"/>

            <property name="hibernate.transaction.manager_lookup_class"

                      value="org.hibernate.transaction.JBossTransactionManagerLookup"/>

          </properties>

        </persistence-unit>

      </persistence>

       

      Any and all help would be appreciated, and I can provide additional information if needed.

        • 1. Re: InvocationTargetException when creating StatefulKnowledgeSession
          swiderski.maciej

          Could you paste complete stack trace that is produced when you run it?

           

          another question, what is jtaManager - do you look it up from JBoss AS JNDI?

           

          Cheers

          • 2. Re: InvocationTargetException when creating StatefulKnowledgeSession
            tim.kutz

            jtaManager is the JBoss TransactionManager (arjuna).  It's injected, as the class where the above code lives is actually an MBean.

             

            I've made some - limited - progress with this.  It appears that the JPAKnowledgeService doesn't like to participate in an existing JTA transaction.  By marking the method with @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED), I am able to get a session created within a UserTransaction.  The code now looks like this:

             

            UserTransaction txn = retrieveTransaction();

            txn.begin();

            kSession =

                JPAKnowledgeService.newStatefulKnowledgeSession( kBase, null, env );

            kSession.getWorkItemManager().registerWorkItemHandler("ValidationService", new ValidationTaskWorkItemHandler());

            kSession.getWorkItemManager().registerWorkItemHandler("SubscriptionEventUpdateService", new SubscriptionHistoryWorkItemHandler());

            kSession.getWorkItemManager().registerWorkItemHandler("ImmunizationService", new JMSWorkItemHandler());

            kSession.getWorkItemManager().registerWorkItemHandler("SchoolFormService", new JMSWorkItemHandler());

            kSession.getWorkItemManager().registerWorkItemHandler("LegacySubscriptionService", new JMSWorkItemHandler());

             

            I'm not thrilled about having to deal with UserTransaction, though.  Isn't this supposed to support standard managed transactions?  Is there something additional I need to provide to the env for it to participate normally?

            • 3. Re: InvocationTargetException when creating StatefulKnowledgeSession
              tim.kutz

              For a bit more info, it seems that the issue with transaction participation is peculiar to the newStatefulKnowledgeSession() call.  When loading one from the database with JPAKnowledgeService.loadStatefuleKnowledgeSession(), it participates normally, and wrapping the UserTransaction around it causes issues, instead.  Having to work with transactions in different modes like this really is bad for maintenance, as it adds a level of complexity to the whole system.  I wasn't able to find anything in the Jira issues about this, is it a known issue already?  I should be able to provide a unit test to replicate it without much effort, if that would help.

              • 4. Re: InvocationTargetException when creating StatefulKnowledgeSession
                swiderski.maciej

                I agree that transaction management should be first of all consistent across invocations of new session and loading from data store and should support joining transactions. As you mentioned it runs in MBean do you see same behaviour in regular let's say web application?

                I will try to find some time to look into that but can't promise when it will happen

                • 5. Re: InvocationTargetException when creating StatefulKnowledgeSession
                  gmlopezdev

                  I'm facing the same issue with jBPM 5.4. Have anyone got any workaround about it?

                   

                  Thanks!