3 Replies Latest reply on May 4, 2004 3:44 PM by jeremystein

    RMI callback

    jeremystein

      I'm trying to call an EJB method on a JBoss server, passing it a reference to the client object so that I can receive a callback. I used to have this working when we were using Weblogic, but I can't seem to get it to work for JBoss.

      The EJB's interface includes a nested interface that extends Remote:

      public interface TestEjb extends EJBObject {
       public void register(Callback callback) throws RemoteException;
      
       public interface Callback extends Remote {
       public void send(String message) throws RemoteException;
       }
      }
      


      My client implements that interface:
      public class TestClient extends UnicastRemoteObject implements TestEjb.Callback {
       ...
       public void send(String message) {
       System.out.println("Message from server: '" + message + "'");
       }
       ...
      }
      


      I expect to be able to pass "this" to TestEbj.register. However, I get an IllegalArgumentException from the server, claiming that I am passing the wrong number of arguments.

      Steps to reproduce:

      1) Get the source files here: http://www.everybody.org/~jeremystein/code/CallbackTest.zip
      2) Extract the zip file
      3) The server directory contains the Test EJB. Deploy it on a JBoss server.
      4) The EjbInterface.jar file contains these classes needed to compile the client.
      - TestEjb$Callback.class
      - TestEjb.class
      - TestEjbHome.class
      (You could create this jar yourself after compiling the EJB classes.)
      5) Grab jbossall-client.jar from the jboss distribution (in the client directory). Put it in the client directory.
      6) CD to the client directory.
      7) javac -d . -classpath EjbInterface.jar;jbossall-client.jar TestClient.java
      8) rmic -classpath .;EjbInterface.jar;jbossall-client.jar com.elementk.client.TestClient
      9) java -classpath .;EjbInterface.jar;jbossall-client.jar com.elementk.client.TestClient

      Detailed exception:

      java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
      java.rmi.ServerException: RuntimeException; nested exception is:
      java.lang.IllegalArgumentException: wrong number of arguments
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:292)
      at sun.rmi.transport.Transport$1.run(Transport.java:148)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
      at java.lang.Thread.run(Thread.java:534)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
      at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
      at sun.rmi.server.UnicastRef.invoke(Unknown Source)
      at org.jboss.invocation.jrmp.server.JRMPInvoker_Stub.invoke(Unknown Source)
      at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:135)
      at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:96)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:45)
      at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:100)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:85)
      at $Proxy2.register(Unknown Source)
      at com.elementk.client.TestClient.main(TestClient.java:25)
      Caused by: java.rmi.ServerException: RuntimeException; nested exception is:
      java.lang.IllegalArgumentException: wrong number of arguments
      at org.jboss.ejb.plugins.LogInterceptor.handleException(LogInterceptor.java:361)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
      at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
      at org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331)
      at org.jboss.ejb.Container.invoke(Container.java:700)
      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:324)
      at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
      at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
      at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:367)
      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:324)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
      at sun.rmi.transport.Transport$1.run(Transport.java:148)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
      at java.lang.Thread.run(Thread.java:534)Caused by: java.lang.IllegalArgumentException: wrong number of arguments
      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:324)
      at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:683)
      at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:185)
      at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:72)
      at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:84)
      at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:267)
      at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
      at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118)
      at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
      ... 21 more

      If no one can tell me what's wrong with my code, perhaps someone can point me to a complete example of RMI callback that works with JBoss.

        • 1. Re: RMI callback
          davidm

          I have your example code working. When running the code, I got the same exception on the client, however there also was a class loader exception in the sever log related to the the stub (sorry, renamed your test class to fit in with our other tests)
          ....
          16:37:09,218 ERROR [STDERR] java.lang.ClassNotFoundException: No ClassLoaders found for: remote.prototype.TestClient_Stub
          16:37:09,234 ERROR [STDERR] at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:161)
          .....

          Adding the stub to the server's classpath (packaged with the server side classes in the ejb-jar) took care of it and the message from server: 'A message from the EJB' came in fine.

          Another side effect still under investigation, the TestClient will not terminate (no return from main) unless you add a call to UnicastRemoteObject.unexportObject(...) [or an system.exit] at the end of main. [Possibly related to remote reference counting/garbage collection]. If you know the proper convention in such a case, let me know.

          David
          Montreal

          • 2. Re: RMI callback
            jeremystein

            I don't see the class loader exception in my log. Adding the stub in a jar on the server didn't solve my problem -- I still get the "wrong number of arguments" exception. Could you give me more details on your configuration? Are you running rmiregistry on the client? Did you have to do anything with your java policy file?

            • 3. Re: RMI callback
              jeremystein

              Two weeks later, I have finally determined that you were right! I had thrown the client stub into our library directory, but apparently our system is a little buggy and didn't make it available to the EJB. Once I got that stub in the classpath, it worked fine. Thanks, David!

              Now, I'd like to figure out how to get JBoss to load the client stub dynamically, since I'd like to be able to change the client without updating the server with the latest stub. Any pointers on that?