2009-05-11 9 views
11

Uso de NetBeans, hago lo siguiente en la clase que contiene main(), y funciona:anotación en @EJB clientes

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

Si hago eso en una clase llamada, sin embargo, falla. Parece que una clase llamada requiere que evite el uso de anotaciones y, en su lugar, utilice una configuración completa de InitialContext().

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

    } 

El, en su defecto copia completa es a continuación:

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

¿Hay alguna razón en particular por @EJB podrían no funcionar en todas las clases de un paquete? Me gustaría poder simplemente etiquetar @EJB donde sea que esté usando uno.

¿Hay alguna forma mejor de hacer esto que me falta por completo?


Editar: Para hacer frente a la preocupación por el uso de un appclient, aquí está mi seguimiento de la pila:

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 

Respuesta

12

El problema es que @EJB sólo se inyecta en las clases "gestionados".

En Java EE hay muy pocas clases administradas. En particular, los clientes de aplicaciones (su "principal" aquí en este caso), los EJB (EJBs sin estado y con estado, los beans de mensaje, etc.) y los servlets.

Cualquier otra cosa (es decir, clases genéricas, entidades JPA, etc.) no tendrá los recursos inyectados, y tendrá que confiar en el mecanismo de búsqueda para obtener acceso a sus recursos.

+0

¿Dónde declaro qué clases se consideran administradas dentro de un cliente de aplicación? –

+0

Citando la especificación JEE 5: "Inyección también es compatible para la clase principal del cliente de la aplicación. Debido a que el contenedor del cliente de la aplicación no crea instancias de la clase principal del cliente de la aplicación , simplemente carga la clase e invoca el método principal la clase de cliente de la aplicación usa campos y métodos estáticos, a diferencia de otros componentes de Java EE. La inyección ocurre antes de que se llame al método principal ". La clase principal en un cliente de aplicaciones JEE es la única "clase administrada", por lo que también puede usar la búsqueda en todas partes. –

+0

Encontraron buena información basada en lo que me dijeron en http://weblogs.java.net/blog/ss141213/archive/2006/03/using_java_pers_1.html Muchas gracias :) –

0

Glassfish admite la inyección de EJB en aplicaciones cliente que no se ejecutan en ningún contenedor Java EE (su pequeña aplicación, clientes Swing, etc.) a través del llamado 'contenedor de cliente de aplicación'.

Para el registro, si no recuerdo mal, tuvimos que usar algo como

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

que se utiliza en < = EJB 2.1 en Weblogic 10 a pesar de que el apoyo y la usamos EJB 3 (JavaEE 5). Se cree que fue causada por la forma en que Weblogic apoya a los EJB3 generando, en versiones previas necesarias, interfaces de estilo EJB 2.1. No sé si ya lo arreglaron.