cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joerg Heinicke <joerg.heini...@gmx.de>
Subject Re: multithreaded Content Aggregator migration from 2.1 to 2.2
Date Thu, 05 Jun 2008 16:53:24 GMT
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.
>>
> 

Mime
View raw message