1

I would like to know if it's prohibited to use an EJB in an infinite thread(since it can't be given back to the container).

Something like this:

@ManagedBean(eager = true)
@ApplicationScoped
public class TestListenner {

    private ResultThread result;

    @PostConstruct
    public void init() {
        result = new ResultThread ();
        Thread myThread = new Thread(result);
        myThread.start();
    }
    public ResultThread getResult() {
        return result;
    }
}

And the thread:

public class ResultThread implements Runnable{
    @EJB
    private SomeService service;
    private boolean continueWork = true;

    public void run(){
        while(continueWork){
            service.doSomething();
            //some proccessing
        }
    }

I'm working with EJB's since I started working with databases. I went over daofactories and the likes but I forgot about them(it was a year ago). I use them to do actions on my database when an user request a web page on my web app. But now I need to have a thread that calculate things in my database continuously to decrease the response time. If I cannot use EJB for the reason the container needs to have an handle on them, then what should I use ?

Hopefully I can use a class similar to what I'm used to use :

@Stateless
public class SomeServiceImpl implements SomeService {
    @PersistenceContext(unitName = "my-pu")
    private EntityManager em;

    @Override
    public void updateCategory(SomeClass theclass) {
        em.merge(theclass);
    }
}

Edit: The first answer by BalusC in this topic seems to imply that spawning threads in a ManagedBean wouldn't be dangerous in a case where no additional threads could be spawned. Since my bean is ApplicationScoped, which the web-app uses 1 and only 1 instance of it to do background work on the database (I've actually like a TOP 100 "posts" table that needs to be continually recalculated over time so I can query the table -with another bean- to have a fast answer).

Community
  • 1
  • 1
Ced
  • 15,847
  • 14
  • 87
  • 146

2 Answers2

3

What you have now won't work for at least one reason:

You can't inject resources into non-managed components. For the @EJB annotation to work, ResultThread ought to be a managed bean, and injected by the container. That means, that you must at least use CDI to inject it, rather than the new ResultThread you have now. What will work will look something like:

@Inject
private ResultThread result;

This way, the container gets in on the action.

The bottom line however, is that there are better ways of doing what you appear to be trying to do.

It may also interest you to know that EJBs are not allowed to spawn their own threads; in fact, it's frowned upon to do any handmade threading in the container. Why? The container is a managed environment - one where memory and concurrency have already been well thought out and designed. Your handspun thread breaks that model and any guarantees that the container may have been able to give you on your beans and other app components

Related:

Community
  • 1
  • 1
kolossus
  • 20,559
  • 3
  • 52
  • 104
  • 2
    >EJBs are not allowed to spawn their own threads - as an historical note; the intend was actually not just EJBs, but the entire Java EE server. At the time the thinking was however that EJB was or would become the groundwork of everything Java EE, including Servlets. That never happened, so now (too many) people think that specifically EJB is not allowed to use threads, but all other component kinds are fine, which was as said never the intention. – Arjan Tijms Jul 29 '15 at 07:08
  • @kolossus Thanks for the answer, I made it work using asynchronous anotation in my stateless ejb and call it in my applicationScoped bean. I've made an edit to my post at the bottom that shows an answer from balusC that kinda confused me a bit and I doubt I'll be the only one (because some say it shouldn't be done but he says it can be), so yeh mayby account for that. I've 1 question though : I'll rely on this "thread" containing a while(true) loop(sort of) working as long as my web-app will be running. There won't be any hiccups right, it definitely won't stop for any reason ? – Ced Jul 29 '15 at 07:48
  • Thanks for the note @ArjanTijms; I should have been clearer: I don't believe that spawning a thread anywhere in the container is kosher(mostly because I'm lazy ha), but yeah, that could have been worded differently – kolossus Jul 29 '15 at 11:37
  • It won't "stop", but you're opening up a hole in your VM for little benefit. Nothing in Balusc's answer endorses a handspun Thread, in fact he states quite clearly that your mustn't do that. The theme here, is that there's very little chance that you're going to be able to properly manage a thread by yourself without side effects to *the rest of the application*. – kolossus Jul 29 '15 at 11:42
1

You can't use your own Threads on Java EE container.

http://www.oracle.com/technetwork/java/restrictions-142267.html#threads

The Java EE spec provide TimerServices for this kind of work.

https://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html

Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Ernesto Campohermoso
  • 7,213
  • 1
  • 40
  • 51