2 Replies Latest reply on May 28, 2010 10:15 AM by zecas zecas

    JBoss EJB3 remote invocation from client app

    zecas zecas Newbie

      Hi,

       

      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