cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <>
Subject Re: Problems with lazy loading components
Date Mon, 17 Oct 2005 09:08:05 GMT
Daniel Fagerstrom wrote:
> While working on the block architecture yesterday, I saw that most of 
> the test cases 
> (org.apache.cocoon.test.components.blocks.BlocksManagerTestCase) 
> failed. The problem was that block local files where resolved in wrong 
> context. After having controlled that nothing in the source resolution 
> mechanism had changed since last time I run the tests, I started to 
> suspect the lazy loading of components. After having switch to eager 
> loading everything worked again.
> What happens is the following: The CocoonSourceResolver resolves 
> relative the current processor (via 
> EnvironmentHelper.getCurrentProcessor()) if there is a current 
> processor and otherwise relative the context root from the Avalon 
> context. So, during eager loading of global components there is not 
> yet a current processor, so the source reolution within the components 
> will be relative the root context of the component manager of the 
> component. This is the correct behaviour.
> During lazy loading the source resolution in the component will be 
> relative the context of the processor that it happen to be first used 
> in. This is in general wrong and can be rather confusing and 
> complicated to find what went wrong.

This already happens with eager loading of poolable components. I banged 
my head several times when using i18nTransfomer in a child sitemap of 
the sitemap where it is declared. Depending on the context in which the 
transfomer is instanciated, the relative context it different. The 
result is that if the transformer is created in the context of the child 
sitemap, it doesn't find the i18n dictionaries.

The workaround is to never inherit i18nTransformer in subsitemaps...

> I think the main problem is that we have a global source resolver and 
> try to get the context right during resolution in a smart and subtle 
> (and fragile) way. If we instead create one source reolver within each 
> service manager all source resolution within a specific service 
> manager will be relative to the context of the service manager 
> irrespectible of when the resolution is done, whether it is eager or 
> lazy. It will also simplify the architecture, and maybe we could get 
> rid of the source resolver from the Processor interface.

I already proposed a solution for this in "multi-relative source 
resolving" [1]. We need two source resolvers:
- the current one, which is always relative to the current sitemap.
- another one per service manager, permanently attached to the context 
where the service manager was created.

That's this second resolver that has to be used to access sources 
defined by the context where the component is declared (message 
dictionaries in the case of i18nTransformer). I proposed in the original 
post to store the "manager-relative" resolver in the Context, but 
finally think this is a bad idead, and that it should go in the 

Now most use cases don't really need to care about choosing one or the 
other resolvers if we consider the following definition of the relative 
- during the component setup phase, sources are relative to the location 
where the service manager holding the component is defined,
- during the component usage phase, sources are relative to the current 
sitemap location.

Note that there's nothing new here, as this is what everybody expects, 
but not always happen...

How to implement this? CoreServiceManager needs to keep it's location, 
and ComponentFactory has to set it as the base location when entering 
newInstance() and restore the previous one on exit. That should be 
pretty much all. This will also work with the Swing<->Avalon bridge if 
we do the same context switch around ApplicationContext.getBean().

Now there are still some use cases where a component needs to access the 
manager-relative resolver in the usage phase. It's again the 
i18nTransformer that does some lazy loading of dictionaries. For these 
cases, we can have a specific variant of the SourceResolver role that's 
always bound to the service manager. To load dictionaries relative to 
its configuration location, i18nTransformer would then lookup e.g. 
SourceResolver.ROLE + "/manager".

Hmm... (light bulb!) or even maybe not if it uses its configuration 
location as the base URL for loading dictionaries!!!!! We tend to forget 
the 3-parameters variant of SourceResolver.resolverURI() which allows to 
specify the base URL!

> Anyway, I suggest that we turn of lazy loading until we have solved 
> this issue.

I consider lazy loading an indicator of source resolving flaws and a 
good motivation to fix it for good :-)



Sylvain Wallez                        Anyware Technologies
Apache Software Foundation Member     Research & Technology Director

View raw message