Can't activate/passivate SFSB containing JPAKnowledgeSession
simplex-software Oct 21, 2013 7:00 AMGreetings,
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