2009-05-11 12 views
11

Mit NetBeans in Kunden, ich nach dem in der Klasse enthält main(), und es funktioniert:@EJB Anmerkung

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

Wenn ich das in einer gerufenen Klasse, aber es funktioniert nicht. Es scheint, dass eine aufgerufene Klasse erfordert, dass ich die Verwendung von Anmerkungen vermeiden und stattdessen das gesamte InitialContext() Setup verwenden.

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

    } 

Die vollständige, Kopie andernfalls ist unten:

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

Gibt es einen bestimmten Grund, warum @EJB möglicherweise nicht in allen Klassen eines Pakets arbeiten? Ich möchte in der Lage sein, einfach @EJB zu markieren, wo immer ich einen benutze.

Gibt es einen besseren Weg, dies zu gehen, über die ich völlig fehlt bin?


Edit: Um die Besorgnis über die Verwendung eines appclient Adresse, hier ist mein 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 

Antwort

12

Das Problem ist, dass @EJB wird nur bei "verwaltet" Klassen injiziert werden.

In Java EE gibt es sehr wenige verwaltete Klassen. Bemerkenswerter Application Clients (Ihre "main" hier in diesem Fall), EJBs (Stateless und Stateful EJBs, Mitteilung-Bohnen, etc.) und Servlets.

Für alles andere (d. H. Generische Klassen, JPA-Entitäten usw.) werden die Ressourcen nicht injiziert, und Sie müssen sich auf den Suchmechanismus verlassen, um Zugriff auf Ihre Ressourcen zu erhalten.

+0

Wo erkläre ich, welche Klassen in einer Anwendung Client verwaltet berücksichtigt werden? –

+0

Die Spezifikation von JEE 5 zitiert: "Injection wird auch für die Hauptklasse des Anwendungsclients unterstützt. Weil der Anwendungsclientcontainer keine Instanzen der Hauptklasse des Anwendungsclients erstellt, sondern lediglich die Klasse lädt und die statische Hauptmethode injection in Die Anwendung Client-Klasse verwendet im Gegensatz zu anderen Java EE-Komponenten statische Felder und Methoden. Die Injektion erfolgt vor dem Aufruf der Hauptmethode. " Die Hauptklasse in einem JEE-App-Client ist die einzige "verwaltete Klasse", daher können Sie die Suche auch überall verwenden. –

+0

Gefunden gute Informationen auf, was Sie sagte mir bei http://weblogs.java.net/blog/ss141213/archive/2006/03/using_java_pers_1.html Dank viel :) –

0

Glassfish unterstützt Injektion von EJBs in Client-Anwendungen laufen nicht in jedem Java EE Container (Ihre kleine App, Swing-Clients, etc.) durch die so genannte 'Anwendungs-Client-Container'.

Für das Protokoll, wenn ich mich gut erinnere, hatten wir so etwas wie

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

zu verwenden, die 10 in < = EJB 2.1 in Weblogic verwendet wird, obwohl es unterstützt und wir verwendeten EJB 3 (JavaEE 5). Es wird vermutet, dass Weblogic die EJB3 unterstützt, indem es in früheren Versionen EJB 2.1-Schnittstellen erzeugt. Ich weiß nicht, ob sie es schon repariert haben.