2009-09-24 20 views
10

He añadido lo siguiente en mi web.xml:EJB de búsqueda en su defecto con 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 utiliza dentro del contenedor:

<ejb-ref> 
     <ejb-ref-name>ejb/userManagerBean</ejb-ref-name> 
     <ejb-ref-type>Session</ejb-ref-type> 
     <home>gha.ywk.name.entry.ejb.usermanager.UserManagerHome</home> 
     <remote>what should go here??</remote> 
</ejb-ref> 

El siguiente código java me está dando NamingException . 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.<init>(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V 
java.lang.NoSuchMethodError: com.sun.enterprise.naming.java.javaURLContext.<init>(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) 
+0

¿Puede proporcionar un seguimiento de la pila? ¿El código se ejecuta afuera o dentro del contenedor? –

+0

por favor vea mi edición – Drake

+0

Agregue también su descriptor de implementación. Descriptor de despliegue –

Respuesta

1

Tal vez la cadena de búsqueda debería ser en realidad: "java: comp/env/ejb/userManagerBean"?

+0

que no funcionó :( – Drake

+2

Parece que no está recibiendo una excepción de nomenclatura ahora. Yo sugeriría que no pase las Propiedades al contexto inicial. Al ejecutar dentro del servidor de la aplicación, no debería necesitar hacer eso. – jsight

1

En primer lugar, arreglar su web.xml y añadir la interfaz remota en ella:

<ejb-ref> 
    <description>Sample EJB</description> 
    <ejb-ref-name>SampleBean</ejb-ref-name> 
    <ejb-ref-type>Session</ejb-ref-type> 
    <home>com.SampleHome</home> 
    <remote>com.Sample</remote> <!-- the remote interface goes here --> 
</ejb-ref> 

Entonces, con respecto a la java.lang.NoSuchMethodError, Sean es correcto, usted tiene una falta de correspondencia entre la versión del servidor de aplicaciones "biblioteca cliente "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 ninguna característica útil al crear el 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 los javadocs InitialContext para obtener más detalles.

1

Las dos últimas respuestas son correctas porque 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.

35

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

bien, 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 poder 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 mundial (después de su puesta en marcha) en la siguiente dirección

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

En Sun Application Server, si quieres ver la dirección JNDI mundial (después de su puesta en marcha), haga lo siguiente

un acceso a la consola de administración en la siguiente dirección

http://127.0.0.1:4848/asadmin 

Y haga clic navegación JNDI

Si el EJB no está registrado allí mismo, hay algo mal

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

Bueno, bueno, bueno ...

Vamos a empezar con EJB 2,1

  1. Crear una interfaz de Inicio

Define métodos para crear, destruir, y la búsqueda local o remoto Objetos EJB. 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.

Tenga cuidado de interfaz inicial remota la siguiente

Una de bean de sesión DEBE definir una o más crear < MÉTODO > métodos. Un bean de sesión sin estado DEBE DEFINIR exactamente un método < MÉTODO > sin argumentos.

...

cláusula throws DEBE CONTENER javax.ejb.CreateException

...

Si la interfaz principal va 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 nombrado crear < MÉTODO >, y debe coincidir con uno de los métodos Init o ejbCreate < MÉTODO > métodos definidos en la clase bean de sesión . El método correspondiente de ejbCreate <METHOD> DEBE TENER EL MISMO NÚMERO Y TIPOS DE ARGUMENTOS. El método create para un bean de sesión sin estado DEBE LLAMARSE crear pero no es necesario que tenga el método "ejbCreate" correspondiente.


Ahora crear una interfaz de negocio con el fin de definir la lógica de negocio 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 se encargan de la siguiente

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

...

Si la interfaz principal va javax.ejb.EJBObject, tiros 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 se encargan de la siguiente

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

Aviso nuestro grano no implementa nuestra interfaz de negocio debido a EJB especificación dice:

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

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

Y USTED TIENE QUE DECLARAR un ejb-jar.archivo XML de acuerdo con

<?xml version="1.0" encoding="UTF-8"?> 
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1"> 
    <enterprise-beans> 
     <session> 
      <ejb-name>HelloWorldEJB</ejb-name> 
      <home>br.com.MyBeanRemoteHome</home> 
      <remote>br.com.MyBeanRemote</remote> 
      <local-home>br.com.MyBeanLocalHome</local-home> 
      <local>br.com.MyBeanLocal</local> 
      <ejb-class>br.com.MyBean</ejb-class> 
      <session-type>Stateless</session-type> 
      <transaction-type>Container</transaction-type> 
     </session> 
    </enterprise-beans> 
</ejb-jar> 

Si usted no tiene un objeto EJB local de retirar del descriptor de despliegue anterior

<local-home>br.com.MyBeanLocalHome</local-home> 
<local>br.com.MyBeanLocal</local> 

Si usted no tiene un objeto EJB remoto retirar del descriptor de despliegue anterior

<home>br.com.MyBeanRemoteHome</home> 
<remote>br.com.MyBeanRemote</remote> 

Y poner en el directorio META-INF

Nuestro archivo jar w enfermos contienen la 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 puso archivo jar en

<JBOSS_HOME>/server/default/deploy 

En el acceso del servidor de aplicaciones Sun (después de su puesta en marcha) consola de administración

http://127.0.0.1:4848/asadmin 

y EJB acceder a los módulos con el fin de implementar el archivo ejb-jar

Como usted tiene algunos problemas al desplegar su aplicación en NetBeans , le sugiero lo siguiente

  1. Crear un simple proyecto de biblioteca de Java (un simple frasco sin un método principal)
  2. Agregar/server/default/lib (contiene archivos jar con el fin de que retriev) archivos jar de correo de su EJB a la aplicación Java si se está utilizando JBoss (no sé qué directorio en Sun Application Server)
  3. Implementar el código de

Ahora crea otro proyecto de guerra

  1. Agregue nuestro proyecto creado justo arriba y agregue <JBOSS_HOME>/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. Ver su dirección de cartografía mundial como se muestra en la parte superior de la respuesta

y aplicar el siguiente código en su servlet o algo más si se está utilizando 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 si usted están usando Sun Application Server - pon el archivo appserv-rt.jar (no sé qué pasado contiene appserv-rt.jar en Sun Application Server) en la ruta de clases

public static Context getInitialContext() throws javax.naming.NamingException { 

    return new javax.naming.InitialContext(); 

} 

Con el fin de acceder a su EJB en nuestro servlet o algo más

MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(<PUT_EJB_GLOBAL_ADDRESS_RIGHT_HERE>); 

myBean.doSomething(); 

respecto,

+0

¿Puedes echar un vistazo a esta pregunta? http://stackoverflow.com/questions/29190816/ejb2-javax-naming-namenotfoundexceptionexception-in-lookup – User27854

Cuestiones relacionadas