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.


Reply via email to