cancel
Showing results for 
Search instead for 
Did you mean: 

activiti-cdi, injection, JavaDelegate

chris_joelly
Champ in-the-making
Champ in-the-making
Hello,

i try to inject beans into an JavaDelegate, but it seems that it does not work. I assume this is because JavaDelegate instances are not managed beans and thus CDI does not intercept their life cycle?

Is the lookup of beans via JNDI the only possibility to use resources from the JEE server within JavaDelegates?

thanks, Chris
6 REPLIES 6

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Have you tried making them managed and use expressions to call tem instead of via class name? Injection might work then…

meyerd
Champ on-the-rise
Champ on-the-rise
Hi chris.joelly,

to step on Ronald's point:

you can invoke a cdi bean directly form a bpmn process. Make sure to make it a @Named bean:


@Named
public void PaymentProcessor {
 
  @Inject
  private PaymentProcessingLogic businessLogic;

  @PersistenceContext
  private EntityManager em;

  public void processPayment() {
  …
  }
}

then your bpmn would look like this:


<serviceTask … activiti:expression="paymentProcessor.processPayment()" />

This way the instance of the PaymentProcessor class is constructed by CDI and not by activiti and can thus use CDI services like injection, interceptors ect. You can even inject other EE resources like a JPA entity manager as demonstrated above.

Note 1: you can also implement JavaDelegate. then you use activiti:delegateExpression="paymentProcessor"

Note 2: you can also use an EJB, make sure to annotate it with @Named

Note 3: if you add no scope annotation, the bean is implicitly @Dependent scoped -> new instance is constructed for each service invocation. You could use @ApplicationScoped to make it a singleton and so forth. Note that you cannot use something like @RequestScoped or @SessionScoped if we are called from the activiti job executor.

ronald_van_kuij
Champ on-the-rise
Champ on-the-rise
Thanks Daniel. Long responses like these are hard for me to do on a mobile phone in a crowded Dutch train…  Smiley Wink

chris_joelly
Champ in-the-making
Champ in-the-making
Hello Ronald, hello Daniel,

thanks for your support. Due to Ronalds suggestion i tried to get it working, i tried the following things:


public abstract class AbstractServiceTask implements JavaDelegate {

public AbstractServiceTask() { super(); }

protected EntityManager getEntityManager() {
  EntityManager em = null;
  try {
   Context ic = new InitialContext();
   em = (EntityManager) ic.lookup("java:comp/env/persistence/em");
  } catch (NamingException e) {
// TODO
  }
  return em;
}
}


@Named
public class SimpleServiceTask extends AbstractServiceTask {

@Inject
@ErpEntityManager
private EntityManager emCDI;

@PersistenceUnit
private EntityManagerFactory emfJEE;

@PersistenceContext
private EntityManager emJEE;

public void execute(DelegateExecution execution) throws Exception {
  TestEntity entity = new TestEntity();
  entity.setCol((String)execution.getVariable("col"));
  emCDI.persist(entity);
//  emJEE.persist(entity);
//  getEntityManager().persist(entity);
}

}

with the following producer:


@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ErpEntityManager {
}


@Singleton
public class ErpEntityManagerProducer {
@Produces
@PersistenceContext
@ErpEntityManager
private EntityManager em;
}

But i get the following results:

when using activiti:class="…SimpleServiceTask", activiti:delegateExpression="${simpleServiceTask}" or activiti:expression="${simpleServiceTask.execute(execution)}" nothing is injected into the simpleServiceTask. emfJEE and emJEE which uses @Persistence* annotations remain null. Only emCDI references a bean which seems to be a delegate or proxy (org.jboss.weldx.persistence.EntityManager$-1697665317$Proxy$_$$_Weld$Proxy$), but using the reference with .persist() results in a null pointer exception:


org.jboss.weld.exceptions.NullInstanceException: WELD-000044 Unable to obtain instance from null
at org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:48)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
at org.jboss.weldx.persistence.EntityManager$-1697665317$Proxy$_$$_Weld$Proxy$.persist(EntityManager$-1697665317$Proxy$_$$_Weld$Proxy$.java)
at erp.domain.activiti.tasks.service.SimpleServiceTask.execute(SimpleServiceTask.java:46)
at org.activiti.engine.impl.delegate.JavaDelegateInvocation.invoke(JavaDelegateInvocation.java:34)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.cdi.impl.CdiProcessVariableFlushingDelegateInterceptor.handleInvocation(CdiProcessVariableFlushingDelegateInterceptor.java:36)
at org.activiti.engine.impl.bpmn.behavior.ServiceTaskDelegateExpressionActivityBehavior.execute(ServiceTaskDelegateExpressionActivityBehavior.java:61)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)

And finally, looking up the entity manager using JNDI does not work either Smiley Happy

On the JSF side i can use CDI without problems, with @Produces, @Resource, @Inject in all combinations.

Which leaves me with the big question mark above my head…

chris_joelly
Champ in-the-making
Champ in-the-making
the exception which is thrown is:

org.activiti.engine.ActivitiException: Error while evalutaing expression
at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:59)
at org.activiti.engine.impl.bpmn.behavior.ServiceTaskExpressionActivityBehavior.execute(ServiceTaskExpressionActivityBehavior.java:39)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:44)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerStart.java:52)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionCreateScope.execute(AtomicOperationTransitionCreateScope.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerTake.execute(AtomicOperationTransitionNotifyListenerTake.java:65)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:115)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerEnd.java:36)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:113)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerEnd.java:36)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:77)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:530)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:525)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.take(ExecutionEntity.java:365)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.takeAll(ExecutionEntity.java:460)
at org.activiti.engine.impl.bpmn.behavior.BoundaryEventActivityBehavior.execute(BoundaryEventActivityBehavior.java:57)
at org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler.execute(TimerExecuteNestedActivityJobHandler.java:48)
at org.activiti.engine.impl.persistence.entity.JobEntity.execute(JobEntity.java:78)
at org.activiti.engine.impl.persistence.entity.TimerEntity.execute(TimerEntity.java:62)
at org.activiti.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:67)
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.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:59)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
at org.activiti.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.activiti.engine.impl.javax.el.ELException: org.jboss.weld.exceptions.NullInstanceException: WELD-000044 Unable to obtain instance from null
at org.activiti.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:481)
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.delegate.ExpressionGetInvocation.invoke(ExpressionGetInvocation.java:33)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.cdi.impl.CdiProcessVariableFlushingDelegateInterceptor.handleInvocation(CdiProcessVariableFlushingDelegateInterceptor.java:36)
at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:50)
… 59 more
Caused by: org.jboss.weld.exceptions.NullInstanceException: WELD-000044 Unable to obtain instance from null
at org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:48)
at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:105)
at org.jboss.weldx.persistence.EntityManager$-1697665317$Proxy$_$$_Weld$Proxy$.persist(EntityManager$-1697665317$Proxy$_$$_Weld$Proxy$.java)
at erp.domain.activiti.tasks.service.simple2Form.Simple2FormCorrCheck.execute(Simple2FormCorrCheck.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.activiti.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:479)
… 69 more

chris_joelly
Champ in-the-making
Champ in-the-making
a little update to this issue:

if i annotate the SimpleServiceTask with @javax.ejb.Stateless and use it with an activiti:expression or activiti:delegateExpression then injection of an entity manager works, and so does injection of EJBs. But CDI injection does not work:

@Inject
HistoryService historyService.

So it seems that everything which is an EJB works with injection, but everything which is just using CDI seems to not work correctly.