Reputation: 18282
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
Upvotes: 12
Views: 15884
Reputation: 118593
The problem is that @EJB will only be injected in to "managed" classes.
In Java EE 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.
Upvotes: 13
Reputation: 2759
Glassfish supports injection of EJBs in client apps not running in any Java EE container (your small app, Swing clients, etc.) through the so called 'application client container'.
For the record, if I remember well, we had to use something like
x = (TestBeanARemote) PortableRemoteObject.narrow(ic.lookup("com.bnncpa.testing.TestBeanARemote"), TestBeanARemote.class)
which is used in <=EJB 2.1 in Weblogic 10 although it supported and we used EJB 3 (JavaEE 5). It think it was caused by Weblogic's way of supporting the EJB3s by generating, in previous versions necessary, EJB 2.1 style interfaces. Do not know if they have already fixed it.
Upvotes: 0