Uploaded image for project: 'JBRULES'
  1. JBRULES
  2. JBRULES-3067

Error creating org.drools.persistence.PersistenceContextManager in org.drools.persistence.SingleSessionCommandService in a Spring environment

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None
    • Environment:

      I observed the problem in Drools 5.2.0.M1 and 5.2.0.CR1. Spring version is 2.5.6.

      Description

      org.drools.persistence.SingleSessionCommandService throws a NullPointerException during the application startup. As described in the environment section the application uses Drools 5.2.0.CR1 and Spring 2.5.6. Drools configuration is created in a Spring xml file:

      	<drools:kbase id="knowledgeBase">
        <drools:resources>
          <drools:resource type="BPMN2" source="..." />
        </drools:resources>
      </drools:kbase>
      
      <drools:ksession id="knowledgeSession" kbase="knowledgeBase" type="stateful">
        <drools:configuration>
          <drools:jpa-persistence>
            <drools:entity-manager-factory ref="entityManagerFactory" />
            <drools:transaction-manager ref="transactionManager" />
          </drools:jpa-persistence>
        </drools:configuration>
      </drools:ksession>
      

      Releated EntityManagerFactory and TransactionManager declarations are as follows:

      <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
        <property name="jpaVendorAdapter">
          <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>
      </bean>
      
      <tx:jta-transaction-manager />
      

      The related stack trace is as follows:

      Caused by: java.lang.IllegalStateException: java.lang.reflect.InvocationTargetException
      	at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommanService(KnowledgeStoreServiceImpl.java:130)
      	at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.newStatefulKnowledgeSession(KnowledgeStoreServiceImpl.java:54)
      	at org.drools.persistence.jpa.JPAKnowledgeService.newStatefulKnowledgeSession(JPAKnowledgeService.java:109)
      	at org.drools.container.spring.beans.StatefulKnowledgeSessionBeanFactory.internalAfterPropertiesSet(StatefulKnowledgeSessionBeanFactory.java:82)
      	at org.drools.container.spring.beans.AbstractKnowledgeSessionBeanFactory.afterPropertiesSet(AbstractKnowledgeSessionBeanFactory.java:108)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
      	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
      	... 30 more
      Caused by: java.lang.reflect.InvocationTargetException
      	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:44)
      	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
      	at java.lang.reflect.Constructor.newInstance(Constructor.java:516)
      	at org.drools.persistence.jpa.KnowledgeStoreServiceImpl.buildCommanService(KnowledgeStoreServiceImpl.java:116)
      	... 36 more
      Caused by: java.lang.RuntimeException: Could not commit session
      	at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:136)
      	... 41 more
      Caused by: java.lang.NullPointerException
      	at org.drools.persistence.SingleSessionCommandService.<init>(SingleSessionCommandService.java:125)
      

      The problem is also discussed in the forum in this thread: http://community.jboss.org/message/595927#595927 The actual problem is caused by the line 232 in org.drools.persistence.SingleSessionCommandService:

      if ( tm.getClass().getName().toLowerCase().contains( "jpa" ) ) {
      

      Now, if Spring is configured to use a JpaTransactionManager there is no problem. However, if a JtaTransactionManager is used, which I believe is the usual case, it is ignored and no PersistenceContextManager is created which causes the NPE on line 125:

      jpm.getApplicationScopedPersistenceContext().persist( this.sessionInfo );
      

      To fix the problem I, currently, use a modified version of the org.drools.container.spring.beans.StatefulKnowledgeSessionBeanFactory which creates an org.drools.runtime.Environment as follows:

      DroolsSpringTransactionManager dstm = new DroolsSpringTransactionManager((AbstractPlatformTransactionManager) jpaConfiguration.getPlatformTransactionManager());
      Environment env = KnowledgeBaseFactory.newEnvironment();
      env.set(EnvironmentName.ENTITY_MANAGER_FACTORY,	jpaConfiguration.getEntityManagerFactory());
      env.set(EnvironmentName.TRANSACTION_MANAGER, dstm);
      env.set(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES, new ObjectMarshallingStrategy[] { new SerializablePlaceholderResolverStrategy(ClassObjectMarshallingStrategyAcceptor.DEFAULT) });
      DroolsSpringJpaManager dsjm = new DroolsSpringJpaManager(env);
      env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, dsjm);
      

      This creates a PersistenceContextManager which uses the correct JtaTransactionManager. This way I have no problems.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                mark.proctor Mark Proctor
                Reporter:
                pbezek Perit Bezek
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated: