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.