Hi Eduardo, ok, I think I see what's happening there. The BusFactory has a thread key based weak hashmap storing references to the thread default bus. AFAICS in the screenshot you have 5 entries in the map, which is coherent considering thread pooling (I assume your 'invokePaymentService' method below is run e.g. as a consequence of a servlet or ejb3 invocation). Each time you call new PaymentWebService_Service constructor, that calls the javax.xml.ws.Service, which goes through the JAXWS SPI Provider resolution. Both the Apache CXF Provider impl and the extension of it that is returned when running in JBoss AS 7 basically get the current thread default bus and use if for creating your jaxws client. So due to thread pooling you end up getting one of those 5 bus instances and keep on adding stuff in it each time you call the 'invokePaymentService'. You're not destroying either the thread that keeps a reference to the bus nor the bus. I'd say you have multiple options here. One is to avoid building up a new jaxws client each time you call the 'invokePaymentService' method: build it once, cache it and reuse it (or a pool of instances of it). Another option is manually starting a new Bus before creating the jaxws client, build the client, run it and finally destroy the thread bus.
Cheers Alessio On 02/26/2013 01:59 PM, Eduardo Andrade wrote: > Hi Alessio, > thanks for replying. > > Somehow the screenshot was filtered and didn't get through to the mailing > list. > > Here's a link for it: > https://dl.dropbox.com/u/2030514/mem_leak_apache_cxf_2.4.6.png > > To answer your question, we are using boiler-plate code to connect to an > external service using WS-Security headers. > > 1) We generate the client proxy code and JAXB classes from the WSDL using > Maven 2.2; > > 2) We then use code as per below to connect to the service: > > protected SetupPaymentResponseData > invokePaymentService(SetupPaymentRequestData payRequest) { > try { > WebServiceLookup paymentWS = > webServiceLookupDao.findByCode(PS_CONFIG); > String wsdlLocation = paymentWS.getUrl() + "?wsdl"; > > PaymentWebService_Service ss = new > PaymentWebService_Service(new URL(wsdlLocation)); > PaymentWebService port = ss.getPort(PaymentWebService.class); > > Map<String, Object> props = new HashMap<String, Object>(); > props.put(WSHandlerConstants.ACTION, > WSHandlerConstants.USERNAME_TOKEN); > props.put(WSHandlerConstants.PASSWORD_TYPE, > WSConstants.PW_TEXT); > props.put(WSHandlerConstants.USER, paymentWS.getUsername()); > props.put(WSHandlerConstants.PW_CALLBACK_REF, new > ClientPasswordCallback(paymentWS.getPassword())); > > Client client = ClientProxy.getClient(port); > Endpoint cxfEndpoint = client.getEndpoint(); > WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(props); > cxfEndpoint.getOutInterceptors().add(wssOut); > > SetupPaymentResponseData response = > port.setupPayment(payRequest); > return response; > > } catch (MalformedURLException murle) { > throw new RuntimeException(murle); > } > } > > In order to use the JBoss AS 7 modules, the application contains a > *jboss-deployment-structure.xml > *file with the following: > > <?xml version="1.0" encoding="UTF-8"?> > <jboss-deployment-structure> > <deployment> > <dependencies> > <module name="org.apache.cxf"/> > <module name="org.apache.ws.security"/> > <module name="org.hibernate.validator"/> > <module name="javax.validation.api"/> > </dependencies> > </deployment> > </jboss-deployment-structure> > > > Many thanks for your help, > Eduardo > > > > On 26 February 2013 12:45, Alessio Soldano <[email protected]> wrote: > >> Hi Eduardo, >> I didn't find any attached screenshot. >> I'm interested in having a look at your case; are you manually handling >> the bus creation & destruction or not? >> Can you provide more info on your client? >> >> Cheers >> Alessio >> >> On 02/26/2013 01:35 PM, Eduardo Andrade wrote: >>> Hello all, >>> I'm using Apache CXF 2.4.6 as a web service client (SOAP) and the >>> application uses the jars provided by JBoss AS7 as modules. No Apache >>> CXF jars are provided with the application. >>> >>> We are seeing OutOfMemory: Java Heap Space in our systems and I've done >>> some analysis on this. >>> >>> While I don't have all the pieces of the puzzle yet, it looks like the >>> org.apache.cxf.BusFactory class keeps threads in a WeakHashMap >>> (threadBusses). >>> The number of threads keeps increasing and they don't seem to be garbage >>> collected? >>> >>> I analised a heap dump (after forcing GC) using Eclipse MAT and result >>> suggests memory leak as per screenshot attached. >>> >>> I am using Apache CXF in other projects with no issues. One main >>> difference is that this is the only project where we use Apache CXF as a >>> Web Service client but we don't use Spring Framework for dependency >>> injection (we use CDI instead). >>> >>> Could this be the cause of it? >>> Do you have any idea how can we fix this? >>> >>> Thanks in advance, >>> >>> -- >>> Eduardo Andrade >>> [email protected] <mailto:[email protected]> >>> >>> www.linkedin.com/in/eduardofandrade >>> <http://www.linkedin.com/in/eduardofandrade> >> >> >> -- >> Alessio Soldano >> Web Service Lead, JBoss >> > > > -- Alessio Soldano Web Service Lead, JBoss
