0 Replies Latest reply on Jan 10, 2007 5:25 AM by espenwn

    Array of abstract class serializable error with EJB3 SSB/JBo

    espenwn

      Hi,
      I'm writing an SSB method that is returning an array where the elements are an abstract type.

      The abstract base class is like this:

      public abstract class MyBaseClass implements Serializable {
       private String baseName;
      
       protected MyBaseClass() {
       }
      
       public String getBaseName() {
       return baseName;
       }
      
       public void setBaseName(String baseName) {
       this.baseName = baseName;
       }
      }


      The concrete class is like this

      public class MyConcreteClass extends MyBaseClass {
      
       private String concreteName;
      
       public MyConcreteClass() {
       }
      
       public String getConcreteName() {
       return concreteName;
       }
      
       public void setConcreteName(String concreteName) {
       this.concreteName = concreteName;
       }
      }


      The SSB is like this

      public interface IMyTestService {
       MyBaseClass[] loadMyBaseClasses();
      }
      
      @Stateless
      @Remote(IMyTestService.class)
      public class MyTestService implements IMyTestService {
      public MyBaseClass[] loadMyBaseClasses() {
       int no = 10;
       MyConcreteClass[] res = new MyConcreteClass[no];
       for (int i = 0; i < no; i++) {
       //create the concrete class instances
       res = new MyConcreteClass("This is my class");
       }
       return res;
       }
       }


      When calling this method from an remote client the following error occurs:
      java.lang.ClassNotFoundException: [Lcom.omx.condico.server.service.remote.test.MyConcreteClass;
       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 org.jboss.remoting.loading.RemotingClassLoader.loadClass(RemotingClassLoader.java:50)
       at org.jboss.remoting.loading.ObjectInputStreamWithClassLoader.resolveClass(ObjectInputStreamWithClassLoader.java:139)
       at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1544)
       at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
       at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1591)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
       at org.jboss.aop.joinpoint.InvocationResponse.readExternal(InvocationResponse.java:122)
       at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1755)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1717)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
       at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.receiveObject(JavaSerializationManager.java:128)
       at org.jboss.remoting.marshal.serializable.SerializableUnMarshaller.read(SerializableUnMarshaller.java:66)
       at org.jboss.remoting.transport.socket.SocketClientInvoker.transport(SocketClientInvoker.java:279)
       at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:143)
       at org.jboss.remoting.Client.invoke(Client.java:525)
       at org.jboss.remoting.Client.invoke(Client.java:488)
       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
       at $Proxy0.loadMyBaseClasses(Unknown Source)


      The concrete class is not declared explicit in the remote interface, but if I do an explicit declaration of an array of the concrete class like this
      public interface IMyTestService {
      
       //dummy declaration for explicit import of concrete class
       MyConcreteClass[] dummy = new MyConcreteClass[0];
      
       MyBaseClass[] loadMyBaseClasses();
      }


      the serialization works fine. Note: it is not working by only importing the concrete class, the array must be declares as shown above for it to work.


      My question is if this is an known bug in how JBoss are loading classes? Has anybody experienced this an come up with a more elegant work around than the one described above?

      It is worth mentioning that I stumbled into this problem when migrating SSB from EJB2 to EJB3. The service above worked fine implemented in EJB2 , deployed in the same container and environment.

      Thanks,
      Espen