On 2011-08-26 2:18, Steven Dolg wrote:
Some things I found out so far:

3) The problem is not the pointcut itself, but the beans that are available for AOP post-processing. Introducing beans into the Spring context that have been obtained from outside the context, potentially created with a foreign class loader is dangerous. (In this case it's the ServletContext that is exposed via org.apache.cocoon.spring.configurator.impl.ServletContextFactoryBean by the spring-configurator)
exactly

4) Other people have run into the similar problems: e.g.
http://forum.springsource.org/showthread.php?109227-AspectJ-Problem-warning-can-t-determine-superclass-of-missing-type-Proxy28 http://forum.springsource.org/showthread.php?82421-Is-it-normal-for-AspectJ-to-post-process-OSGi-references

I've found also other interesting references:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=306915 this is what causes problem, more than a year old already

https://jira.springsource.org/browse/SPR-7678 another interesting bug-report... I've just checked, my simplistic Cocoon example that is basically empty web-app with just two pages eats up 500 MB right after start!!! Is it what called "light-weight"? At least it seems that somebody is trying to do something about this bug, but it is still unknown when it will be fixed. Until then it is a serious problem also for Cocoon with its heavy use of SpringAOP.

Technically, all those solutions are available to us.
1) requires to switch to Load-Time Weaving. This might or might not have side-effects. I couldn't even begin to speculate...
I do not understand you here... isn't it already load-time? Or do you mean Weaving instead of Proxying? Then this is definitely not as easy as proxying in terms of configuration.

2a) don't expose the ServletContext in the spring-configurator or prevent it from receiving a proxy (mark as synthetic bean?)
I've verified that marking it synthetic does the think, everything works after that. Not exposing it at all is also an option as there is already mechanism in Spring that allows to get ServletContext injected - ServletContextAware interface. ServletContextFactoryBean javadoc tells that it created to avoid a dependency to Spring ServletContextAware interface, but it implements this interface itself, so - what is the difference, the dependency is already there?

2b) add jetty-webapp to the dependencies of your webapp, so that the class is visible
It is a hack that works only for "mvn jetty:run". Breaking JEE container class-loading is not an option. Cocoon is not in the position to dictate servlet container how to load classes.

3) Downgrade to 1.6.6
As AspectJ folks knows about the problem for long time and do nothing to solve it we cannot expect it to be fixed any time soon. 1.6.6 is quite old already, should Cocoon limit progress? What if someone needs a new version of AspectJ because of new features? While it is easiest fix I don't think Cocoon should limit its users to some specific old versions of libraries except when there is obvious bugs in some versions that are fixed new newer versions and not become a 'feature'.

I think 1)  and 2a) are risky.
3) is odd, because we just upgraded for some reason.
2b) is quite a kludge but a very precise, rather risk-free and completely and easily reversible one, if required.
Strongly disagree, IMHO (2a) is the only way to go.

My fix with synthetic looks like this:

protected void registerComponents(Element settingsElement, ParserContext parserContext) {
        super.registerComponents(settingsElement, parserContext);
        // add the servlet context as a bean
final RootBeanDefinition beanDef = createBeanDefinition(ServletContextFactoryBean.class.getName(), null, false);
        beanDef.setSynthetic(true);
register(beanDef, ServletContext.class.getName(), parserContext.getRegistry());
    }

I could also create a patch, but it already can be easily applied. More problems with that cocoon-spring-configurator snapshots are not deploying currently to maven snapshots repository, i.e. - organizational.

I am even more in favor of completely removing this and use native Spring means to inject ServletContext when needed (the ServletContextAware). This way ServletConfig also could be injected (with ServletConfigAware). But unfortunately it can break some existing Cocoon 2.2 apps.

Reply via email to