La búsqueda de ejb falla con NamingException

He agregado lo siguiente en mi web.xml:

 ejb/userManagerBean Session gha.ywk.name.entry.ejb.usermanager.UserManagerHome what should go here??  

El siguiente código de Java me está dando NamingException:

 public UserManager getUserManager () throws HUDException { String ROLE_JNDI_NAME = "ejb/userManagerBean"; try { Properties props = System.getProperties(); Context ctx = new InitialContext(props); UserManagerHome userHome = (UserManagerHome) ctx.lookup(ROLE_JNDI_NAME); UserManager userManager = userHome.create(); WASSSecurity user = userManager.getUserProfile("user101", null); return userManager; } catch (NamingException e) { log.error("Error Occured while getting EJB UserManager" + e); return null; } catch (RemoteException ex) { log.error("Error Occured while getting EJB UserManager" + ex); return null; } catch (CreateException ex) { log.error("Error Occured while getting EJB UserManager" + ex); return null; } } 

El código se usa dentro del contenedor. Con eso quiero decir que el .WAR se implementa en el servidor (Sun Application Server).

StackTrace (después de la sugerencia de jsight):

 >Exception occurred in target VM: com.sun.enterprise.naming.java.javaURLContext.(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V java.lang.NoSuchMethodError: com.sun.enterprise.naming.java.javaURLContext.(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V at com.sun.enterprise.naming.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:32) at javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584) at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:533) at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:279) at javax.naming.InitialContext.lookup(InitialContext.java:351) at gov.hud.pih.eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.java:34) 

Creo que desea acceder a una aplicación EJB (conocida como módulo EJB) desde una aplicación web en Sun Application Server, ¿verdad?

OK vamos.

Cuando implementa un EJB en un servidor de aplicaciones, el servidor de aplicaciones le da una dirección, conocida como dirección JNDI global, como una forma de acceder a ella (algo así como su dirección). Cambia de un servidor de aplicaciones a otro.

En JBoss Application Server, puede ver la dirección JNDI global (después de iniciarla) en la siguiente dirección

 http://127.0.0.1:8080/jmx-console/HtmlAdaptor 

En Sun Application Server, si desea ver la dirección JNDI global (después de iniciarla), haga lo siguiente

Acceda a la consola de administración en la siguiente dirección

 http://127.0.0.1:4848/asadmin 

Y haz clic en la navegación JNDI

Si su EJB NO está registrado allí, hay algo mal

EJB viene en dos sabores: EJB 2.1 y EJB 3.0. Entonces cuál es la diferencia ?

Bien bien bien…

Comencemos con EJB 2.1

  1. Crea una interfaz de inicio

Define métodos para CREAR, destruir y encontrar objetos EJB locales o remotos. Actúa como interfaces de ciclo de vida para los objetos EJB. Todas las interfaces de origen deben ampliar la interfaz estándar javax.ejb.EJBHome, si utiliza un objeto ejb remoto, o javax.ejb.EJBLocalHome, si está utilizando un objeto EJB local.

 // a remote EJB object - extends javax.ejb.EJBHome // a local EJB object - extends javax.ejb.EJBLocalHome public interface MyBeanRemoteHome extends javax.ejb.EJBHome { MyBeanRemote create() throws javax.ejb.CreateException, java.rmi.RemoteException; } 

Application Server creará objetos de inicio como una forma de obtener un objeto EJB, nada más.

Cuida lo siguiente

La interfaz de inicio remota de un bean de sesión DEBE DEFINIR UNO O MÁS métodos create . Un bean de sesión sin estado DEBE DEFINIR exactamente un método sin argumentos.

La cláusula throws DEBE INCLUIR javax.ejb.CreateException

Si su interfaz de Inicio extiende javax.ejb.EJBHome, las cláusulas throws DEBEN INCLUIR la java.rmi.RemoteException. Si extiende javax.ejb.EJBLocalHome, NO DEBE INCLUIR la java.rmi.RemoteException.

Cada método create de un bean de sesión con estado DEBE SER NOMBRE create , y debe coincidir con uno de los métodos Init o los métodos ejbCreate definidos en la clase bean de sesión. El método equivalente ejbCreate DEBE TENER EL MISMO NÚMERO Y TIPOS DE ARGUMENTOS. El método de creación para un bean de sesión sin estado DEBE SER NOMBRADO create, pero no es necesario que tenga un método “ejbCreate” correspondiente.


Ahora crea una interfaz de negocios para definir la lógica de negocios en nuestro objeto EJB

 // a remote EJB object - extends javax.ejb.EJBObject // a local EJB object - extends javax.ejb.EJBLocalObject public interface MyBeanRemote extends javax.ejb.EJBObject { void doSomething() throws java.rmi.RemoteException; } 

Ahora cuida de lo siguiente

Si está utilizando un objeto EJB remoto, los métodos de interfaz remota NO DEBEN EXPONER los tipos de interfaz local o los tipos de interfaz doméstica local.

Si su interfaz de Inicio extiende javax.ejb.EJBObject, throws cláusulas DEBE INCLUIR la java.rmi.RemoteException. Si extiende javax.ejb.EJBLocalObject, NO DEBE INCLUIR la java.rmi.RemoteException.


Ahora nuestro EJB

 public class MyBean implements javax.ejb.SessionBean { // why create method ? Take a special look at EJB Home details (above) public void create() { System.out.println("create"); } public void doSomething() throws java.rmi.RemoteException { // some code }; } 

Ahora cuida de lo siguiente

DEBE IMPLEMENTAR javax.ejb.SessionBean. Define cuatro métodos, que no se muestran arriba: setSessionContext, ejbRemove, ejbPassivate y ejbActivate.

Tenga en cuenta que nuestro bean NO IMPLEMENTA nuestra interfaz comercial debido a que la especificación EJB dice:

Para cada método definido en la interfaz, debe haber un método de coincidencia en la clase del bean de la sesión. El método de coincidencia debe tener:

  • El mismo nombre
  • El mismo número y tipos de argumentos, y el mismo tipo de devolución.
  • Todas las excepciones definidas en la cláusula throws del método de concordancia de la clase de bean de sesión se deben definir en la cláusula throws del método de la interfaz local.

Y TIENE QUE DECLARAR un archivo ejb-jar.xml según

 < ?xml version="1.0" encoding="UTF-8"?>    HelloWorldEJB br.com.MyBeanRemoteHome br.com.MyBeanRemote br.com.MyBeanLocalHome br.com.MyBeanLocal br.com.MyBean Stateless Container    

Si no tiene un objeto EJB local, elimínelo del descriptor de implementación anterior

 br.com.MyBeanLocalHome br.com.MyBeanLocal 

Si no tiene un objeto EJB remoto, elimínelo del descriptor de implementación anterior

 br.com.MyBeanRemoteHome br.com.MyBeanRemote 

Y poner en el directorio META-INF

Nuestro archivo jar contendrá lo siguiente

 /META-INF/ejb-jar.xml br.com.MyBean.class br.com.MyBeanRemote.class br.com.MyBeanRemoteHome.class 

Ahora nuestro EJB 3.0

 // or @Local // You can not put @Remote and @Local at the same time @Remote public interface MyBean { void doSomething(); } @Stateless public class MyBeanStateless implements MyBean { public void doSomething() { } } 

Nada más,

En JBoss poner archivo jar en

 /server/default/deploy 

En el acceso de Sun Application Server (después de iniciarlo) consola de administración

 http://127.0.0.1:4848/asadmin 

Y acceda a los módulos EJB para desplegar su archivo ejb-jar

Como tiene algunos problemas al implementar su aplicación en NetBeans, sugiero lo siguiente

  1. Cree un PROYECTO de biblioteca Java simple (un simple jar sin un método principal)
  2. Agregue / server / default / lib (contiene archivos jar para recuperar los archivos jar de su EJB) a su aplicación Java ya sea que esté utilizando JBoss (no sé qué directorio en Sun Application Server)
  3. Implementar el código anterior

Ahora crea otro PROYECTO de guerra

  1. Agregue nuestro proyecto creado justo arriba y agregue / client (contiene archivos jar para acceder a nuestros EJB). De nuevo, no sé qué directorio en Sun Application Server. Ckeck fuera de su documentación.
  2. Vea su dirección de mapeo global como se muestra en la parte superior de la respuesta

E implemente el siguiente código en su Servlet u otra cosa ya sea que esté usando JBoss

 public static Context getInitialContext() throws javax.naming.NamingException { Properties p = new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); p.put(Context.URL_PKG_PREFIXES, " org.jboss.naming:org.jnp.interfaces"); p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099"); return new javax.naming.InitialContext(p); } 

O lo siguiente, ya sea que esté usando Sun Application Server: coloque el archivo appserv-rt.jar (no sé qué pasado contiene appserv-rt.jar en Sun Application Server) en su classpath

 public static Context getInitialContext() throws javax.naming.NamingException { return new javax.naming.InitialContext(); } 

Para acceder a su EJB en nuestro Servlet u otra cosa

 MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(); myBean.doSomething(); 

Saludos,

Quizás la cadena de búsqueda debería ser: “java: comp / env / ejb / userManagerBean”?

Las dos últimas respuestas son correctas, ya que son cosas que necesita cambiar / corregir. Pero el NoSuchMethodError que ve no proviene de su código, ni de las cosas que intentan encontrar su código (creo que produciría algún tipo de NoClassDefFoundException, creo, si este fuera el caso). Esto se parece más a las versiones incompatibles del proveedor JNDI proporcionado por el contenedor, y lo que quiere la implementación JNDI en la biblioteca Java. Esa es una respuesta bastante vaga, pero imaginaría que es posible solucionarla, tal vez actualizando su servidor de aplicaciones, y asegurándose de que no está implementando copias posiblemente anticuadas de las clases de infraestructura relacionadas con JNDI con su aplicación, que podrían interferir.

Primero, arregle su web.xml y agregue la interfaz remota en él:

  Sample EJB SampleBean Session com.SampleHome com.Sample   

Luego, con respecto a java.lang.NoSuchMethodError , Sean tiene razón, tiene una discrepancia entre la versión de la “biblioteca de cliente” del servidor de aplicaciones que está utilizando dentro de NetBeans y la versión del servidor de aplicaciones (del lado del servidor). No puedo decirle exactamente a qué JAR necesita alinear, consulte la documentación de Sun Application Server.

PD: Esta no es una respuesta directa al problema, pero no creo que estés pasando propiedades útiles al crear tu contexto inicial con los resultados de la llamada a System.getProperties() , no hay nada útil en estas propiedades para definir el entorno de un contexto (por ejemplo, la fábrica de contexto inicial). Consulte InitialContext javadocs para más detalles.