views:

49

answers:

4

Is it possible to access an EJB from a POJO? I have tried the

@EJB MyClass obj

but that does not work.

A: 

Hi James,

It is possible to access an EJB from a POJO. You'll have to do a JNDI-lookup for that.

Normally dependency injection, like what you are trying now, works only in the managed environments - In Servlets and EJBs.

stratwine
In Java EE 6, anything can be turned into a managed bean using CDI, not only Servlets, EJBs, etc.
Pascal Thivent
A: 

the annotation you are using requires that your infrastructure knows to into the field with that annotation. you may need to either use a wrapping class or do it manually, it really depends on your setup.

steven
+1  A: 

Injection would be possible IF you use JSR-199 (Java Contexts and Dependency Injection) that can turn anything into a managed component. So if your POJO is a CDI managed bean, you could do:

@Inject MyEjb service

Without CDI, you'll have to do a lookup.

See also

Pascal Thivent
@Pascal Thivent Thanks, I will read through you links. Does this mean I can have a class MyPojo with the annotation @ManagedBean and create as many instances of the object as I need each of which will have a reference to my Dao EJB as long as MyPojo has an @Inject MyDao dao? Cheers, James
James
@James CDI beans are annotated with `@Named`. And you don't really create them, they get injected. I really suggest to have a look at the links above :)
Pascal Thivent
A: 

I will look in to the @Inject as that sounds like the solution I am looking for but it didn't work when I tried it. I am sure I am missing something but I tried for a while and didn't get anywhere. A tight deadline lead me to implementing the below helper class which I thought I would post for anyone to use if they have similar issues.

Thanks for the responses.

public class InjectionHelper {

    private static final String DEPENDENCY_SEPERATOR = "/";

    private static Logger logger = Logger.getLogger(InjectionHelper.class);

    private static Map<Class<?>, Object> dependencies = null;

    private static List<Object> dependenciesList = null;

    private static Context baseContext = null;

    /**
     * Search for the dependency of the specified class.
     */
    public static final <T> T injectDependency(Class<T> dependencyClass){

        //initialise the dependencies
        if(dependenciesList == null){
            dependenciesList = new ArrayList<Object>();
            dependencies = new HashMap<Class<?>, Object>();
            try{
                baseContext = new InitialContext();
                populateDependencies(baseContext, new Stack<String>());
            }
            catch(Exception e){
                logger.error("Error populating dependencies", e);
            }
        }

        //We have seen this dependency before and can get it from the map
        if(dependencies.containsKey(dependencyClass)){
            return (T)dependencies.get(dependencyClass);
        }

        //Not seen the dependency so we must try and find it in the list 
        for(Object o: dependenciesList){
            if(dependencyClass.isInstance(o)){
                dependencies.put(dependencyClass, o);
                return (T)o;
            }
        }

        //We don't have the dependency
        return null;
    }

    /**
     * Traverse the InitialContext and extract all dependencies and store them in the map keyed by their class.
     *  
     * @param lookupNameStack
     */
    private static final void populateDependencies(Context ctx, Stack<String> lookupNameStack) {
        try {
            NamingEnumeration<Binding> list = ctx.listBindings("");

            while (list.hasMore()) {
               Binding item = list.next();

               //Get the name and object for the binding
               String lookupName = item.getName();
               Object objectBinding = item.getObject();

               //If a JavaGlobalJndiNamingObjectProxy this is a dependency we want to store
               if(objectBinding instanceof JavaGlobalJndiNamingObjectProxy){

                   //Based on our current position in the tree get the string representation
                   Iterator<String> lookupNameIterator = lookupNameStack.iterator();
                   String lookupPrefix = "";
                   while(lookupNameIterator.hasNext()){
                       lookupPrefix += lookupNameIterator.next();
                   }

                   //lookup the object and store in the map
                   try{
                       Object obj = baseContext.lookup(lookupPrefix+lookupName);
                       dependenciesList.add(obj);
                       logger.info("Found [" + obj.getClass() + "] Lookup [" + lookupPrefix + lookupName +"]");
                   }
                   catch(Exception e){
                       logger.info("Failed to find Lookup [" + lookupPrefix+lookupName + "]", e);
                   }
               }
               lookupNameStack.push(lookupName+DEPENDENCY_SEPERATOR);

               //If we find a context we can explore that branch
               if (objectBinding instanceof Context) {
                   populateDependencies((Context) objectBinding, lookupNameStack);
               }
               //Now we have traversed the branch we need to remove the last leaf
               lookupNameStack.pop();
           }

        } catch (NamingException ex) {
           logger.info("JNDI failure: ", ex);
        }
    }
}
James