JBoss EJB3 remote invocation from client app
zecas May 24, 2010 2:38 PMHi,
I'm trying to workout an EJB example with JBoss, but I'm having some trouble understanding some things, and making other things to work.
My Environment:
- Windows XP;
- JBoss 5.1.0.GA;
- Eclipse.
The project is composed of an EAR with an EJB 3.0 and WAR module. Then I'll try to connect remotely in a client application to invoke the EJB.
So for a start, my EJB definition is:
package com.test; import javax.ejb.Stateless; /** * Session Bean implementation class MyBean */ @Stateless(name = "my-name", mappedName = "my-map") public class MyBean implements MyRemote, MyLocal { /** * Default constructor. */ public MyBean() { } public String getMyCommon() { return "My-Common"; } public String getMyRemote() { return "My-Remote"; } public String getMyLocal() { return "My-Local"; } }
package com.test; import javax.ejb.Local; @Local public interface MyLocal { public String getMyCommon(); public String getMyLocal(); }
package com.test; import javax.ejb.Remote; @Remote public interface MyRemote { public String getMyCommon(); public String getMyRemote(); }
My ejb-jar.xml in EJB module META-INF, has no definitions:
<?xml version="1.0" encoding="ASCII"?> <ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> <display-name>my-ejb</display-name> </ejb-jar>
My web.xml in WAR module has no reference to EJB:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>my-web</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>
My application.xml describes the modules:
<?xml version="1.0" encoding="UTF-8"?> <application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5"> <display-name>my-ear</display-name> <module> <web> <web-uri>my-web-0.0.1-SNAPSHOT.war</web-uri> <context-root>/my-web</context-root> </web> </module> <module> <ejb>my-ejb-0.0.1-SNAPSHOT.jar</ejb> </module> </application>
The WAR has a small test page, that injects the @EJB local interface, and successfully gets data, so I assume no other config should be necessary (for now, at least).
For deployment, I just copied the EAR to deploy directory. No errors, and checking JMX Console I can find the following info:
jboss.deployment # id="jboss.j2ee:ear=my-ear-0.0.1-SNAPSHOT.ear,jar=my-ejb-0.0.1-SNAPSHOT.jar,name=my-name,service=EJB3",type=Component # id="jboss.j2ee:ear=my-ear-0.0.1-SNAPSHOT.ear,jar=my-ejb-0.0.1-SNAPSHOT.jar,name=my-name,service=EJB3_endpoint",type=Component
I then created a small standalone project, with following code:
Hashtable environment = new Hashtable(); environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); environment.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099"); // remote machine IP InitialContext context = null; try { context = new InitialContext(environment); Object obj = context.lookup("my-name"); System.out.println("-->> lookup object successfully"); } catch(Throwable ex) { ex.printStackTrace(); } finally { if( context!=null ) { context.close(); } }
When executing, I get the exception:
javax.naming.NameNotFoundException: my-name not bound at org.jnp.server.NamingServer.getBinding(NamingServer.java:771) at org.jnp.server.NamingServer.getBinding(NamingServer.java:779) at org.jnp.server.NamingServer.getObject(NamingServer.java:785) at org.jnp.server.NamingServer.lookup(NamingServer.java:443) 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 sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305) at sun.rmi.transport.Transport$1.run(Transport.java:159) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142) at org.jnp.server.NamingServer_Stub.lookup(Unknown Source) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:528) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:507) at javax.naming.InitialContext.lookup(InitialContext.java:392)
Changing the lookup to:
Object obj = context.lookup("my-map");
Works ok. Lookup goes successfull.
Replacing with:
MyRemote myRemote = (MyRemote) context.lookup("my-map");
Will return:
java.lang.ClassCastException: javax.naming.Reference cannot be cast to com.test.MyRemote
My client application has dependency to the EJB client jar, which only has MyRemote and MyLocal classes, and a dependency to jbossall-client-3.2.3.jar.
If I narrow:
MyRemote myRemote = (MyRemote) PortableRemoteObject.narrow( context.lookup("my-map"), MyRemote.class );
I'll get:
java.lang.ClassCastException at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) ... 2 more Caused by: java.lang.ClassCastException: javax.naming.Reference cannot be cast to org.omg.CORBA.Object at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) ... 3 more
What am I doing wrong?
Thanks