0 Replies Latest reply on Dec 20, 2005 6:29 PM by edale

    EJB3 Remoting via ServerInvokerServlet

    edale

      Using JBoss 4.0.3SP1 and EJB3, I'm trying to invoke methods on a stateless session bean via the ServerInvokerServlet. I have it working using http, where ejb3.deployer/META-INF/jboss-service.xml is set up to use http transport. i.e.:

      <attribute name="InvokerLocator">http://localhost:7080</attribute>
      


      But, I can't get it to work using the servlet transport. The general idea is to get everything to work via port 8080, so that only a single port needs to be open on the firewall between the client and server. Here's my test case, which seems to be correct per the documentation, and per the examples in other posts I have found in the forum. For this test, I am running both client and server on the same machine because the URL is set to localhost:

      Client app:

      package com.nfr.hello.client;
      
      import java.rmi.RMISecurityManager;
      import java.util.Properties;
      
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      
      import com.nfr.hello.server.CopyOfHello;
      import com.nfr.hello.server.Hello;
      
      public class HelloClient
      {
      
       public static void main(String[] args)
       {
       try
       {
       if (System.getSecurityManager() == null)
       {
       System.setSecurityManager(new RMISecurityManager());
       }
      
       InitialContext initial = new InitialContext();
      
       Hello hello = (Hello)initial.lookup(Hello.class.getName());
       System.out.println(hello.sayHello());
       }
       catch (NamingException e)
       {
       e.printStackTrace();
       }
       }
      }
      


      Bean Interface:

      package com.nfr.hello.server;
      
      public interface Hello
      {
       public String sayHello();
      }
      


      Stateless Bean:

      package com.nfr.hello.server;
      
      import javax.ejb.Remote;
      import javax.ejb.Stateless;
      
      import org.jboss.annotation.ejb.RemoteBinding;
      import org.jboss.annotation.ejb.RemoteBindings;
      
      @Stateless
      @Remote({Hello.class})
      @RemoteBindings({
       @RemoteBinding(
       clientBindUrl="http://localhost:8080/servlet-invoker/ServerInvokerServlet")
       })
      public class HelloBean implements Hello
      {
      
       public String sayHello()
       {
       return "Hello";
       }
      
      }
      


      ejb3.deployer/META-INF/jboss-service.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <server>
       <mbean code="org.jboss.ejb3.EJB3Deployer"
       name="jboss.ejb3:service=EJB3Deployer">
       <depends>jboss.aop:service=AspectDeployer</depends>
       </mbean>
       <mbean code="org.jboss.remoting.transport.Connector"
       xmbean-dd="org/jboss/remoting/transport/Connector.xml"
       name="jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">
       <depends>jboss.aop:service=AspectDeployer</depends>
       <attribute name="InvokerLocator">servlet://localhost:8080/servlet-invoker/ServerInvokerServlet</attribute>
       <attribute name="Configuration">
       <config>
       <handlers>
       <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
       </handlers>
       </config>
       </attribute>
       </mbean>
      </server>
      


      servlet-invoker.war/WEB-INF/web.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE web-app PUBLIC
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
       "http://java.sun.com/dtd/web-app_2_3.dtd">
      
      <!-- The the JBossRemoting server invoker servlet web.xml descriptor
       $Id: web.xml,v 1.1 2005/06/16 21:12:48 telrod Exp $
      -->
      <web-app>
       <servlet>
       <servlet-name>ServerInvokerServlet</servlet-name>
       <description>
       The ServerInvokerServlet receives requests via HTTP protocol
       from within a web container and passes it onto the
       ServletServerInvoker for processing.
       </description>
       <servlet-class>org.jboss.remoting.transport.servlet.web.ServerInvokerServlet</servlet-class>
       <init-param>
       <param-name>invokerName</param-name>
       <param-value>jboss.remoting:service=invoker,transport=servlet
       </param-value>
       <description>The servlet server invoker</description>
       </init-param>
       <load-on-startup>1</load-on-startup>
       </servlet>
       <servlet-mapping>
       <servlet-name>ServerInvokerServlet</servlet-name>
       <url-pattern>/ServerInvokerServlet/*</url-pattern>
       </servlet-mapping>
      </web-app>
      


      servlet-invoker.war/WEB-INF/jboss-web.xml:

      <jboss-web>
       <!-- Uncomment the security-domain to enable security. You will
       need to edit the jmx-console login configuration to setup the
       login modules used to authentication users.
       <security-domain>java:/jaas/jmx-console</security-domain>
       -->
      </jboss-web>
      


      The server starts up with no errors. When I attempt to connect with the client, I get the following exception:


      Exception in thread "main" org.jboss.remoting.CannotConnectException: Can not connect http client invoker.
      at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:123)
      at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:56)
      at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:112)
      at org.jboss.remoting.Client.invoke(Client.java:226)
      at org.jboss.remoting.Client.invoke(Client.java:189)
      at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:41)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:46)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:40)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:41)
      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:88)
      at $Proxy0.sayHello(Unknown Source)
      at com.nfr.hello.client.HelloClient.main(HelloClient.java:32)
      Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8080/servlet-invoker/ServerInvokerServlet
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1149)
      at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:111)
      ... 15 more


      This error is a result of line 80 in ServletServerInvoker, which is:

      Object obj = unmarshaller.read(inputStream, metadata);

      The return value here is null, which causes a null pointer exception, and hence the "500 error" in the client.

      I've spent days on this and I'm having real trouble getting to the root cause of the problem. Help would be ***GREATLY*** appreciated.