You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by "Christoph Gaffga (triplemind.com)" <cg...@triplemind.com> on 2008/07/03 14:12:57 UTC

Re: multithreaded Content Aggregator migration from 2.1 to 2.2

hi,

we found the problem in DefaultIncludeCacheManager and fixed it. I just 
submitted a patch together with some more information on the problem.

see:
https://issues.apache.org/jira/browse/COCOON-2216

thanks for your help.

regards,
Christoph


Joerg Heinicke wrote:
> InheritableThreadLocal [1] might be one solution. But being not able to 
> clean up a thread is always a problem in web environment. IIRC Spring 
> used to use InheritableThreadLocal in RequestContextListener, but they 
> changed it to standard ThreadLocal for that reason.
> 
> I don't know if CocoonRunnable mentioned by Grek is another point for 
> potential changes.
> 
> Joerg
> 
> [1] 
> http://java.sun.com/j2se/1.4.2/docs/api/java/lang/InheritableThreadLocal.html 
> 
> 
> On 05.06.2008 09:21, Imran Pariyani wrote:
>> Hello,
>>
>> we have come across this issue .. i posted it on user mailing list and 
>> some one from there suggested me to post it here since it seems to be 
>> bug in cocoon 2.2 .. its a very crucial issue for us.. we cant upgrade 
>> to 2.2  unless we  some how solve or find a work around for this issue ..
>>
>> we have multithreaded Content Aggregator which is based on the 
>> CIncludeTransformer and it also implements 
>> CacheableProcessingComponent for caching .. it used to work fine for 
>> cocoon 2.1.x but with cocoon 2.2 it gives strange error .. it is 
>> actually a generator and it gives error in the generate method ..
>>
>> the code where it gives error
>>
>> // generate...
>>           for (Part part : this.parts) {
>>               if (this.manager.hasService(IncludeCacheManager.ROLE)) {
>>                   part.uri = this.cacheManager.load(part.uri, 
>> this.cachingSession);
>>               } else {
>>                   this.getLogger().error(
>>                           "The ContentAggregator: aggregator cannot 
>> find the IncludeCacheManager");
>>               }
>>           }
>>
>>           // aggregate...
>>           StreamPipe streamPipe = new StreamPipe(this.contentHandler);
>>           for (Part part : this.parts) {
>>               streamPipe.firstElement(part.element, this.rootElement, 
>> part.stripRootElement);
>>               try {
>>                   System.out.println("ParallelContentAgg.part.uri:" + 
>> part.uri);
>>                   this.cacheManager.stream(part.uri, 
>> this.cachingSession, streamPipe);
>>               } finally {
>>                   streamPipe.lastElement(part.element);
>>               }
>>           }
>>
>> it gives the following error
>>
>> Caused by: org.springframework.beans.factory.BeanCreationException: 
>> Error creating bean with name 
>> 'scopedTarget.org.apache.cocoon.el.objectmodel.ObjectModel': Scope 
>> 'request' is not active for the current thread; consider defining a 
>> scoped proxy for this bean if you intend to refer to it from a 
>> singleton; nested exception is java.lang.IllegalStateException: No 
>> thread-bound request found: Are you referring to request attributes 
>> outside of an actual web request? If you are actually operating within 
>> a web request and still receive this message,your code is probably 
>> running outside of DispatcherServlet/DispatcherPortlet: In this case, 
>> use RequestContextListener or RequestContextFilter to expose the 
>> current request.
>>       at 
>> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:293) 
>>
>>       at 
>> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) 
>>
>>       at 
>> org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33) 
>>
>>       at 
>> org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184) 
>>
>>       at $Proxy2.cleanupLocalContext(Unknown Source)
>>       at 
>> org.apache.cocoon.components.source.impl.SitemapSource.toSAX(SitemapSource.java:382) 
>>
>>       at 
>> org.apache.cocoon.components.source.util.SourceUtil.toSAX(SourceUtil.java:111) 
>>
>>       at 
>> org.apache.cocoon.components.source.util.SourceUtil.toSAX(SourceUtil.java:170) 
>>
>>       at 
>> org.apache.cocoon.components.source.SourceUtil.toSAX(SourceUtil.java:63)
>>       at 
>> org.apache.cocoon.transformation.helpers.DefaultIncludeCacheManager$LoaderThread.run(DefaultIncludeCacheManager.java:415) 
>>
>>       at 
>> org.apache.cocoon.environment.CocoonRunnable.doRun(CocoonRunnable.java:64) 
>>
>>       at 
>> org.apache.cocoon.environment.internal.EnvironmentHelper$AbstractCocoonRunnable.run(EnvironmentHelper.java:453) 
>>
>>       at 
>> EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(Unknown 
>> Source)
>>       ... 1 more
>>
>> Grzegorz Kossakowski wrote:
>>> Imran Pariyani pisze:
>>>> Hi
>>>
>>> Hi Imran,
>>>
>>>> last night i wasted 5 hrs overs this without any success .. i guess 
>>>> it has something to do with passing the RequestContextListener to 
>>>> the spring context .. i have initialized the listener in my web.xml 
>>>> and also added the config in applicationcontext.xml .. i checked 
>>>> everything on my end .. everything seems to be fine .. is something 
>>>> wrong with the cachemanager present in cocoon ?
>>>>
>>>> any help will be greatly appreciated !! ..
>>>
>>> Unfortunately, it looks like you stumbled across rather complicated 
>>> (and obscure) bug. It's related to the fact how Spring's request 
>>> scope works (objects are tied to the thread). If you run 
>>> multithreaded aggregation then child threads don't have an access to 
>>> beans defined with 'request' scope because they are visible only in 
>>> parent thread.
>>>
>>> More details below...
>>>
>>> <snip/>
>>>
>>>>> org.apache.cocoon.components.source.impl.SitemapSource.toSAX(SitemapSource.java:382) 
>>>>
>>>>
>>>>
>>>
>>> The failing code is:
>>>             if (touchedOM) {
>>>                 //Because of complicated flow of this source it must 
>>> maintain the cleaness of OM on its own
>>>                 ObjectModel newObjectModel;
>>>                 try {
>>>                     newObjectModel = 
>>> (ObjectModel)manager.lookup(ObjectModel.ROLE);
>>>                 } catch (ServiceException e) {
>>>                     throw new SAXException("Couldn't look up Object 
>>> Model", e);
>>>                 }
>>>                 newObjectModel.cleanupLocalContext();
>>>                 touchedOM = false;
>>>             }
>>> Here, manager.lookup fails because ObjectModel is a bean with request 
>>> scope.
>>>
>>> To be honest, I don't have an idea how this should be fixed. I guess 
>>> it's a bug of CocoonRunnable class but I don't know how to give child 
>>> threads access to parent thread variables in a safe way.
>>>
>>> This would require more investigation that I have no time for at the 
>>> moment, unfortunately.
>>>
>>> I hope it helped you a little to understand the problem. Maybe you 
>>> will find someone on dev@ mailing list that has an idea how to fix it.
>>>
>>
> 

-- 
Triplemind Internet OHG
Berlinerstr. 2
DE-63065 Offenbach
Germany

http://www.triplemind.com
Mail info@triplemind.com
Tel  +49 69 82367670
Fax  +49 69 82367654

Unternehmensdaten: Triplemind OHG
Geschaeftsfuehrung: Christoph Gaffga, Mathias Ziegler
Bankverbindung: Postbank Frankfurt,  BLZ: 50010060, Kto: 563581608, 
IBAN: DE28 5001 0060 0563 5816 08, BIC: PBNKDEFF
Eingetragen im HR Offenbach am Main 40202, USt-IdNr.: DE210080643