cancel
Showing results for 
Search instead for 
Did you mean: 

Intermittent issues with JuelExpression

hburgett
Champ in-the-making
Champ in-the-making
Hi,

I have been getting intermittent exceptions from the Activiti Engine that look like the following (complete stack trace shortened for brevity):

org.activiti.engine.ActivitiException: Error while evalutaing expression
   at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:52)
   at org.activiti.engine.impl.bpmn.listener.ExpressionExecutionListener.notify(ExpressionExecutionListener.java:35)
   at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:38)
   at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:76)
   at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:481)
   at org.activiti.engine.impl.persistence.entity.ExecutionEntity.start(ExecutionEntity.java:280)
   at org.activiti.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:70)
   at org.activiti.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:30)
   at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
   at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
   at org.activiti.engine.impl.RuntimeServiceImpl.startProcessInstanceByKey(RuntimeServiceImpl.java:49)
Caused by: org.activiti.engine.impl.javax.el.ELException: Invalid expression factory class: org.activiti.engine.impl.juel.ExpressionFactoryImpl
   at org.activiti.engine.impl.javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:206)
   at org.activiti.engine.impl.javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:183)
   at org.activiti.engine.impl.javax.el.ExpressionFactory.newInstance(ExpressionFactory.java:89)
   at org.activiti.engine.impl.javax.el.BeanELResolver.getExpressionFactory(BeanELResolver.java:527)
   at org.activiti.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:479)
   at org.activiti.engine.impl.javax.el.CompositeELResolver.invoke(CompositeELResolver.java:397)
   at org.activiti.engine.impl.juel.AstMethod.invoke(AstMethod.java:91)
   at org.activiti.engine.impl.juel.AstMethod.eval(AstMethod.java:75)
   at org.activiti.engine.impl.juel.AstEval.eval(AstEval.java:50)
   at org.activiti.engine.impl.juel.AstNode.getValue(AstNode.java:26)
   at org.activiti.engine.impl.juel.TreeValueExpression.getValue(TreeValueExpression.java:114)
   at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:46)
   … 26 more

The BPMN script is executed within a thread inside a JBoss AS 5.1 WAR during a JMS onMessage() operation.

Thanks!
3 REPLIES 3

hburgett
Champ in-the-making
Champ in-the-making
I am running this in a web app (WAR) using JBoss AS 5.1.  I noticed that JBoss comes with a el-api.jar containing classes like javax.el.ExpressionFactory.  Could this some strange classloader issue?

hburgett
Champ in-the-making
Champ in-the-making
Solution:

JBoss AS 5.1 executes the JMS onMessage() operation using the classloader of the message sender, not the web context classloader of the receiver.  This results in the exception above because the org.activiti.engine.impl.javax.el.ExpressionFactory.newInstance() method does a type check using Class.isAssignableFrom(), and the 2 types it is comparing come from 2 different class loaders, so the comparison fails.

Bottom Line:  make sure the classloader used to execute Activiti inside a JBoss WAR does not get switched when responding to JMS messages.

My workaround was to assign the classloader manually in my JMS listener:


    @Override
    public void onMessage(Message msg)
    {
        if (msg instanceof TextMessage)
        {
            ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
           
            try
            {
                String xml = ((TextMessage) msg).getText();

                Thread.currentThread().setContextClassLoader( this.getClass().getClassLoader() );

                 doActivitiStuff();

            }
            catch (JMSException e)
            {
                e.printStackTrace();
            }
            finally
            {
                Thread.currentThread().setContextClassLoader( originalCL );
            }
        }
    }

trademak
Star Contributor
Star Contributor
I would recommend to take a look at the camunda fox platform, which provides native integration of the Activiti Engine in JBoss.

Best regards,