CXF
  1. CXF
  2. CXF-3978

Multiple BusApplicationContext Objects created by CXF

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Cannot Reproduce
    • Affects Version/s: 2.1
    • Fix Version/s: Invalid
    • Component/s: JAX-WS Runtime
    • Labels:
      None
    • Environment:

      Production

    • Estimated Complexity:
      Unknown

      Description

      Hi all,
      Can anyone tell me if there was a known bug or issue wherein CXF creates a new BusApplicationCOntext object for each outgoing Web Service call? I see that while using JCA Connector architecture, SpringBusFactory object creates a new BusApplicationContext object. Is it a bug? I am running CXF in WebContainer thread pool of WAS and as the threads never gets killed due to pool, the BusApplicationContext objects accumulates and results in high GC memory.
      Please help if this is a known bug in this version of CXF? We are in a production down situation due to memory overhead created by BusApplicationContext object size and number of these objects. there is one-one correspondence between BusApplicatioContext to Thread in thread pool which is causing memory to increase.
      The version of cxf-bundle-fuse is 2-1-3-18
      THanks

        Activity

        Hide
        Daniel Kulp added a comment -


        Cannot reproduce with a supported version of CXF. If a testcase can be created using a recent version of CXF, feel free to reopen or log a new issue.

        Show
        Daniel Kulp added a comment - Cannot reproduce with a supported version of CXF. If a testcase can be created using a recent version of CXF, feel free to reopen or log a new issue.
        Hide
        Dhawalpatel added a comment -

        Can anyone please comment on my last comment please?
        Thanks
        Dhawal

        Show
        Dhawalpatel added a comment - Can anyone please comment on my last comment please? Thanks Dhawal
        Hide
        Dhawalpatel added a comment -

        Can anyone else from the development team comment on above, please?
        THanks
        Dhawal

        Show
        Dhawalpatel added a comment - Can anyone else from the development team comment on above, please? THanks Dhawal
        Hide
        Dhawalpatel added a comment -

        Hi Daniel, I just discovered one fact
        When we call connectionSpec.setBusConfigURL before getConnection of CXFConnectionFactory, the issue is coming.
        If I remove this setter, the CXF is spawning ONLY ONE CXF Bus. Can you please comment if this is expected?
        Thanks

        Show
        Dhawalpatel added a comment - Hi Daniel, I just discovered one fact When we call connectionSpec.setBusConfigURL before getConnection of CXFConnectionFactory, the issue is coming. If I remove this setter, the CXF is spawning ONLY ONE CXF Bus. Can you please comment if this is expected? Thanks
        Hide
        Dhawalpatel added a comment -

        Hi Daniel,
        Can you please update on above comment? I am sure its not going to work as SpringBusFactory code is writted as below:
        public Bus createBus(String cfgFiles[], boolean includeDefaults) {
        try

        { return finishCreatingBus(createApplicationContext(cfgFiles, includeDefaults)); }

        catch (BeansException ex)

        { LogUtils.log(LOG, Level.WARNING, "APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null); throw new RuntimeException(ex); }

        }

        and createApplicatioNContext method
        private BusApplicationContext createApplicationContext(String cfgFiles[], boolean includeDefaults) {
        try

        { return new BusApplicationContext(cfgFiles, includeDefaults, context); }

        catch (BeansException ex) {
        LogUtils.log(LOG, Level.WARNING, "INITIAL_APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null);
        ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
        if (contextLoader != BusApplicationContext.class.getClassLoader()) {
        Thread.currentThread().setContextClassLoader(
        BusApplicationContext.class.getClassLoader());
        try

        { return new BusApplicationContext(cfgFiles, includeDefaults, context); }

        finally

        { Thread.currentThread().setContextClassLoader(contextLoader); }

        } else

        { throw ex; }

        }
        }

        creates it without checking if already the BusApplicationContext object exists or not.

        Similar case with ManagedConnectionImpl code wherein it doesnt check for if bus already exists
        This is even the case in 2.1.7 code. I dont think it will resolve this issue.
        The Bus is created by below code:
        final Bus bus = (Bus)bac.getBean(Bus.DEFAULT_BUS_ID); in SpringBusFactory and I see No fixes around this area. Thus the issue is still there.
        Thanks

        Show
        Dhawalpatel added a comment - Hi Daniel, Can you please update on above comment? I am sure its not going to work as SpringBusFactory code is writted as below: public Bus createBus(String cfgFiles[], boolean includeDefaults) { try { return finishCreatingBus(createApplicationContext(cfgFiles, includeDefaults)); } catch (BeansException ex) { LogUtils.log(LOG, Level.WARNING, "APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null); throw new RuntimeException(ex); } } and createApplicatioNContext method private BusApplicationContext createApplicationContext(String cfgFiles[], boolean includeDefaults) { try { return new BusApplicationContext(cfgFiles, includeDefaults, context); } catch (BeansException ex) { LogUtils.log(LOG, Level.WARNING, "INITIAL_APP_CONTEXT_CREATION_FAILED_MSG", ex, (Object[])null); ClassLoader contextLoader = Thread.currentThread().getContextClassLoader(); if (contextLoader != BusApplicationContext.class.getClassLoader()) { Thread.currentThread().setContextClassLoader( BusApplicationContext.class.getClassLoader()); try { return new BusApplicationContext(cfgFiles, includeDefaults, context); } finally { Thread.currentThread().setContextClassLoader(contextLoader); } } else { throw ex; } } } creates it without checking if already the BusApplicationContext object exists or not. Similar case with ManagedConnectionImpl code wherein it doesnt check for if bus already exists This is even the case in 2.1.7 code. I dont think it will resolve this issue. The Bus is created by below code: final Bus bus = (Bus)bac.getBean(Bus.DEFAULT_BUS_ID); in SpringBusFactory and I see No fixes around this area. Thus the issue is still there. Thanks
        Hide
        Dhawalpatel added a comment -

        Hi Daniel,
        Thanks for clarifying!
        I am sorry for being irritating but somehow I do not see that comment mentioned in this bug comments history. I tried to see the changes that he made in ManagedConnectionImpl class but could really make out that infact his changes also included caching the Bus and not call createBus every time. Can you please help me where in which class did he modify to cache the bus creation?
        Thanks
        Dhawal

        Show
        Dhawalpatel added a comment - Hi Daniel, Thanks for clarifying! I am sorry for being irritating but somehow I do not see that comment mentioned in this bug comments history. I tried to see the changes that he made in ManagedConnectionImpl class but could really make out that infact his changes also included caching the Bus and not call createBus every time. Can you please help me where in which class did he modify to cache the bus creation? Thanks Dhawal
        Hide
        Daniel Kulp added a comment -

        The issue isn't the BusApplicationContext, it's the Bus itself. By creating a new Bus per request, it's getting a new BusApplicationContext per request. The fix from Seumas (as per his second comment on that issue) was to cache the Bus and not destroy it for each request thus causing it to have to be recreated.

        Show
        Daniel Kulp added a comment - The issue isn't the BusApplicationContext, it's the Bus itself. By creating a new Bus per request, it's getting a new BusApplicationContext per request. The fix from Seumas (as per his second comment on that issue) was to cache the Bus and not destroy it for each request thus causing it to have to be recreated.
        Hide
        Dhawalpatel added a comment -

        Hi Daniel,
        Thanks for your reply.
        When I checked the CXF-2398, it doesnt look like Seumas fixed anything related to BusApplicationContext objects. But anyway, let me check the code of SpringBusFactory is it was modified to have ONLY one BusApplicationContext object in createBus method. But I assume, you understood my issue properly.
        Let me know if you have any questions in understanding my issue.
        Thanks
        Dhawal

        Show
        Dhawalpatel added a comment - Hi Daniel, Thanks for your reply. When I checked the CXF-2398 , it doesnt look like Seumas fixed anything related to BusApplicationContext objects. But anyway, let me check the code of SpringBusFactory is it was modified to have ONLY one BusApplicationContext object in createBus method. But I assume, you understood my issue properly. Let me know if you have any questions in understanding my issue. Thanks Dhawal
        Hide
        Daniel Kulp added a comment -


        We'd also likely need to know if this is reproducible with CXF 2.3.x (or preferably even 2.5.1)as we don't support 2.1.x anymore.

        Show
        Daniel Kulp added a comment - We'd also likely need to know if this is reproducible with CXF 2.3.x (or preferably even 2.5.1)as we don't support 2.1.x anymore.
        Hide
        Daniel Kulp added a comment -

        You likely need to update to a newer CXF. I think this is related to:

        https://issues.apache.org/jira/browse/CXF-2398

        that is marked fixed in 2.1.7.

        Show
        Daniel Kulp added a comment - You likely need to update to a newer CXF. I think this is related to: https://issues.apache.org/jira/browse/CXF-2398 that is marked fixed in 2.1.7.
        Hide
        Dhawalpatel added a comment -

        Hi Daniel
        Any updates regarding this issue?
        Thanks

        Show
        Dhawalpatel added a comment - Hi Daniel Any updates regarding this issue? Thanks
        Hide
        Dhawalpatel added a comment -

        Also, since BusFactory code puts the instantiated CXFBusImpl Object in the thread's threadLocal, the accumulation increase with increase in thread in ThreadPool. PLease check code of BusFactory.java and SpringBusfactory.java
        Thanks

        Show
        Dhawalpatel added a comment - Also, since BusFactory code puts the instantiated CXFBusImpl Object in the thread's threadLocal, the accumulation increase with increase in thread in ThreadPool. PLease check code of BusFactory.java and SpringBusfactory.java Thanks
        Hide
        Dhawalpatel added a comment -

        The stack trace looks like below for each thread calling the Outgoing Web Service call:

        at org.apache.cxf.bus.spring.BusApplicationContext.<init>(BusApplicationContext.java:97)
        at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:136)
        at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:131)
        at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:121)
        at org.apache.cxf.jca.outbound.ManagedConnectionImpl.getBus(ManagedConnectionImpl.java:314)

        • locked <cf38d300> (a org.apache.cxf.jca.outbound.ManagedConnectionImpl)
          at org.apache.cxf.jca.outbound.ManagedConnectionImpl.createClientProxy(ManagedConnectionImpl.java:265)
        • locked <cf38d300> (a org.apache.cxf.jca.outbound.ManagedConnectionImpl)
          at org.apache.cxf.jca.outbound.ManagedConnectionImpl.createConnectionHandle(ManagedConnectionImpl.java:249)
          at org.apache.cxf.jca.outbound.ManagedConnectionImpl.getConnection(ManagedConnectionImpl.java:149)
          at com.ibm.ejs.j2c.MCWrapper.getConnection(MCWrapper.java:2020)
          at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:625)
          at org.apache.cxf.jca.outbound.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:53)

        This definitely is creating a new CXFBusImpl object and new BusApplicationContext object for each outgoing call. This leads to about 700Mb accumulation of memory since as the Threads in ThreadpoOl grows, the number of these objects will also grow. In Scenario of ThreadPool size of 55 for WAS Webcontainer, the total size of BusApplicationContext exceeds 700M and causes JVMs to crash due to high GC and OOM errors.
        Please check the code on priority as to what can be done to NOT instantiate a new BusapplicationContext by SpringBusFactory?
        Thanks

        Show
        Dhawalpatel added a comment - The stack trace looks like below for each thread calling the Outgoing Web Service call: at org.apache.cxf.bus.spring.BusApplicationContext.<init>(BusApplicationContext.java:97) at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:136) at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:131) at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:121) at org.apache.cxf.jca.outbound.ManagedConnectionImpl.getBus(ManagedConnectionImpl.java:314) locked <cf38d300> (a org.apache.cxf.jca.outbound.ManagedConnectionImpl) at org.apache.cxf.jca.outbound.ManagedConnectionImpl.createClientProxy(ManagedConnectionImpl.java:265) locked <cf38d300> (a org.apache.cxf.jca.outbound.ManagedConnectionImpl) at org.apache.cxf.jca.outbound.ManagedConnectionImpl.createConnectionHandle(ManagedConnectionImpl.java:249) at org.apache.cxf.jca.outbound.ManagedConnectionImpl.getConnection(ManagedConnectionImpl.java:149) at com.ibm.ejs.j2c.MCWrapper.getConnection(MCWrapper.java:2020) at com.ibm.ejs.j2c.ConnectionManager.allocateConnection(ConnectionManager.java:625) at org.apache.cxf.jca.outbound.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:53) This definitely is creating a new CXFBusImpl object and new BusApplicationContext object for each outgoing call. This leads to about 700Mb accumulation of memory since as the Threads in ThreadpoOl grows, the number of these objects will also grow. In Scenario of ThreadPool size of 55 for WAS Webcontainer, the total size of BusApplicationContext exceeds 700M and causes JVMs to crash due to high GC and OOM errors. Please check the code on priority as to what can be done to NOT instantiate a new BusapplicationContext by SpringBusFactory? Thanks

          People

          • Assignee:
            Unassigned
            Reporter:
            Dhawalpatel
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development