2 Replies Latest reply on Oct 17, 2003 2:47 AM by eske

    AOP remoting in DR3

    eske

      We are currently working on our Master's thesis which is about documenting and evaluating the AOP in JBoss 4. The idea is, that we would like to document how new AOP services can be written.

      But... We are currently quite stuck on getting the already implemented AOP services to work - in particular AOP Remoting. We haven't been able to find any examples on using the AOP services, so we have looked at the tests in the testsuite from the jboss-head CVS module. We have practically copied the approach from the AOP Remoting test, but it does not work. Nor can we get the AOP Remoting test to work either.

      What we have done so far:
      We have created an MBean that can create a remote proxy for our POJO, thus making it a remote POJO. This part seems to work. We have registered our POJO (it is called Item) by calling "Dispatcher.singleton.registerTarget("item", item);" as stated in the AOP documentation.
      We created an AOP deployment jar-file (.aop) that includes the required jboss-aop.xml file.
      We created a .sar that contains our MBean as well as the .aop file.
      Once copied into the server deployment dir, it seems to deploy alright.

      The problem arises when we try to execute the JUnit test case (that is not deployed on the server and thus not in the same JVM). The test calls the "invoke" method on the RMIAdaptor - exactly as in the AOP Remoting test case.
      From the testcase failure output we can verify that the Item class has had a proxy created for it.
      [junit] ------------- Standard Error -----------------
      [junit] java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
      [junit] java.lang.ClassNotFoundException: org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl (no security manager: RMI class loader disabled)
      [junit] at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:169)
      [junit] at org.jboss.jmx.adaptor.rmi.RMIAdaptorImpl_Stub.invoke(Unknown Source)
      [junit] at jboss.thesis.inventory.test.InventoryRemoteTestCase.testRemoting(InventoryRemoteTestCase.java:136)
      [junit] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      [junit] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      [junit] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      [junit] at java.lang.reflect.Method.invoke(Method.java:324)

      .... and so on through the JUnit framework, and then:

      [junit] Caused by: java.lang.ClassNotFoundException: org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl (no security manager: RMI class loader disabled)
      [junit] at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:371)
      [junit] at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
      [junit] at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:631)
      [junit] at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:257)
      [junit] at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:200)
      [junit] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513)
      [junit] at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
      [junit] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)
      [junit] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
      [junit] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
      [junit] at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:297)
      [junit] at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:146)
      [junit] ... 16 more
      [junit] ------------- ---------------- ---------------

      The problem seems to be getting the changed class definition to the client. Since the class must be downloaded dynamically from the server to the client, we tried installing an RMISecurityManager on the client (the test case). This, however, causes the test to halt and a NullPointerException to be thrown on the server:

      15:28:04,805 ERROR [STDERR] java.lang.NullPointerException
      15:28:04,805 ERROR [STDERR] at org.jboss.mx.loading.LoadMgr3.beginLoadTask(LoadMgr3.java:118)
      15:28:04,805 ERROR [STDERR] at org.jboss.mx.loading.UnifiedClassLoader3.loadClass(UnifiedClassLoader3.java:159)
      15:28:04,805 ERROR [STDERR] at java.lang.ClassLoader.loadClass(ClassLoader.java:282)
      15:28:04,805 ERROR [STDERR] at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
      15:28:04,805 ERROR [STDERR] at org.jboss.remoting.loading.ObjectInputStreamWithClassLoader.resolveClass(ObjectInputStreamWithClassLoader.java:72)
      15:28:04,805 ERROR [STDERR] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1513)
      15:28:04,815 ERROR [STDERR] at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1435)
      15:28:04,815 ERROR [STDERR] at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1626)
      15:28:04,815 ERROR [STDERR] at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
      15:28:04,815 ERROR [STDERR] at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
      15:28:04,815 ERROR [STDERR] at org.jboss.remoting.loading.ClassUtil.deserialize(ClassUtil.java:58)
      15:28:04,815 ERROR [STDERR] at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:129)
      15:28:04,815 ERROR [STDERR] at org.jboss.remoting.transport.socket.SocketServerInvoker$Client.run(SocketServerInvoker.java:208)

      It appears that we get the same reaction - with regards to the halt of the client and NullPointerException - when we run the AOPRemoting test (the AOPRemoting test case times out after a while).

      Our main concern is being able to establish a remote connection to a POJO. Maybe we just don't understand JBoss Remoting or maybe something is not working yet. Whatever the reason, we would be very happy to receive insights into what can make this work.

      Help Obi-Wan Kenobi. You're my only hope!

      Kind regards

      Eske

        • 1. Re: AOP remoting in DR3
          eske

          UPDATE:
          We have discovered one of the problems. The AOPRemoting test case states that we should register the POJO and not the proxy for it with the Dispatcher. When we register the proxy instead of the POJO, we can deploy the POJO and get an instance sent to back to the client from the server. So now our InventoryService MBean code looks like this:
          public Item registerItem(){
          ... //try catch removed for brevity
          log.info("Testing getting an Item remotely");
          Item item = new ItemImpl();
          item.setName( "SomeName" );
          Item proxyItem = (Item) Remoting.createRemoteProxy( "item", item.getClass(), "socket://localhost:5150" );
          Dispatcher.singleton.registerTarget( "item", proxyItem ); //previously: ...registerTarget( "item", item );
          return proxyItem;
          ...
          }

          On the client (our test case) we can get an Item with the following code (that calls the registerItem method):
          //try catch removed for brevity
          RMIAdapter server = (RMIAdaptor) new InitialContext( props ).lookup( connectorName );
          Item proxyItem = (Item) server.invoke( testerName, "registerItem", noparams, nosig );

          We can do reflective calls on the proxyItem object and class and call toString and other methods inherited from Object. But we cannot call any method native to the Item and ItemImpl interface/class such as getName() on the proxy. When the method getName is called we get a StackOverflowError on the server side:
          10:40:08,487 INFO [InventoryService] Testing getting an Item remotely
          10:40:10,140 ERROR [STDERR] java.lang.StackOverflowError
          10:40:10,150 ERROR [STDERR] at java.lang.ThreadLocal.get(ThreadLocal.java:115)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.ThreadMetaData.getMetaData(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.ThreadMetaData.resolve(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.Invocation.getMetaData(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.Dispatcher.invoke(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.remoting.IsLocalInterceptor.invoke(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.Invocation.invokeNext(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.ClassAdvisor.dynamicInvoke(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl._dynamicInvoke(ItemImpl.java)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.Dispatcher.invoke(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.remoting.IsLocalInterceptor.invoke(Unknown Source)
          10:40:10,150 ERROR [STDERR] at org.jboss.aop.Invocation.invokeNext(Unknown Source)
          10:40:10,160 ERROR [STDERR] at org.jboss.aop.ClassAdvisor.dynamicInvoke(Unknown Source)
          10:40:10,160 ERROR [STDERR] at org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl._dynamicInvoke(ItemImpl.java)

          And on the client
          [junit] Testcase: testRemoting took 2,934 sec
          [junit] Caused an ERROR
          [junit] null
          [junit] java.lang.StackOverflowError
          [junit] at java.lang.ThreadLocal.get(ThreadLocal.java:115)
          [junit] at org.jboss.aop.ThreadMetaData.getMetaData(Unknown Source)
          [junit] at org.jboss.aop.ThreadMetaData.resolve(Unknown Source)
          [junit] at org.jboss.aop.Invocation.getMetaData(Unknown Source)
          [junit] at org.jboss.aop.Dispatcher.invoke(Unknown Source)
          [junit] at org.jboss.aop.remoting.IsLocalInterceptor.invoke(Unknown Source)
          [junit] at org.jboss.aop.Invocation.invokeNext(Unknown Source)
          [junit] at org.jboss.aop.ClassAdvisor.dynamicInvoke(Unknown Source)
          [junit] at org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl._dynamicInvoke(ItemImpl
          .java)
          [junit] at org.jboss.aop.Dispatcher.invoke(Unknown Source)
          [junit] at org.jboss.aop.remoting.IsLocalInterceptor.invoke(Unknown Source)
          [junit] at org.jboss.aop.Invocation.invokeNext(Unknown Source)
          [junit] at org.jboss.aop.ClassAdvisor.dynamicInvoke(Unknown Source)
          [junit] at org.jboss.aop.proxy$jboss.thesis.inventory.model.ItemImpl._dynamicInvoke(ItemImpl.j

          Has anyone any idea as to why that is?

          Regards
          Eske

          • 2. Re: AOP remoting in DR3
            eske

            We found he problem. As stated in the AOP documentation on Remoting the real object should be registered in the Dispatcher and not the proxy. Instead the proxy should be bound to JNDI where clients outside the JBoss JVM can get hold of it.
            Once this has been set up it appears to work.

            Eske