[ 
https://issues.apache.org/jira/browse/CXF-2164?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12702424#action_12702424
 ] 

Daniel Kulp commented on CXF-2164:
----------------------------------


>From a IM chat I had with Bharath:   (posted here so all can benefit)

(11:00:12) rbharathganesh: What Francois Masurel is saying about the 
ThreadLocal leak seems to be correct
(11:00:39) rbharathganesh: If you look at ClientImpl we never unset the req and 
resp contexts
(11:00:39) jdkulp: Yea, I'm just not sure how to go about fixing it.  :-(
(11:00:49) rbharathganesh: I have something in mind
(11:00:59) rbharathganesh: Just wanted to confirm with you before doing it
(11:01:27) jdkulp: The part in the WebServiceContext server side should already 
be fixed.
(11:01:35) rbharathganesh: If you look at his latest comment on the bug: 
(11:01:35) jdkulp: I think he's looking at 2.1.4 code.
(11:01:36) rbharathganesh: //There is no try/finally around 
WebServiceContextImpl.setMessageContext and WebServiceContextImpl.clear in 
org.apache.cxf.jaxws.JAXWSMethodInvoker invoke method. But as long no exception 
is throw in between it should'nt be a problem. 
(11:01:41) rbharathganesh: This is incorrect
(11:01:48) rbharathganesh: We have already fixed this
(11:01:49) rbharathganesh: Oh yes
(11:01:56) jdkulp: Yea.   It WAS broken in 2.1.4.
(11:01:58) rbharathganesh: Sorry did not rread what you typed :-(
(11:02:39) rbharathganesh: But yes the second part seems to be right
(11:03:07) jdkulp: Yea.   If you have a good idea to fix it, I'm all ears.  :-)
(11:03:31) jdkulp: Maybe a weak ref in the thread local and a strong ref in the 
ClientImpl?
(11:04:22) rbharathganesh: hmmm.. But how about explicitly  clearing it in 
JaxWsClientProxy?
(11:04:45) jdkulp: The issue is "when to clear it".
(11:05:41) rbharathganesh: In JaxWsClientProxy#invoke(), Before retuning the 
result to the user? 
(11:06:40) jdkulp: You cannot clear the response context then.
(11:06:53) jdkulp: Or they obviously couldn't get the response stuff.
(11:07:23) jdkulp: Plus, if you make 3 invokes, the original stuff in the 
context needs to still be used.
(11:09:15) rbharathganesh: Dan I guess I am missing something
(11:09:21) rbharathganesh: // if you make 3 invokes, the original stuff in the 
context needs to still be used.
(11:09:23) jdkulp: or I am...  :-)
(11:10:04) rbharathganesh: Is there any state to be maintained beyond the scope 
of the invoke method?
(11:10:22) jdkulp: The state of the request context is for ALL invokes on that 
thread.
(11:10:24) jdkulp: So yes.
(11:10:39) jdkulp: If I set the ENDPOINT_URL in the request context, then call 
invoke 10 times, all 10 should go to that URL.
(11:10:54) rbharathganesh: Oh Yes!
(11:16:41) jdkulp: One option could be to use a WeakHashMap<Thread, Map<...>> 
in client impl instead of thread locals.
(11:17:03) jdkulp: Thus, when clientImpl is garbage collected, so would that 
map and everything it points to.
(11:17:30) rbharathganesh: Yeah....
(11:17:33) jdkulp: If a thread goes away, it's map would be gc'd
(11:18:47) rbharathganesh: In his case, the clientImpl goes away right?
(11:18:54) jdkulp: I assume so.  :-)
(11:19:09) jdkulp: I think when the war/app is undeployed, it should go away.
(11:19:11) rbharathganesh: The thread going away would mostly never happen 
right?
(11:19:33) jdkulp: Maybe, maybe not.    It could be a workqueue that 
grows/shrinks on demand.
(11:19:38) rbharathganesh: The web server would anyway pool these threads
(11:19:40) rbharathganesh: yeah right
(11:19:40) jdkulp: In which case it COULD go away.
(11:19:46) rbharathganesh: Yeah

> CXFBusImpl never removed from ThreadLocal, generates permgen out of memory 
> error after some redeployments
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: CXF-2164
>                 URL: https://issues.apache.org/jira/browse/CXF-2164
>             Project: CXF
>          Issue Type: Bug
>          Components: Bus
>    Affects Versions: 2.1.4
>            Reporter: Francois Masurel
>         Attachments: cxf_threadlocal.jpg, 
> Heap_Walker_Incoming_References.zip, threadlocal.patch
>
>
> I've found this message on a mailing list recently, and it doesn't seem to 
> have been resolved as we have the same problem with version 2.1.4 of CXF on 
> one of our webapp :
> Hello CXF users,
> I've been  working on figuring out why our JBoss servers keep going down with 
> permgen out
> of memory exceptions when we redeploy our war files. To do this I had been 
> using a profiler
> to inspect the WebAppClassloader to find out what was keeping it from being 
> garbage collected.
> One such culprit was the class org.apache.cxf.BusFactory
> The BusFactory has a ThreadLocal in which it stores a copy of CXFBusImpl. 
> However, this isn't
> getting cleaned up properly when the war is undeployed. I noticed that 
> CXFBusImpl has a shutdown
> method that calls BusFactory.setDefaultBus(null) which in turn sets the value 
> stored in the
> ThreadLocal to null. However, this doesn't seem to be getting called.
> The way we are using CXF from spring is with the following 
> WEB-INF/services.xml file in our
> war:
>   <beans xmlns="http://www.springframework.org/schema/beans"; 
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
>     xmlns:amq="http://activemq.org/config/1.0"; 
> xmlns:jaxws="http://cxf.apache.org/jaxws";
>     xmlns:http-conf="http://cxf.apache.org/transports/http/configuration";
>     xsi:schemaLocation="
>       http://www.springframework.org/schema/beans 
> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
>       http://cxf.apache.org/transports/http/configuration 
> http://cxf.apache.org/schemas/configuration/http-conf.xsd
>       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
>       http://activemq.org/config/1.0 
> http://activemq.apache.org/schema/core/activemq-core-5.0.0.xsd";
>     default-autowire="byType">
>     <import resource="classpath:META-INF/cxf/cxf.xml" />
>     <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
>     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
>     <jaxws:endpoint id="helloService" implementor="#helloSvc" 
> address="/HelloService" />
>   </beans>
> I'm not really sure why this Bus.shutdown() isn't getting called or even who 
> is responsible
> for calling it. I tried doing something along the lines of:
>   WebApplicationContext webContext = 
> WebApplicationContextUtils.getRequiredWebApplicationContext(context);
>   if (webContext.containsBean("cxf")) {
>     CXFBusImpl cxfBus = (CXFBusImpl) webContext.getBean("cxf");
>     cxfBus.shutdown(true);
>   }
> But that didn't work. What I eventually ended up doing was to have the 
> following hack in the
> shutdown sequence of our webapp:
>   Field field = org.apache.cxf.BussFactory.class.getDeclaredField("localBus");
>   field.setAccessible(true);
>   ThreadLocal<?> localBus = (ThreadLocal<?>) field.get(null);
>   localBus.remove();
> This did work but obviously it is a bit of an ugly hack. Is there something 
> that needs to
> be included in our service.xml file to tell spring how to cleanup CXF? Is 
> this maybe a bug
> in CXF that the CXFBusImpl.shutdown(Boolean) just isn't getting called at all 
> or maybe that
> in BusFactory.setThreadDefaultBus(Bus) that there should be some check such 
> as:
>   if (bus == null) {
>     localBus.remove();
>   } else {
>     localBus.set(bus);
>   }
> Or maybe some combination of all of these. I'm reasonably new to CXF, Spring, 
> and all this
> stuff so I apologize ahead of time if there is some obvious solution that I 
> just didn't come
> across but I've been trying to scour the CXF and Spring documentation for 
> some idea of the
> correct way to do this and why BusFactory is keeping its ThreadLocal but I 
> can't figure it
> out.
> Thanks!
> Ben Dean
> Software Engineer
> Ontario Systems, LLC

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to