6 Replies Latest reply on Sep 22, 2008 2:53 PM by dmlloyd

    Using customized RMI socket factory with JBOSSSerialization

      Hello all,

      We are trying to imrove RMI performance in one client-server RMI application. we customized RMI socket factory (client and server), which uses customized Socket and ServerSocket, which use JBOSSObjectInputStraem and JBOSSObjectOutputStraem (is this the correct way to use jboss serialization in RMI?).

      One flow in the client application invoke many time Naming.lookup() on the server rmi registry.

      If not using the customized socket factory (hence not using jboss serialization) - everything works great. If using the custmozied socket factories, OutOfMemoryError is raised:

      java.lang.OutOfMemoryError: unable to create new native thread
      at java.lang.Thread.start0(Native Method)
      at java.lang.Thread.start(Thread.java:597)
      at sun.rmi.transport.DGCClient$EndpointEntry.(DGCClient.java:231)
      at sun.rmi.transport.DGCClient$EndpointEntry.lookup(DGCClient.java:202)
      at sun.rmi.transport.DGCClient.registerRefs(DGCClient.java:120)
      at sun.rmi.transport.ConnectionInputStream.registerRefs(ConnectionInputStream.java:80)
      at sun.rmi.transport.StreamRemoteCall.releaseInputStream(StreamRemoteCall.java:138)
      at sun.rmi.transport.StreamRemoteCall.done(StreamRemoteCall.java:292)
      at sun.rmi.server.UnicastRef.done(UnicastRef.java:431)
      at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
      at java.rmi.Naming.lookup(Naming.java:84)
      at com.commons.pattern.barakota.HashRAMRMIClient.lookup(HashRAMRMIClient.java:483)
      at com.commons.pattern.css.rmi.RMICSSClient.initializeDelegatesPool(RMICSSClient.java:70)
      at com.commons.pattern.css.CSSPeer.init(CSSPeer.java:35)
      at com.commons.pattern.barakota.HashRAMRMIClient.(HashRAMRMIClient.java:36)
      at com.storing.context.StoringContext$HashRAMBooter.run(StoringContext.java:908)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
      at java.lang.Thread.run(Thread.java:619)

      Can you please assist with debugging this behaviour?

      Thanks,

      Barak.

        • 1. Re: Using customized RMI socket factory with JBOSSSerializat

          By the way, the application is running with Java6.0.

          Another question, is there a way to contact directly with the developer or maintainer of this project?

          10x,

          Barak.

          • 2. Re: Using customized RMI socket factory with JBOSSSerializat
            clebert.suconic

            I'm sorry I didn't realize this post before...

            This would require some debugging.... Maybe a testcase to reproduce this problem.


            With the information you sent, I have no idea what's happening.

            • 3. Re: Using customized RMI socket factory with JBOSSSerializat

               

              "clebert.suconic@jboss.com" wrote:
              I'm sorry I didn't realize this post before...

              This would require some debugging.... Maybe a testcase to reproduce this problem.


              With the information you sent, I have no idea what's happening.


              Ok, here it comes...

              I've extended the Socket class:

              public class JBOSSSocket extends Socket
              {
               /* The InputStream used by the socket. */
               private InputStream in = null;
              
               /* The OutputStream used by the socket */
               private OutputStream out = null;
              
               public JBOSSSocket( String host, int port ) throws UnknownHostException, IOException
               {
               super( host, port );
               }
              
               public JBOSSSocket()
               {
               super();
               }
              
               /*
               * Returns a stream of type XorInputStream.
               */
               public synchronized InputStream getInputStream() throws IOException
               {
               if( in == null )
               {
               in = new JBossObjectInputStream( super.getInputStream() );
               }
               return in;
               }
              
               /*
               *Returns a stream of type XorOutputStream.
               */
               public synchronized OutputStream getOutputStream() throws IOException
               {
               if( out == null )
               {
               out = new JBossObjectOutputStream( super.getOutputStream() );
               }
               return out;
               }
              
              }
              



              I've extended the ServerSocket class:

              public class JBOSSServerSocket extends ServerSocket
              {
               /*
               * Constructor for class XorServerSocket.
               */
               public JBOSSServerSocket( int port ) throws IOException
               {
               super( port );
              
               }
              
               /*
               * Creates a socket of type XorSocket and then calls
               * implAccept to wait for a client connection.
               */
               public Socket accept() throws IOException
               {
               Socket s = new JBOSSSocket();
               implAccept( s );
               return s;
               }
              
              }
              
              


              Then, I've extended RMIServerSocketFactory:

              
              public class JBOSSServerSocketFactory implements RMIServerSocketFactory
              {
              
               @Override
               public ServerSocket createServerSocket( int port ) throws IOException
               {
               // TODO Auto-generated method stub
               return new JBOSSServerSocket( port );
               }
              
              }
              
              



              Then, I've extended RMIClientSocketFactory:

              
              public class JBOSSClientSocketFactory implements RMIClientSocketFactory, Serializable
              {
              
               public JBOSSClientSocketFactory()
               {
               super();
               }
               /**
               *
               */
               private static final long serialVersionUID = 1L;
              
               @Override
               public Socket createSocket( String host, int port ) throws IOException
               {
               return new JBOSSSocket( host, port );
               }
              
              }
              
              



              In the server side application, instaed of using:

              
              Remote stub = UnicastRemoteObject.exportObject( this, 0 );
              Naming.rebind( name, stub );
              
              


              I changhed to

              
              Remote stub = UnicastRemoteObject.exportObject( this, 0, new JBOSSClientSocketFactory(), new JBOSSServerSocketFactory() );
              
              Naming.rebind( name, stub );
              
              


              After all that, I started the server side application and the client side application.
              As I mentioned before, when the client side application is booting, it performs 2000 calls of Naming.lookup() with the url of the server application. After few calles an exception raised:

              java.lang.OutOfMemoryError: unable to create new native thread
              at java.lang.Thread.start0(Native Method)
              at java.lang.Thread.start(Thread.java:597)
              at sun.rmi.transport.DGCClient$EndpointEntry.(DGCClient.java:231)
              at sun.rmi.transport.DGCClient$EndpointEntry.lookup(DGCClient.java:202)
              at sun.rmi.transport.DGCClient.registerRefs(DGCClient.java:120)
              at sun.rmi.transport.ConnectionInputStream.registerRefs(ConnectionInputStream.java:80)
              at sun.rmi.transport.StreamRemoteCall.releaseInputStream(StreamRemoteCall.java:138)
              at sun.rmi.transport.StreamRemoteCall.done(StreamRemoteCall.java:292)
              at sun.rmi.server.UnicastRef.done(UnicastRef.java:431)
              at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
              at java.rmi.Naming.lookup(Naming.java:84)
              at com.commons.pattern.barakota.HashRAMRMIClient.lookup(HashRAMRMIClient.java:483)
              at com.commons.pattern.css.rmi.RMICSSClient.initializeDelegatesPool(RMICSSClient.java:70)
              at com.commons.pattern.css.CSSPeer.init(CSSPeer.java:35)
              at com.commons.pattern.barakota.HashRAMRMIClient.(HashRAMRMIClient.java:36)
              at com.storing.context.StoringContext$HashRAMBooter.run(StoringContext.java:908)
              at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
              at java.lang.Thread.run(Thread.java:619)

              If running both application without the customized RMI socket factory, everything working without any problems.

              Can you please assist with debugging this behaviour?

              Thanks,

              Barak.





              • 4. Re: Using customized RMI socket factory with JBOSSSerializat
                clebert.suconic

                I just remembered looking into this when JBSER was being originally developed.

                RMI is strictly tight integrated with ObjectInputStream. It will use a lot of java.rmi.MarshalledObjects (or javax.. I don't remember now).

                Because of that I had an effect such has ObjectInputStream Marshalling JBossObjectInputStream... and then objectINputStream, what used a lot of memory and caused some performance issues.

                I suggest you taking a look on JBoss-Remoting2. It has a more light weight approach to remote calls, it supports JBSER, and it will have another cool Marshalling mechanism that David Lloyd is working on.

                if you have access to IRC, I hang a lot on #jboss-remoting, IRC@freenode. David Lloyd would also be a good person to be talking to.

                • 5. Re: Using customized RMI socket factory with JBOSSSerializat

                  Hi,

                  Ok, thanks for clearing this point. I'l check the project you mentioned... Is it stable already?

                  Thanks again,

                  Barak.

                  • 6. Re: Using customized RMI socket factory with JBOSSSerializat
                    dmlloyd

                    JBoss Remoting 2 is stable (2.5.0 is the latest). In development is JBoss Remoting 3, which is a yet better overall design; however that version is just shy of the first beta release so it's not quite stable yet (though we should have at least one stable release out by the end of this year).

                    Check out http://www.jboss.org/jbossremoting/ for more information.