5 Replies Latest reply on Aug 14, 2006 10:39 AM by Tom Elrod

    InstantiationException with client passed proxies

    Chris DeLashmutt Newbie

      I;m trying to code up a little example using JBoss Remoting 1.4.4 in JBoss AS 4.0.4.GA, and JBoss Serialization. This example is based on the "Trasporters sample - proxy" example in the user guide.

      I've got an MBean that manages the lifecycle of a socket based Remoting server that has a few methods in it. The client can get a reference to the server (hosted at socket://localhost:5400/?serializationtype=jboss), and call a method on the server that returns a String with no problems. However, if I try to create a proxy for a pojo on the client and pass that into the server, I get an InstatiationException from within the remoting framework when I call a method on the server and pass in the proxy.

      Here is a snippet from the TestClient main method:

      //Get the remote server
      remote = (TestRemote) TransporterClient.createTransporterClient(
       "socket://localhost:5400/?serializationtype=jboss",
       TestRemote.class);
      
      //Just test out getting a simple String
      String classPath = remote.getMyClasspath();
      System.out.println("Server Classpath: " + classPath);
      
      //Create a new PersonImpl which implements a Person interface
      PersonImpl aPerson = new PersonImpl("Chris DeLashmutt");
      aPerson.setAge(31);
      System.out.println("Asserting Person " + aPerson.getName()
       + " with age of " + aPerson.getAge());
      
      //Create a local server for the Person proxy
      server = TransporterServer.createTransporterServer(
       "socket://localhost:5401/?serializationtype=jboss",
       aPerson, Person.class.getName());
      
      //Create the proxy to pass to the server
      Person personProxy = (Person) TransporterClient
       .createTransporterClient(
       "socket://localhost:5401/?serializationtype=jboss",
       Person.class);
      
      //Pass the person to the server
      remote.assertFact(personProxy);
      
      //Have the server set a random age on the Person through the proxy
      System.out.println("Fireing rules");
      remote.applyRules();
      
      //Show the new age of the person
      System.out.println("Person " + aPerson.getName()
       + " now has age of " + aPerson.getAge());
      


      The server is very simple, and the exception I get is on the server side, but before my method actually gets invoked. The Person interface just specifies a couple getters/setters for name and age, and the PersonImpl is just a POJO with a no-arg constructor, and a String constructor to set the name.

      The exception I get is a SerializationException caused by an InstantiationException. It looks like the error is coming from the Remoting code trying to instantiate an org.jboss.remoting.transport.local.LocalClientInvoker, but there isn't any no-arg constructor for that class, so it fails.

      13:55:11,187 ERROR [ServerThread] failed
      org.jboss.serial.exception.SerializationException: Could not create instance of org.jboss.remoting.transport.local.LocalClientInvoker - org.jboss.remoting.transport.local.LocalClientInvoker
       at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:327)
       at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:239)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:353)
       at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:273)
       at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:241)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:353)
       at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:273)
       at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:241)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.ProxyPersister.readData(ProxyPersister.java:66)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.ArrayPersister.readObjectArray(ArrayPersister.java:196)
       at org.jboss.serial.persister.ArrayPersister.readData(ArrayPersister.java:172)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:353)
       at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:273)
       at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:241)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:353)
       at org.jboss.serial.persister.RegularObjectPersister.defaultRead(RegularObjectPersister.java:273)
       at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:241)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
       at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
       at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
       at org.jboss.serial.io.JBossObjectInputStream.readObjectOverride(JBossObjectInputStream.java:165)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:333)
       at org.jboss.remoting.serialization.impl.jboss.JBossSerializationManager.receiveObject(JBossSerializationManager.java:127)
       at org.jboss.remoting.marshal.serializable.SerializableUnMarshaller.read(SerializableUnMarshaller.java:66)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:350)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
      Caused by: java.lang.InstantiationException: org.jboss.remoting.transport.local.LocalClientInvoker
       at java.lang.Class.newInstance0(Class.java:335)
       at java.lang.Class.newInstance(Class.java:303)
       at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:319)
       ... 44 more
      


      What am I doing wrong here?

        • 1. Re: InstantiationException with client passed proxies
          Tom Elrod Master

          Looks like problem is with the sending of the client which is actually LocalClientInvoker. When create a client that points to a server within the same vm, remoting will internally use a local client invoker (by reference calling) instead of remote client invoker (this is done automatically by default). Since the local client invoker has a dirrect reference on the server invoker, can't send it over the wire to another server.

          A quick work around for this would be to force the use of the remote client invoker (via 'byvalue' for 1.4.x or 'force_remote' for 2.0.0 property - see http://labs.jboss.com/portal/jbossremoting/docs/guide/ch05.html#section-configuration for detals).

          However, this should be something that the local client invoker does internally (basically switch itself to remote when being serialized). Have created a jira issue for this - http://jira.jboss.com/jira/browse/JBREM-575.

          BTW, there has been a good bit of work around transporters done for 2.0.0 release.

          • 2. Re: InstantiationException with client passed proxies
            Chris DeLashmutt Newbie

            I tried using byvalue=true to force a remote invoker to be used, but I'm still getting the same exception. The only difference this time is that remoting is complaining that it can't instantiate org.jboss.remoting.transport.socket.SocketClientInvoker because it doesn't have a no-arg constructor. :)

            14:44:40,578 ERROR [ServerThread] failed
            org.jboss.serial.exception.SerializationException: Could not create instance of org.jboss.remoting.transport.socket.SocketClientInvoker - org.jboss.remoting.transport.socket.SocketClientInvoker
             at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:327)
             at org.jboss.serial.persister.RegularObjectPersister.readData(RegularObjectPersister.java:239)
             at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:411)
             at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:81)
             at org.jboss.serial.objectmetamodel.DataContainer$DataContainerDirectInput.readObject(DataContainer.java:639)
             at org.jboss.serial.persister.RegularObjectPersister.readSlotWithFields(RegularObjectPersister.java:353)
             .... (many more snipped for clarity)
            Caused by: java.lang.InstantiationException: org.jboss.remoting.transport.socket.SocketClientInvoker
             at java.lang.Class.newInstance0(Class.java:335)
             at java.lang.Class.newInstance(Class.java:303)
             at org.jboss.serial.classmetamodel.ClassMetaData.newInstance(ClassMetaData.java:319)
             ... 44 more
            


            I'll try to make the server and client both use remoting 2.0.

            • 3. Re: InstantiationException with client passed proxies
              Tom Elrod Master

              After digging through release notes for 2.0.0.Beta2, see that this was fixed in JBREM-312, so is not going to work for 1.4.x.

              I did create (and close) jira issue for this for 2.0.0.GA (JBREM-575) along with test case under org.jboss.test.remoting.transporter.proxy.local that show it in action (is dumb test case, but you'll get the point). Can also view at:
              http://viewcvs.labs.jboss.com/cgi-bin/viewcvs.cgi/JBossRemoting/src/tests/org/jboss/test/remoting/transporter/proxy/local/
              when ever cvs sync's up.

              • 4. Re: InstantiationException with client passed proxies
                Chris DeLashmutt Newbie

                I tried making the MBean use the new 2.0.0.CR2 release, but I ran into some strange problems. So to help isolate things, I ran the server component outside of the App Server. Basically, I just added a main method to explictly call the startup methods which create the Transporter server. The client remained the same.

                I can now send a proxy to the server for the Person object, and it can work with it. However, when the server tries to call a method (void setAge (int age)) on the Person object proxy that was passed in, I get a ClassNotFoundException:

                Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
                 at $Proxy0.setAge(Unknown Source)
                 at com.foo.server.impl.TestRemoteImpl.applyRules(TestRemoteImpl.java:53)
                 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:585)
                 at org.jboss.remoting.transporter.TransporterHandler.invoke(TransporterHandler.java:74)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:999)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:848)
                 at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:447)
                 at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:534)
                 at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:257)
                 at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
                 at org.jboss.remoting.Client.invoke(Client.java:612)
                 at org.jboss.remoting.Client.invoke(Client.java:604)
                 at org.jboss.remoting.Client.invoke(Client.java:589)
                 at org.jboss.remoting.transporter.TransporterClient.invoke(TransporterClient.java:276)
                 at $Proxy0.applyRules(Unknown Source)
                 at com.foo.client.TestClient.main(TestClient.java:66)
                Caused by: java.lang.ClassNotFoundException: int
                 at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
                 at java.security.AccessController.doPrivileged(Native Method)
                 at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
                 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
                 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
                 at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                 at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
                 at java.lang.Class.forName0(Native Method)
                 at java.lang.Class.forName(Class.java:164)
                 at org.jboss.remoting.transporter.TransporterHandler.invoke(TransporterHandler.java:69)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:999)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:848)
                 at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:447)
                 at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:520)
                 at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:257)
                 at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:163)
                 at org.jboss.remoting.Client.invoke(Client.java:612)
                 at org.jboss.remoting.Client.invoke(Client.java:604)
                 at org.jboss.remoting.Client.invoke(Client.java:589)
                 at org.jboss.remoting.transporter.TransporterClient.invoke(TransporterClient.java:276)
                 at $Proxy0.setAge(Unknown Source)
                 at com.foo.server.impl.TestRemoteImpl.applyRules(TestRemoteImpl.java:53)
                 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:585)
                 at org.jboss.remoting.transporter.TransporterHandler.invoke(TransporterHandler.java:74)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:999)
                 at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:848)
                 at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:447)
                 at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:534)
                 at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:257)
                


                I can't believe that remoting isn't able to sent primitives, so I must be doing something wrong again.

                Any more thoughts?