Am 25.08.2011 21:11, schrieb Steven Dolg:
Am 23.08.2011 00:00, schrieb Igor Malinin:
Hello, C3 developers.
After C3 has updated its dependencies to use AspectJ 1.6.11 it become
impossible to use it with Jetty 7.
The problem could be easily reproduced in cocoon-sample-webapp by
replacing maven-jetty-plugin of Jetty 6 with the following (actually
any Jetty 7 version will give the same result):
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.4.5.v20110725</version>
<configuration>
<connectors>
<connector
implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8890</port>
<maxIdleTime>30000</maxIdleTime>
</connector>
</connectors>
<webAppSourceDirectory>${project.build.directory}/${project.artifactId}-${project.version}</webAppSourceDirectory>
<contextPath>/</contextPath>
</configuration>
</plugin>
I've tried to debug this problem and it seems that it is related to
two things.
1) AspectJ in version 1.6.7 changed the way how it does static
optimizations, so some cases that were working before are broken
because it has not enough information at the optimization time.
2) Cocoon Servlet Service Framework is the one of such cases. It
fails on
cocoon-servlet-service-impl-1.2.0/META-INF/cocoon/spring/cocoon-ssf-urlhandler-advice.xml
where it tries to apply pointcut "execution(*
javax.servlet.Servlet.service(..)) and bean(*/embedded)" to the
ServletContext. The problem is that Jetty 7 returns an implementation
instance that is isolated from the web-app classloader. It is
perfectly legal and I believe same thing will happen on most modern
JEE containers, especially when many of them are moving to OSGI and
alternatives. AspectJ tries to resolve this hidden class by name and
fails, so it cannot validate if it can do optimizations and then
fails with the described error.
A quick google search returned some interesting threads.
I'll dig around a little and see what I can find out / fix.
Nice catch!
Some things I found out so far:
1) AspectJ does not support short-circuit evaluation of pointcuts, so
doing something like "!within(org.eclipse.jetty..*) and execution(...)"
won't help
2) Spring-AOP does use AspectJ, but you don't get to touch any of the
nice settings/properties you can read about in the AspectJ documentation
(we'd need to use Load-Time Weaving for that)
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)
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
The solutions other people seem to choose are:
1) Configure AspectJ to ignore those classes or ignore that specific error.
2) Make sure those objects are not subject to proxying / fix the class
loader problems.
3) Downgrade to an AspectJ version before optimized matching was introduced.
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...
2a) don't expose the ServletContext in the spring-configurator or
prevent it from receiving a proxy (mark as synthetic bean?)
2b) add jetty-webapp to the dependencies of your webapp, so that the
class is visible
3) Downgrade to 1.6.6
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.
:/
I think it serious problem and need to be solved... As I can see SSF
has not been changed for long time, so do we have anyone who
remembers how it works and is able to fix it? Where to submit
bugreport? SSF is technically in Cocoon 2 JIRA, while almost no
activity happening there and I am not sure it will be noticed there,
while Cocoon 3 does not have SSF component...
That might indeed become a problem, because C2 and C3 are sharing that
code and it actually belongs to C2.
But lets take this one step at a time.
There are some indications that this could be resolved by
configuration...
--------------------------------------------
The exception trace is:
2011-08-23 00:47:57.865:WARN::Failed startup of context
o.m.j.p.JettyWebAppContext{/,file:/W:/worksources/cocoon3/cocoon3/cocoon-sample-webapp/target/cocoon-sample-webapp-3.0.0-beta-1-SNAPSHOT/},file:/W:/worksources/cocoon3/cocoon3/cocoon-sample-webapp/target/cocoon-sample-webapp-3.0.0-beta-1-SNAPSHOT/org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.apache.cocoon.blockdeployment.BlockResourcesHolder' defined in
URL
[jar:file:/W:/worksources/cocoon3/cocoon3/cocoon-sample-webapp/target/cocoon-sample-webapp-3.0.0-beta-1-SNAPSHOT/WEB-INF/lib/cocoon-block-deployment-1.1.0.jar!/META-INF/cocoon/spring/cocoon-blockdeployment-resourcesholder.xml]:
Cannot resolve reference to bean 'javax.servlet.ServletContext' while
setting bean property 'servletContext'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'javax.servlet.ServletContext':
Post-processing of the FactoryBean's object failed; nested exception
is
org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException:
warning can't determine modifiers of missing type
org.eclipse.jetty.webapp.WebAppContext$Context| [Xlint:cantFindType]
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at
org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at
org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at
org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:640)
at
org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:229)
at
org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1208)
at
org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586)
at
org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:449)
at
org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:179)
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at
org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at
org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:164)
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at
org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:224)
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at
org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:258)
at
org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:67)
at
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:58)
at
org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:468)
at
org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:408)
at
org.mortbay.jetty.plugin.JettyRunMojo.execute(JettyRunMojo.java:589)
at
org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at
org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at
org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at
org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at
org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at
org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at
org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'javax.servlet.ServletContext':
Post-processing of the FactoryBean's object failed; nested exception
is
org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException:
warning can't determine modifiers of missing type
org.eclipse.jetty.webapp.WebAppContext$Context| [Xlint:cantFindType]
at
org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:165)
at
org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:102)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1429)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:245)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
...