Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java EE 7 - Injection into Runnable/Callable object

Concurrency Utilities(JSR 236) has been introduced in Java EE 7.

Is there any way how to inject my EJBs into Runnable/Callable object?

Specifically I want something like this:

ejb with business logic

@LocalBean
public class MyEjb {
    public void doSomeStuff() {
        ... do some stuff ...
    }
}

runnable/callable class where I want to inject instance of MyEjb

public class MyTask implements Runnable {
    @EJB
    MyEjb myEjb;

    @Override
    public void run() {
        ...
        myEjb.doSomeStuff();
        ...
    }
}

Object which starts the new task

@Singleton
@Startup
@LocalBean
public class MyTaskManager {
    @Resource
    ManagedExecutorService executor;

    @PostConstruct
    void init() {
        executor.submit(new MyTask());
    }
}

myEjb field in MyTask is always null. I suppose there could help JNDI lookup, but is there any proper way how to do this?

like image 377
madox2 Avatar asked Jan 12 '14 18:01

madox2


2 Answers

You have to give the container a chance to inject the EJB into your Task instance. You can do this by using a dynamic instance like in this code:

@Stateless
public class MyBean {
    @Resource
    ManagedExecutorService managedExecutorService;
    @PersistenceContext
    EntityManager entityManager;
    @Inject
    Instance<MyTask> myTaskInstance;

    public void executeAsync() throws ExecutionException, InterruptedException {
    for(int i=0; i<10; i++) {
        MyTask myTask = myTaskInstance.get();
        this.managedExecutorService.submit(myTask);
    }
}

Because you don't create the instance with the new operator but rather over CDI's instance mechanism, the container prepares each instance of MyTask when calling myTaskInstance.get().

like image 163
siom Avatar answered Nov 15 '22 23:11

siom


The EJB can not be injected if the MyTask instance is created by you because the Container knows only instances created by itself. Instead you can inject the EJB in the MyTaskManager Singleton SB and define your MyTask Runnable class as innerclass as follow:

@Singleton
@Startup
@LocalBean
public class MyTaskManager {
    @Resource
    ManagedExecutorService executor;

    @EJB
    MyEjb myEjb;

    @PostConstruct
    void init() {
        executor.submit(new MyTask());
    }

    class MyTask implements Runnable {
        @Override
        public void run() {
            ...
            myEjb.doSomeStuff();
            ...
        }
    }
}
like image 31
Marco Montel Avatar answered Nov 15 '22 21:11

Marco Montel