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.