2 Replies Latest reply on Oct 22, 2013 12:53 PM by nicolas duminil

    Can't activate/passivate SFSB containing JPAKnowledgeSession

    nicolas duminil Master

      Greetings,

       

      I'm using Drools 5.5 with JBoss SOA-P 5.3.1. I have a SFSB which receives facts that it adds to a knowledge session. And in order to persist the sesion context, I use a JPA knowledge session. Every thing seems to work fine until the SFSB gets passivated. Then very verbose exceptions are raised like:

       

      2013-10-18 14:33:24,431 FATAL [org.jboss.serial.persister.RegularObjectPersister] (SFSB Passivation Thread - jboss.j2ee:ear=drools-persistence-ear-0.0.1-SNAPSHOT.ear,jar=drools-persistence-facade-0.0.1-SNAPSHOT.jar,name=DroolsFacadeBean,service=EJB3) error

      java.lang.reflect.InvocationTargetException

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

          at java.lang.reflect.Method.invoke(Method.java:601)

          at org.jboss.serial.persister.RegularObjectPersister.writeSlotWithMethod(RegularObjectPersister.java:122)

          at org.jboss.serial.persister.RegularObjectPersister.defaultWrite(RegularObjectPersister.java:88)

          at org.jboss.serial.persister.RegularObjectPersister.writeData(RegularObjectPersister.java:64)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:276)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)

          at org.jboss.serial.persister.RegularObjectPersister.writeSlotWithFields(RegularObjectPersister.java:189)

          at org.jboss.serial.persister.RegularObjectPersister.defaultWrite(RegularObjectPersister.java:92)

          at org.jboss.serial.persister.RegularObjectPersister.writeData(RegularObjectPersister.java:64)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:276)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)

          at org.jboss.serial.persister.RegularObjectPersister.writeSlotWithFields(RegularObjectPersister.java:189)

          at org.jboss.serial.persister.RegularObjectPersister.defaultWrite(RegularObjectPersister.java:92)

          at org.jboss.serial.persister.RegularObjectPersister.writeData(RegularObjectPersister.java:64)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.describeObject(ObjectDescriptorFactory.java:276)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectOutput.writeObject(DataContainer.java:206)

          at org.jboss.serial.persister.ObjectOutputStreamProxy.writeObjectOverride(ObjectOutputStreamProxy.java:60)

          at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:342)

          at java.util.HashSet.writeObject(HashSet.java:284)

       

      I stop here as the stack trace is huge. But here I see that a HashSet is to be serialized, which is not possible as the HashSet is not serializable.

       

      Here is the code:

       

      @Stateful

      @TransactionAttribute(TransactionAttributeType.REQUIRED)

      @CacheConfig(idleTimeoutSeconds=30)

      public class DroolsFacadeBean implements DroolsFacadeLocal, DroolsFacadeRemote

      {

        private EntityManagerFactory emf;

        private EntityManager em;

        private static Logger logger = LoggerFactory.getLogger(DroolsFacadeBean.class);

        private KnowledgeBase kbase;

        private StatefulKnowledgeSession ksession;

        private Environment env;

        private KnowledgeBuilder kbuilder;

       

        @Override

        public void insertEnvelopeIntoKS(Envelope envelope) throws Exception

        {

          ksession.insert(envelope);

          ksession.fireAllRules();

        }

       

        @PostConstruct

        @Override

        public void initialize()

        {

          initializeKB();

          ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

        }

       

        @PostActivate

        @Override

        public void recover()

        {

          initializeKB();

          SessionInfo si =

              (SessionInfo)em.createQuery("select si from sessioninfo si where si.startDate = (select max(ssi.startDate) from sessioninfo ssi where si.id = ssi.id)")

              .getSingleResult();

          ksession = si != null ?

              JPAKnowledgeService.loadStatefulKnowledgeSession(si.getId(), kbase, null, env) :

              JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env);

        }

       

        private void initializeKB()

        {

          emf = Persistence.createEntityManagerFactory("DroolsPersistence");

          em = emf.createEntityManager();

          env = KnowledgeBaseFactory.newEnvironment();

          env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);

          env.set(EnvironmentName.GLOBALS, new MapGlobalResolver());

          kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();

          kbuilder.add(new ClassPathResource("derivative2.drl", getClass()), ResourceType.DRL);

          if (kbuilder.hasErrors())

          {

            if (kbuilder.getErrors().size() > 0)

              for (KnowledgeBuilderError kerror : kbuilder.getErrors())

                logger.error(kerror.getMessage());

            throw new RuntimeException("### Unexpected KnowledgeSession errors. Please see the log file.");

          }

          kbase = kbuilder.newKnowledgeBase();

        }

      }

       

      After different tests I came to the conclusion that the KnowledgeBuilder is at the origin of the problem. Hence if I declare it as transient I don't have any exception at the passivation time. But after the SFSB has been passivated, sending a new request doesn't succeed to activate it and the exception raised is the following:

       

      .................................

      Caused by: java.lang.reflect.InvocationTargetException

          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

          at java.lang.reflect.Method.invoke(Method.java:601)

          at org.jboss.soa.esb.actions.EJBProcessor.invoke(EJBProcessor.java:466)

          at org.jboss.soa.esb.actions.EJBProcessor.process(EJBProcessor.java:193)

          ... 13 more

      Caused by: javax.ejb.EJBException: java.lang.RuntimeException: org.jboss.serial.exception.SerializationException: Could not create instance of org.drools.command.impl.CommandBasedStatefulKnowledgeSession - org.drools.command.impl.CommandBasedStatefulKnowledgeSession

          at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:77)

          at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)

          at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke(RoleBasedAuthorizationInterceptorv2.java:201)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:182)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:67)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.core.context.CurrentInvocationContextInterceptor.invoke(CurrentInvocationContextInterceptor.java:47)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.interceptor.EJB3TCCLInterceptor.invoke(EJB3TCCLInterceptor.java:86)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:193)

          at org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:250)

          at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:188)

          at $Proxy893.insertEnvelopeIntoKS(Unknown Source)

          ... 19 more

      Caused by: java.lang.RuntimeException: org.jboss.serial.exception.SerializationException: Could not create instance of org.drools.command.impl.CommandBasedStatefulKnowledgeSession - org.drools.command.impl.CommandBasedStatefulKnowledgeSession

          at org.jboss.ejb3.stateful.StatefulBeanContext.extractBeanAndInterceptors(StatefulBeanContext.java:935)

          at org.jboss.ejb3.stateful.StatefulBeanContext.postActivate(StatefulBeanContext.java:488)

          at org.jboss.ejb3.cache.simple.StatefulSessionFilePersistenceManager.activateSession(StatefulSessionFilePersistenceManager.java:324)

          at org.jboss.ejb3.cache.simple.SimpleStatefulCache$1.call(SimpleStatefulCache.java:494)

          at org.jboss.ejb3.cache.simple.SimpleStatefulCache$1.call(SimpleStatefulCache.java:483)

          at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)

          at java.util.concurrent.FutureTask.run(FutureTask.java:166)

          at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:526)

          at org.jboss.ejb3.cache.simple.SimpleStatefulCache.get(SimpleStatefulCache.java:435)

          at org.jboss.ejb3.stateful.StatefulInstanceInterceptor.invoke(StatefulInstanceInterceptor.java:59)

          at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)

          at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)

          ... 43 more

      Caused by: org.jboss.serial.exception.SerializationException: Could not create instance of org.drools.command.impl.CommandBasedStatefulKnowledgeSession - org.drools.command.impl.CommandBasedStatefulKnowledgeSession

          at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:342)

          at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:256)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)

          at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:376)

          at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:290)

          at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:258)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)

          at org.jboss.serial.persister.ArrayPersister.readObjectArray(ArrayPersister.java:196)

          at org.jboss.serial.persister.ArrayPersister.readData(ArrayPersister.java:172)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)

          at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)

          at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:643)

          at org.jboss.serial.io.JBossObjectInputStream.readObjectOverride(JBossObjectInputStream.java:163)

          at java.io.ObjectInputStream.readObject(ObjectInputStream.java:363)

          at org.jboss.serial.io.MarshalledObject.get(MarshalledObject.java:68)

          at org.jboss.ejb3.stateful.StatefulBeanContext.extractBeanAndInterceptors(StatefulBeanContext.java:906)

          ... 54 more

      Caused by: java.lang.InstantiationException: org.drools.command.impl.CommandBasedStatefulKnowledgeSession

          at java.lang.Class.newInstance0(Class.java:357)

          at java.lang.Class.newInstance(Class.java:325)

          at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:334)

          ... 73 more

       

      What could be the cause of this and how could I manage to handle knowledge sessions in SFSB while avoiding this passivation/activation problems ?

       

      Many thanks in advance,

       

      Nicolas