Friday, May 6, 2011

@EJB annotation in clients

Using NetBeans, I do the following in the class containing main(), and it works:

import javax.ejb.EJB;

public class Master {
    @EJB
    TestBeanARemote x;

    public static void main(String[] args) {
        Master m = new Master();
        m.doStuff();
    }
//doStuff includes x, but it works, so who cares.
...

If I do that in a called class, however, it fails. It seems that a called class requires me to avoid using annotations and instead use a the whole InitialContext() setup.

String testRun(String arg) {
   InitialContext ic;
    try {
        ic = new InitialContext();
        x = (TestBeanARemote) ic.lookup("com.bnncpa.testing.TestBeanARemote");
        return x.testRun(arg);

    }

The full, failing copy is below:

package enterpriseapplication1;
public class Main {

    private Secondary x = new Secondary();

    public static void main(String[] args) {
        Main m = new Main();
        m.doStuff();
    }

    public void doStuff() {
        System.out.println(x.testRun("bar"));
    }

}

package enterpriseapplication1;
import org.mine.testing.TestBeanARemote;
import javax.ejb.EJB;

public class Secondary {
   @EJB
   static private TestBeanARemote x;

   String testRun(String arg) {
       return x.testRun(arg);
   }
}

Is there a particular reason why @EJB might not work in all classes of a package? I'd like to be able to simply tag @EJB wherever I'm using one.

Is there some better way to go about this that I'm missing entirely?


Edit: To address the concern over using an appclient, here's my stack trace:

May 11, 2009 4:24:46 PM com.sun.enterprise.appclient.MainWithModuleSupport <init>
WARNING: ACC003: Application threw an exception.
java.lang.NullPointerException
    at enterpriseapplication1.Secondary.testRun(Secondary.java:20)
    at enterpriseapplication1.Main.doStuff(Main.java:27)
    at enterpriseapplication1.Main.main(Main.java:23)
    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 com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:266)
    at com.sun.enterprise.appclient.MainWithModuleSupport.<init>(MainWithModuleSupport.java:449)
    at com.sun.enterprise.appclient.MainWithModuleSupport.<init>(MainWithModuleSupport.java:259)
    at com.sun.enterprise.appclient.Main.main(Main.java:200)
Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at com.sun.enterprise.appclient.MainWithModuleSupport.<init>(MainWithModuleSupport.java:461)
    at com.sun.enterprise.appclient.MainWithModuleSupport.<init>(MainWithModuleSupport.java:259)
    at com.sun.enterprise.appclient.Main.main(Main.java:200)
Caused by: java.lang.reflect.InvocationTargetException
    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 com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:266)
    at com.sun.enterprise.appclient.MainWithModuleSupport.<init>(MainWithModuleSupport.java:449)
    ... 2 more
Caused by: java.lang.NullPointerException
    at enterpriseapplication1.Secondary.testRun(Secondary.java:20)
    at enterpriseapplication1.Main.doStuff(Main.java:27)
    at enterpriseapplication1.Main.main(Main.java:23)
    ... 8 more
Java Result: 1
From stackoverflow
  • The problem is that @EJB will only be injected in to "managed" classes.

    In JEE there are very few managed classes. Notably Application Clients (your "main" here in this case), EJBs (Stateless and Stateful EJBs, Message Beans, etc.), and Servlets.

    Anything else (i.e. generic classes, JPA entities, etc.) will not have the resources injected, and you will need to rely on the lookup mechanism to get access to your resources.

    Autocracy : Where do I declare which classes are considered managed within an application client?
    Will Hartung : Quoting the JEE 5 spec: "Injection is also supported for the application client main class. Because the application client container does not create instances of the application client main class, but merely loads the class and invokes the static main method, injection into the application client class uses static fields and methods, unlike other Java EE components. Injection occurs before the main method is called." The main class in a JEE App Client is the only "managed class", so you may as well use lookup everywhere.
    Autocracy : Found good info based on what you told me at http://weblogs.java.net/blog/ss141213/archive/2006/03/using_java_pers_1.html Thanks much :)

0 comments:

Post a Comment