1 Reply Latest reply on Nov 10, 2005 9:52 AM by msobkow

    EJB3 and references/handles?

    msobkow

      I'm trying to create a "hidden" session bean (stateful) within a container/wrapper session bean as follows:

       SubObjLclXfc inst = (SubObjLclXfc)ctx.lookup(
       "java:comp/env/myapp/ejb/objserver/local/SubObj" );
      


      I then hold on to the "inst" reference for use in future invocations, some of which need to pass back a remote reference to "inst" to the client. Obviously I can't just pass back inst as it's a local interface and has no context outside the VM.

      I'm a bit concerned about my current code, as I'd expect the address of the interface to change if the bean is swapped off to disk (i.e. passivated and reactivated.) What might be safer/correct is to make inst an Object, and then typecast whenever inst is referenced:

       Object inst = ctx.lookup(
       "java:comp/env/myapp/ejb/objserver/local/SubObj" );
       ....
       SubObjLclXfc useInst = (SubObjLclXfc)inst;
       useInst.myMethod();
      


      That way any "hidden" attributes of the Object would be serialized with the container's reference, whereas typecasting to an interface might lose information needed to relocate the referenced bean.

      According to Page 480 of ejb-3_0-pr-spec-ejbcore.pdf:


      The enterprise bean must not attempt to pass this as an argument or method result. The enterprise bean must pass the result of SessionContext.getBusinessObject, SessionContext.getEJBObject, SessionContext.getEJBLocalObject, EntityContext.getEJBObject, or EntityContext.getEJBLocalObject instead.


      But documentation at this point is a tad sparse.

      In order to deal with passing back a remote reference to the client, I was thinking to add a method to SubObjBean and SubObjLclXfc as follows:
       @SessionContext ctx;
      
       public SubObjRmtXfc getRemoteXfc() {
       Object xfc = ctx.getBusinessObject(
       SubObjRmtXfc.class.getName() );
       return( (SubObjRmtXfc)xfc );
       }
      


      Would this work? Or should I pass back the returned business object without casting and force the client to do some sort of casting ala EJB 2.x narrowing? (i.e. Does getBusinessObject() return the specified interface, or is it an object stub that happens to implement the interface?)

      There is mention of getHandle() in EJB2.x documentation sections of the spec, but I'm not sure how that applies to EJB3.


        • 1. Re: EJB3 and references/handles?
          msobkow

          Just to clarify:

          The reason I'm "hiding" the bean is that while it's owned and used only by the one session, the session client doesn't (and shouldn't) have the information needed to locate the bean.

          The container session bean has additional information about partitioned/federated databases, so it uses different JNDI names to instantiate the actual bean. You wouldn't want that in the client's deployment configuration because then you'd have to synchronize all the client configurations if you merge or split a federation node. This way the client only has to know where it's FEP is located.

          I also simplify the client coding a bit by having the container session "own" all the beans that it instantiates via JNDI lookup. It takes responsibility for calling an @Remove-annotated release() method on those beans, so the client session only has to release() it's container instead of all the referenced beans. That dramatically reduces the chances of memory/EJB leaks due to programmer oversights, network failures, and system crashes.