java 客户端中的@EJB 注释

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/848675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:03:00  来源:igfitidea点击:

@EJB annotation in clients

javanetbeansjakarta-eeejb

提问by Jeff Ferland

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

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

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.

但是,如果我在一个被调用的类中这样做,它就会失败。似乎被调用的类要求我避免使用注释,而是使用整个InitialContext()设置。

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 @EJBmight not work in all classes of a package? I'd like to be able to simply tag @EJBwherever I'm using one.

是否有特殊原因@EJB可能无法在包的所有类中工作?我希望能够@EJB在我使用的任何地方简单地标记。

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:

编辑:为了解决使用 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

回答by Will Hartung

The problem is that @EJB will only be injected in to "managed" classes.

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

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.

在 Java EE 中,托管类非常少。特别是应用程序客户端(在这种情况下是您的“主要”)、EJB(无状态和有状态 EJB、消息 Bean 等)和 Servlet。

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.

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

回答by MarianP

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

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

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.

它在 Weblogic 10 中的 <=EJB 2.1 中使用,尽管它支持并且我们使用了 EJB 3 (JavaEE 5)。它认为这是由 Weblogic 支持 EJB3 的方式引起的,在以前的版本中,它需要生成 EJB 2.1 样式的接口。不知道他们是否已经修复了它。