glassfish
  1. glassfish
  2. GLASSFISH-4021

Resouce Injection does not work in HandlerChain due to EJB initialization order (non-deterministic)

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: V3
    • Fix Version/s: 4.1
    • Component/s: ejb_container, web_services
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: All

      Description

      --------
      Problem
      --------
      1. Resource injections fails when using HandlerChain that have a
      EJB/Resource injected that is an EJB/JNDI. And one gets
      "Handler xxxxx instance injection failed : Exception attempting to inject
      Resolved Ejb-Ref xxxx/bean@jndi: - > xxxxx]

      The issues is that assuming we have 2 EJB and we want to have

      • EJB B exposed as Webservice and handle a HandlerChain handler
        So we have
        @Stateless
        @WebService
        @HandlerChain(file = "handle.xml")
        public void EJBBBean { ... }
      • We do not care above EJB A
      • Note that the handler is
        public class handler implements SOAPHanlder { @EJB EJBBBean bean; .... }
      • Now when one deploy this depending on the ordering
        of initialization of EJB, sometimes
        EJBA, EJBB and this works but if sometimes it is
        EJBB, EJBA then resource injection fails
      • The issues is that the following happens where it seems when
        a EJB is exposed as WebService and have a handler,
        a) The EJB is created and the handler is created
        b) The handler will be injected but then the issue is
        that THERE is IT may be possible that at the time
        the dependency is not met (since EJBA is not loaded or initialized
        nor registered to the JNDI even)

      com.sun.enterprise.InjectionException: Exception attempting to inject Resolved
      Ejb-Ref org.test.ws.FailInjectionHandler/bean@jndi: - > b5Bean into class
      org.test.ws.FailInjectionHandler
      at
      com.sun.enterprise.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:391)
      at
      com.sun.enterprise.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:206)
      at
      com.sun.enterprise.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:100)
      at
      com.sun.enterprise.webservice.WsUtil.processConfiguredHandlers(WsUtil.java:2529)
      at
      com.sun.enterprise.webservice.WsUtil.configureJAXWSServiceHandlers(WsUtil.java:2570)
      at
      com.sun.enterprise.webservice.EjbRuntimeEndpointInfo.prepareInvocation(EjbRuntimeEndpointInfo.java:294)
      at
      com.sun.enterprise.webservice.EjbRuntimeEndpointInfo.initRuntimeInfo(EjbRuntimeEndpointInfo.java:342)
      at
      com.sun.enterprise.webservice.WebServiceEjbEndpointRegistry.registerEjbWebServiceEndpoint(WebServiceEjbEndpointRegistry.java:122)
      at
      com.sun.ejb.containers.StatelessSessionContainer.initializeHome(StatelessSessionContainer.java:329)
      at
      com.sun.ejb.containers.ContainerFactoryImpl.createContainer(ContainerFactoryImpl.java:345)
      at
      com.sun.enterprise.server.AbstractLoader.loadEjbs(AbstractLoader.java:550)
      at
      com.sun.enterprise.server.ApplicationLoader.doLoad(ApplicationLoader.java:188)

      • Now, this problem does not seems to be that the system does not resolve ordering
        Since writing more EJB seems to say that the GF system tends to order the EJB
        module
        However, there seems to be some race or data structure ordering issue since
        that the EJB module loading sequence on every stop/start is different and
        it is possible to get a EJB processing order that does not work.

      --------------------
      Testcase and details
      --------------------
      1. Get the attached NB6 ejbdeptest.zip and deploy
      This testcase have many a few EJB modules to make this easier to hit this
      Deploy ejbdeptest.ear

      2. Stop/Start (asadmin stop-domain/start-domain)
      and look for the injection failure. (REPEAT until failure is SEEN)
      (grep SEVERE)

      3. [Unpredictable and repeat (2) until SEVERE happens like below]

      [#......|SEVERE|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=20;_ThreadName=httpSSLWorkerThread-14849-2;_RequestID=3a6b0964-02e0-419f-acc0-49c651e2916b;|Handler
      org.test.ws.FailInjectionHandler instance injection failed : Exception
      attempting to inject Resolved Ejb-Ref
      org.test.ws.FailInjectionHandler/bean@jndi: - > b5Bean into class
      org.test.ws.FailInjectionHandler|#]

      3. Note some tracing does indicate that Bean processing via getEjbDescriptors()
      varies sometimes and below is a failure sequence. (It is unknown
      why the behaviour on the EJB processed changes sometimes)

      [#.....|INFO|sun-appserver9.1|javax.enterprise.system.co
      re.classloading|_ThreadID=10;_ThreadName=main;|[DEBUG] AbstractLoader org.test.s
      lsb.e0Bean org.test.slsb.b6Bean org.test.slsb.b3Bean org.test.slsb.b2Bean or
      g.test.slsb.b4Bean org.test.slsb.b1Bean org.test.slsb.b5Bean org.test.slsb.b0
      Bean org.test.slsb.e1Bean org.test.slsb.zfailBean org.test.slsb.z0Bean org.t
      est.slsb.z1Bean org.test.slsb.e2Bean |#]

        Activity

        gfuser9999 created issue -
        Hide
        Hong Zhang added a comment -

        Assign to Mahesh for initial investigation. Also addding Bhakti to the Cc.

        Attaching CWeng's suggested solutions below:
        =============================================
        And so i suppose plain common-sense must be used (which would then indicate the
        system should be able to tell that a Handler class is used by WebserviceX and
        the Handler class need Y, so Y must be initialized by X.

        Even if there is no LOAD order, one may presume that creation of ALL EJB should
        be done first and then on 2nd part the creation of all Webservices that those
        EJB expose is done.
        At this point the EJB and Webservice step for a EJB is coupled together....

        Show
        Hong Zhang added a comment - Assign to Mahesh for initial investigation. Also addding Bhakti to the Cc. Attaching CWeng's suggested solutions below: ============================================= And so i suppose plain common-sense must be used (which would then indicate the system should be able to tell that a Handler class is used by WebserviceX and the Handler class need Y, so Y must be initialized by X. Even if there is no LOAD order, one may presume that creation of ALL EJB should be done first and then on 2nd part the creation of all Webservices that those EJB expose is done. At this point the EJB and Webservice step for a EJB is coupled together....
        Hide
        Mahesh Kannan added a comment -

        The problem is that the handlers are created probably way too early.

        The Container calls
        WebServiceEjbEndpointRegistry.registerEjbWebServiceEndpoint() during container
        initialization time which causes the handlers to be instantiated (which inturn
        causes injection). We need to delay the instantiation of the handlers till the
        dependent EJBs are processed.

        One way to do that is to provide two methods:
        1. One to register the the EjbService endpoint which WILL NOT call
        WsUtil.processConfiguredHandlers()

        2. The other method (say createConfiguredHandlers()) can create and call
        InjectionManager.injectInstance(handler)

        Once the above methods are in place the StatelessContainer can call the second
        method from doAfterApplicationDeployed().

        I am assigning this to Bhakti to implement the above two methods.

        Show
        Mahesh Kannan added a comment - The problem is that the handlers are created probably way too early. The Container calls WebServiceEjbEndpointRegistry.registerEjbWebServiceEndpoint() during container initialization time which causes the handlers to be instantiated (which inturn causes injection). We need to delay the instantiation of the handlers till the dependent EJBs are processed. One way to do that is to provide two methods: 1. One to register the the EjbService endpoint which WILL NOT call WsUtil.processConfiguredHandlers() 2. The other method (say createConfiguredHandlers()) can create and call InjectionManager.injectInstance(handler) Once the above methods are in place the StatelessContainer can call the second method from doAfterApplicationDeployed(). I am assigning this to Bhakti to implement the above two methods.
        Hide
        Bhakti Mehta added a comment -

        Looking into it

        Show
        Bhakti Mehta added a comment - Looking into it
        Hide
        harpreet added a comment -

        Based on input from Bhakti, assigning issue to next release

        Show
        harpreet added a comment - Based on input from Bhakti, assigning issue to next release
        Hide
        sanandal added a comment -

        "Reclassifying as P4 because this issue is not deemed "must fix" for this v2.1
        release whose primary release driver is SailFin.
        This issue will be scrubbed after this release and will be given the right
        priority for the next release."

        Show
        sanandal added a comment - "Reclassifying as P4 because this issue is not deemed "must fix" for this v2.1 release whose primary release driver is SailFin. This issue will be scrubbed after this release and will be given the right priority for the next release."
        kenaiadmin made changes -
        Field Original Value New Value
        issue.field.bugzillaimportkey 4021 35625
        Hide
        ramapulavarthi added a comment -

        I have n't run any tests but seeing the code in v3.1, we should run into the same problem.
        Can't forward port the patches CR6653050 and CR6750245 as the code in v3 is little different from v2.1.
        The fix needs to go into EJB container code to change the way we intialize and load the ejb web services.

        Show
        ramapulavarthi added a comment - I have n't run any tests but seeing the code in v3.1, we should run into the same problem. Can't forward port the patches CR6653050 and CR6750245 as the code in v3 is little different from v2.1. The fix needs to go into EJB container code to change the way we intialize and load the ejb web services.
        ramapulavarthi made changes -
        Fix Version/s 3.1 [ 10968 ]
        Affects Version/s V3 [ 10981 ]
        Affects Version/s 9.1peur1 [ 10975 ]
        Priority Minor [ 4 ] Major [ 3 ]
        Hide
        Bhakti Mehta added a comment -

        Reassigning to Rama since he has already looked into this issue . My inclination is to exclude this for this release but will wait for Rama's input

        Show
        Bhakti Mehta added a comment - Reassigning to Rama since he has already looked into this issue . My inclination is to exclude this for this release but will wait for Rama's input
        Bhakti Mehta made changes -
        Assignee Bhakti Mehta [ bhaktimehta ] ramapulavarthi [ ramapulavarthi ]
        Hide
        ramapulavarthi added a comment -

        This requires changes in EJB Container to change the way EJB ws are loaded and needs coordination with EJB team. Adding V3.1 excludes as this is risky to make this change now.

        Show
        ramapulavarthi added a comment - This requires changes in EJB Container to change the way EJB ws are loaded and needs coordination with EJB team. Adding V3.1 excludes as this is risky to make this change now.
        ramapulavarthi made changes -
        Tags 3_1-exclude
        Hide
        Nazrul added a comment -

        This bug has been around for few releases now. Based on inputs from Bill, I am setting target for 3.2 release with P2 priority so that it gets fixed. If we do not want to fix this bug, please close it.

        Show
        Nazrul added a comment - This bug has been around for few releases now. Based on inputs from Bill, I am setting target for 3.2 release with P2 priority so that it gets fixed. If we do not want to fix this bug, please close it.
        Nazrul made changes -
        Fix Version/s 3.2 [ 10969 ]
        Fix Version/s 3.1 [ 10968 ]
        Priority Major [ 3 ] Critical [ 2 ]
        Chris Kasso made changes -
        Fix Version/s 3.2 [ 10969 ]
        Fix Version/s 9.2 [ 11147 ]
        Hide
        8086 added a comment -

        We have been waiting for a fix for three years now. As of now, our application needs to be redeployed until it works. This might take anywhere from 1 redeploy to 15 redeploys to get it working.

        If you are not fixing it, is there a way to work around it in our code that can remove the pain of innumerous redeploys?

        Show
        8086 added a comment - We have been waiting for a fix for three years now. As of now, our application needs to be redeployed until it works. This might take anywhere from 1 redeploy to 15 redeploys to get it working. If you are not fixing it, is there a way to work around it in our code that can remove the pain of innumerous redeploys?
        Hide
        kumara added a comment -

        -> Martin Grebac for evaluation.

        Show
        kumara added a comment - -> Martin Grebac for evaluation.
        kumara made changes -
        Assignee ramapulavarthi [ ramapulavarthi ] Martin Grebac [ snajper ]
        Martin Grebac made changes -
        Assignee Martin Grebac [ snajper ] Lukas Jungmann [ jungicz ]
        Lukas Jungmann made changes -
        Component/s web_services [ 10623 ]
        Lukas Jungmann made changes -
        Fix Version/s 4.0 [ 10970 ]
        Srini made changes -
        Fix Version/s 4.0.1 [ 16061 ]
        Fix Version/s 4.0 [ 10970 ]
        Lukas Jungmann made changes -
        Tags 3_1-exclude 3_1-exclude 4_0-release-notes
        Gail Risdal made changes -
        Tags 3_1-exclude 4_0-release-notes 3_1-exclude 4_0-release-notes 4_0-release-notes-drafted
        Hide
        Gail Risdal added a comment -

        Added the following to the release notes:

        Resource Injection does not work in HandlerChain due to EJB initialization order (non-deterministic) (4021)

        Description
        EJB module deployment may fail when an EJB that is exposed as a web service, and which has a handler, is initialized before an EJB on which it has dependencies. This is caused by the way the EJB container initializes and loads EJB web services.

        Workaround
        EJB initialization usually happens in alphabetical order. Rename the EJBs so that the EJB exposed as a web service is initialized after the EJB on which it has dependencies.

        In the following example, B is initialized first together with handler X, which expects C to be available but it is not, and deployment fails. The workaround is to rename B to D (for example), so lexicographically it follows C, in which case C should be initialized first and be available for injection to X.

        EJB module sth:

        @Stateless public class C

        {...}
        @Stateless @WebService @HandlerChain(file = "handlers.xml") public class B {...}

        handlers.xml:

        <?xml version="1.0" encoding="UTF-8"?>
        <jws:handler-chains ...>
        <jws:handler-chain>
        <jws:handler>
        <jws:handler-class>X</jws:handler-class>
        </jws:handler>
        </jws:handler-chain>
        </jws:handler-chains>

        Handler:

        </jws:handler-chains>
        @EJB private C;
        ...}

        Show
        Gail Risdal added a comment - Added the following to the release notes: Resource Injection does not work in HandlerChain due to EJB initialization order (non-deterministic) (4021) Description EJB module deployment may fail when an EJB that is exposed as a web service, and which has a handler, is initialized before an EJB on which it has dependencies. This is caused by the way the EJB container initializes and loads EJB web services. Workaround EJB initialization usually happens in alphabetical order. Rename the EJBs so that the EJB exposed as a web service is initialized after the EJB on which it has dependencies. In the following example, B is initialized first together with handler X, which expects C to be available but it is not, and deployment fails. The workaround is to rename B to D (for example), so lexicographically it follows C, in which case C should be initialized first and be available for injection to X. EJB module sth: @Stateless public class C {...} @Stateless @WebService @HandlerChain(file = "handlers.xml") public class B {...} handlers.xml: <?xml version="1.0" encoding="UTF-8"?> <jws:handler-chains ...> <jws:handler-chain> <jws:handler> <jws:handler-class>X</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> Handler: </jws:handler-chains> @EJB private C; ...}
        Gail Risdal made changes -
        Tags 3_1-exclude 4_0-release-notes 4_0-release-notes-drafted 3_1-exclude 4_0-release-notes 4_0-release-notes-completed 4_0-release-notes-drafted
        Hide
        Gail Risdal added a comment -

        Fixed the example in the release notes (first line in the "Handler" section; release notes document has proper formatting/indentation):

        EJB module sth:

        @Stateless public class C

        {...}
        @Stateless @WebService @HandlerChain(file = "handlers.xml") public class B {...}

        handlers.xml:

        <?xml version="1.0" encoding="UTF-8"?>
        <jws:handler-chains ...>
        <jws:handler-chain>
        <jws:handler>
        <jws:handler-class>X</jws:handler-class>
        </jws:handler>
        </jws:handler-chain>
        </jws:handler-chains>

        Handler:

        public class X implements SOAPHandler<SOAPMessageContext>

        { @EJB private C; ...}
        Show
        Gail Risdal added a comment - Fixed the example in the release notes (first line in the "Handler" section; release notes document has proper formatting/indentation): EJB module sth: @Stateless public class C {...} @Stateless @WebService @HandlerChain(file = "handlers.xml") public class B {...} handlers.xml: <?xml version="1.0" encoding="UTF-8"?> <jws:handler-chains ...> <jws:handler-chain> <jws:handler> <jws:handler-class>X</jws:handler-class> </jws:handler> </jws:handler-chain> </jws:handler-chains> Handler: public class X implements SOAPHandler<SOAPMessageContext> { @EJB private C; ...}
        Romain Grécourt made changes -
        Fix Version/s 4.1 [ 16387 ]
        Fix Version/s 4.0.1 [ 16061 ]

          People

          • Assignee:
            Lukas Jungmann
            Reporter:
            gfuser9999
          • Votes:
            5 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated: