This discussion is archived
7 Replies Latest reply: Nov 19, 2012 12:10 PM by gimbal2 RSS

Calling EJB from a work manager

user2695214 Newbie
Currently Being Moderated
I've created a commonj work manager that runs periodically. In the work manager I am calling from EJB/DAO classes to execute some queries and insert data in to a database. My implementation is working in my development environment, however I am afraid that I have done something that will fail in the long term.

For most of my code, I am using dependency injection to create the DAO classes.

something like this:

@Stateless
public class MyStartupClass {
@EJB
private MyDAO myDAO;
...
}

This does not seem to work when I create my work manager. as myDAO is always null in the following
public class MyWork implements Work
@EJB
private MyDAO myDAO;
...
}

To work around this I have put myDAO as a parameter in the MyWork constructor:
public MyWork(MyDAO myDAO)
{
this.myDAO = myDAO;
}

This seems to be a viable work around, but are there any issues of doing it this way in the long run? For example, is it possible that the myDAO object will be cleaned up or destroyed while processing MyWork. My thought is that myDAO was created with dependency injection into another class (MyStartupClass and not MyWork).

Is this the correct way of calling EJB/DAO classes from work managers or is the a better way of injecting EJB classes into work managers?

Thanks,
  • 1. Re: Calling EJB from a work manager
    Kayaman Guru
    Currently Being Moderated
    user2695214 wrote:
    This seems to be a viable work around, but are there any issues of doing it this way in the long run? For example, is it possible that the myDAO object will be cleaned up or destroyed while processing MyWork. My thought is that myDAO was created with dependency injection into another class (MyStartupClass and not MyWork).

    Is this the correct way of calling EJB/DAO classes from work managers or is the a better way of injecting EJB classes into work managers?
    It seems that your work manager class is not a managed bean of any sort, that's why the injection also fails. You could make your work manager class a @ManagedBean, that'd probably be the best move.
    However, if you do pass the DAO through the constructor, there is no risk. It won't magically disappear or stop working.
  • 2. Re: Calling EJB from a work manager
    gimbal2 Guru
    Currently Being Moderated
    Kayaman wrote:
    However, if you do pass the DAO through the constructor, there is no risk. It won't magically disappear or stop working.
    It will probably work, but it isn't really how EJBs were designed. The container is there to manage instances to EJBs, when you start passing them to the constructor of a non-managed class, implying it will be assigned to a class member for later use, you're inviting resource leaks. Might be that the reference just sticks forever preventing the EJB instance to actually be returned to the container's control at some point.

    If you want to use an EJB in a class that is not managed by the container you can always look it up through the JNDI context the moment you need it. That would be my advise to do, but I can't really say how to do it because that depends on the version of JEE being used (JEE 5 or JEE 6) and which container is being used. A google search for "java ejb jndi lookup" will probably provide the code you need.
  • 3. Re: Calling EJB from a work manager
    Kayaman Guru
    Currently Being Moderated
    Oops, you're right. I missed the DAO being an EJB. That should definitely be fetched from JNDI, or better yet, make the worker a managed bean (providing high enough Java EE level).
  • 4. Re: Calling EJB from a work manager
    gimbal2 Guru
    Currently Being Moderated
    Kayaman wrote:
    Oops, you're right. I missed the DAO being an EJB. That should definitely be fetched from JNDI, or better yet, make the worker a managed bean (providing high enough Java EE level).
    Well that would depend on how the instance of this worker is constructed of course. If it is part of some grander framework / technology stack then it might not be possible to turn it into an EJB.
  • 5. Re: Calling EJB from a work manager
    user2695214 Newbie
    Currently Being Moderated
    Thanks to everyone who replied. I really didn't think this would be so difficult. Here's a summary of my issue at this point:

    1 - I can't do a JNDI look up because I want a generic solution and the JNDI names for EJB seem to be container specific.
    2 - I can't use @ManagedBean to make the work manager managed because I need to support JAVA EE 5

    Anyone know if there is simple way in java EE 5 to make the work manager class into a managed bean?

    Is there another way of getting an instance of an EJB/DAO in my non-managed work manager class that is not container specific?

    Thanks again!
  • 6. Re: Calling EJB from a work manager
    r035198x Pro
    Currently Being Moderated
    If you are stuck with EE5 then you can't get away from non portable EJB JNDI names.
    Consider a service locator pattern with implementations for all the containers you intend to support and pick the service locator implementation to use from some portable location (e.g properties file on the container's classpath), this just moves the selection to one point of non portability.
  • 7. Re: Calling EJB from a work manager
    gimbal2 Guru
    Currently Being Moderated
    user2695214 wrote:
    Thanks to everyone who replied. I really didn't think this would be so difficult.
    Its mostly difficult because you're using old tech. If you would target JEE6 you can benefit from standardized global JNDI names. The problem was recognized and fixed, but you have to move along with the times to benefit from improvements.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points