问题 客户端的@EJB注释


使用NetBeans,我在包含的类中执行以下操作 main(),它的工作原理:

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.
...

但是,如果我在被调用的类中执行此操作,则会失败。似乎被调用的类要求我避免使用注释而是使用整体 InitialContext() 建立。

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

    }

完整的,失败的副本如下:

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);
   }
}

有什么特别的原因吗? @EJB 可能不适用于所有类的包?我希望能够简单地标记 @EJB 无论我在哪里使用。

有没有更好的方法可以解决这个问题,我完全错过了?


编辑:为了解决使用appclient的问题,这是我的堆栈跟踪:

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

7776
2018-05-11 15:34


起源



答案:


问题是@EJB只会被注入“托管”类。

在Java EE中,托管类很少。特别是应用程序客户端(在本例中为“主要”),EJB(无状态和有状态EJB,消息Bean等)和Servlet。

其他任何东西(即泛型类,JPA实体等)都不会注入资源,您需要依赖查找机制来访问您的资源。


12
2018-05-11 20:43



在哪里可以声明哪些类在应用程序客户端中被视为托管? - Jeff Ferland
引用JEE 5规范:“应用程序客户机主类也支持注入。因为应用程序客户机容器不创建应用程序客户机主类的实例,而只是加载类并调用静态main方法,注入应用程序与其他Java EE组件不同,客户端类使用静态字段和方法。在调用main方法之前进行注入。“ JEE App Client中的主要类是唯一的“托管类”,因此您也可以在任何地方使用查找。 - Will Hartung
根据你告诉我的内容找到了很好的信息 weblogs.java.net/blog/ss141213/archive/2006/03/...  非常感谢 :) - Jeff Ferland


答案:


问题是@EJB只会被注入“托管”类。

在Java EE中,托管类很少。特别是应用程序客户端(在本例中为“主要”),EJB(无状态和有状态EJB,消息Bean等)和Servlet。

其他任何东西(即泛型类,JPA实体等)都不会注入资源,您需要依赖查找机制来访问您的资源。


12
2018-05-11 20:43



在哪里可以声明哪些类在应用程序客户端中被视为托管? - Jeff Ferland
引用JEE 5规范:“应用程序客户机主类也支持注入。因为应用程序客户机容器不创建应用程序客户机主类的实例,而只是加载类并调用静态main方法,注入应用程序与其他Java EE组件不同,客户端类使用静态字段和方法。在调用main方法之前进行注入。“ JEE App Client中的主要类是唯一的“托管类”,因此您也可以在任何地方使用查找。 - Will Hartung
根据你告诉我的内容找到了很好的信息 weblogs.java.net/blog/ss141213/archive/2006/03/...  非常感谢 :) - Jeff Ferland


Glassfish支持通过所谓的“应用程序客户端容器”在未在任何Java EE容器(您的小应用程序,Swing客户端等)中运行的客户端应用程序中注入EJB。

为了记录,如果我记得很清楚,我们必须使用类似的东西

x = (TestBeanARemote) PortableRemoteObject.narrow(ic.lookup("com.bnncpa.testing.TestBeanARemote"), TestBeanARemote.class)

虽然它支持并且我们使用EJB 3(JavaEE 5),但它在Weblogic 10中的<= EJB 2.1中使用。它认为它是由Weblogic通过在必要的先前版本中生成EJB 2.1样式接口来支持EJB3的方式引起的。不知道他们是否已经修好了。


0
2017-08-12 15:11