glassfish
  1. glassfish
  2. GLASSFISH-17281

javax.ejb.AsyncResult in Remote interfaces with DTOs generates ClassCastException on client

    Details

    • Type: Bug Bug
    • Status: In Progress
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 3.1.1_b12
    • Fix Version/s: None
    • Component/s: orb
    • Labels:
      None
    • Environment:

      Windows Vista SP2
      JDK 1.6.0_26

      Description

      Scenario:

      • 2 ear apps say A and B (module-a-ear and module-b-ear)
      • each ear has contains an ejb-jar (module-a-ejb and module-b-ejb)
      • A's ejb exposes remote interface with an @Asyncronous method
      • the asyncronous method returns a serializable DTO (ADto)
      • both A and B have the same copy of A's ejbClient in their ear's root (module-a-ejbClient.jar)

      when a method of B calls a remote asynch method on A, the call is perfomed but when Future<ADto> is done, on module-b-ejb side a ClassCastException is thrown when invoking:
      ADto wrappedDto = futureDto.get();

      EJB 3.1 specs don't make dinstinction about local or remote interface for @Asynchrouse annotation.They also don't put any limitation in Future<V>, so Data Transfer Objects (serializable) must be supported, right?

      In order to have a very simple test case (didn't want to create JEE appclient..) I've annotated module-b-ejb as WebService so that you can call module-b-ejb method via glassfish admin gui webservice tester. You can find a stacktrace in the attached zip file. I also provided the 2 deployable ear files.

      IMHO:
      Debugging on client side (using eclipse debugger) I had a look at classloader of the ADto instance received from A: it's the A's classloader, not B's! It's strange because I tried also to change method in the "old traditional" synch fashion( public ADto doAsync() ) and on client side the returning ADto correclty comes from A's classloader. Does this help?

        Activity

        Hide
        wfsaxton added a comment -

        This bug is very old. Is it really still being worked on? Is there a workaround available?

        This issue still exists in GF 4.1.

        Show
        wfsaxton added a comment - This bug is very old. Is it really still being worked on? Is there a workaround available? This issue still exists in GF 4.1.
        Hide
        juergenschmied added a comment -

        I get this problem after upgrading from 3.1.2 to 3.1.2.2. A application that was working before is now broken with this error. Would it help do use a Future<ByteArrayOutputStream> an do serialization/deserialization by myself? It looks like this bug does not affect build-in classes.

        Thanks!

        Show
        juergenschmied added a comment - I get this problem after upgrading from 3.1.2 to 3.1.2.2. A application that was working before is now broken with this error. Would it help do use a Future<ByteArrayOutputStream> an do serialization/deserialization by myself? It looks like this bug does not affect build-in classes. Thanks!
        Hide
        Harshad Vilekar added a comment -

        Cheng and I exchanged email on this - and decided to target this issue post 3.1.2

        Show
        Harshad Vilekar added a comment - Cheng and I exchanged email on this - and decided to target this issue post 3.1.2
        Hide
        Cheng Fang added a comment -

        re-assign to orb team for further evaluation.

        Show
        Cheng Fang added a comment - re-assign to orb team for further evaluation.
        Hide
        Cheng Fang added a comment -

        In org/glassfish/pfl/dynamic/copyobject/impl/ClassCopierOrdinaryImpl (in modules/pfl-dynamic.jar)
        obj.getClass() is called to get the Class, which is then used to create a class copier, which in turn creates the constructor. It is hence associated with the class loader of the source object, not the target.

        This part of the code is executed to copy all fields of a source object.

        After changing to use thread context class loader in instead of
        obj.getClass(), it worked without CCE. There could be other places the kind of changes are also necessary. Also not clear about the full implication or side effects.

        Show
        Cheng Fang added a comment - In org/glassfish/pfl/dynamic/copyobject/impl/ClassCopierOrdinaryImpl (in modules/pfl-dynamic.jar) obj.getClass() is called to get the Class, which is then used to create a class copier, which in turn creates the constructor. It is hence associated with the class loader of the source object, not the target. This part of the code is executed to copy all fields of a source object. After changing to use thread context class loader in instead of obj.getClass(), it worked without CCE. There could be other places the kind of changes are also necessary. Also not clear about the full implication or side effects.

          People

          • Assignee:
            Harshad Vilekar
            Reporter:
            vins4java
          • Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: