Leszek Gawron (JIRA)
2016-09-28 09:16:20 UTC
Leszek Gawron created COCOON-2353:
-------------------------------------
Summary: Cocoon 2.2 in servlet 3.0 environment fails to initialize when webjars present on classpath.
Key: COCOON-2353
URL: https://issues.apache.org/jira/browse/COCOON-2353
Project: Cocoon
Issue Type: Bug
Components: * Cocoon Core
Affects Versions: 2.2
Reporter: Leszek Gawron
have found a problem that prevents deploying cocoon to 3.0 containers if the webapp contains webjars - by webjar I mean a jar containing META-INF/resources folder which is specially treated by sevlet container (the resources from that folder are served by container itself bypassing any webapp setup).
This happens on jetty 9.x. No matter if I set webapp to be 2.5 servlet compliant or 3.0.
Does not happen on jetty 8 which is ancient as of now.
I try running my app in embedded Jetty 9 - it works - as long as there is no actual .war - there is no scanning for META-INF resources.
As soon as I build a war this is how a configured context looks like:
startup of context ***@5bcab519{/,[
file:///C:/cygwin/tmp/jetty-0.0.0.0-8080-root.war-_-any-1513195852101013802.dir/webapp/,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/modernizr-2.8.3.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/openlayers-3.2.0.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/bootstrap-3.3.2.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/jquery-1.11.1.jar!/META-INF/resources],UNAVAILABLE}
{C:\temp\jetty-gemini\gemini/root.war}
suddenly there is more than one root for static resources.
This yields following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cocoon.Processor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Unable to initialize Avalon component with role org.apache.cocoon.Processor; nested exception is org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:759)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:434)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:843)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:533)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:816)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1404)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1366)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:520)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561)
at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
at org.eclipse.jetty.server.Server.start(Server.java:411)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.Server.doStart(Server.java:378)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1516)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1441)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jetty.start.Main.invokeMain(Main.java:214)
at org.eclipse.jetty.start.Main.start(Main.java:457)
at org.eclipse.jetty.start.Main.main(Main.java:75)
Caused by: org.springframework.beans.factory.BeanCreationException: Unable to initialize Avalon component with role org.apache.cocoon.Processor; nested exception is org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.apache.cocoon.core.container.spring.avalon.AvalonBeanPostProcessor.postProcessBeforeInitialization(AvalonBeanPostProcessor.java:258)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 54 more
Caused by: org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.apache.cocoon.components.treeprocessor.TreeProcessor.configure(TreeProcessor.java:230)
at org.apache.avalon.framework.container.ContainerUtil.configure(ContainerUtil.java:202)
at org.apache.cocoon.core.container.spring.avalon.AvalonBeanPostProcessor.postProcessBeforeInitialization(AvalonBeanPostProcessor.java:246)
... 57 more
Caused by: java.net.MalformedURLException: context://sitemap.xmap could not be found. (possible context problem)
at org.apache.cocoon.components.source.impl.ContextSourceFactory.getSource(ContextSourceFactory.java:128)
at org.apache.cocoon.components.source.CocoonSourceResolver.resolveURI(CocoonSourceResolver.java:153)
at org.apache.cocoon.components.source.CocoonSourceResolver.resolveURI(CocoonSourceResolver.java:183)
at org.apache.cocoon.components.treeprocessor.TreeProcessor.configure(TreeProcessor.java:228)
... 59 more
This is the problematic ContextSourceFactory code:
public Source getSource(String location, Map parameters) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Creating source object for " + location);
}
// Lookup resolver
SourceResolver resolver = null;
try {
resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
// Remove the protocol and the first '/'
final int pos = location.indexOf(":/");
final String scheme = location.substring(0, pos);
final String path = location.substring(pos + 2);
// fix for #24093, we don't give access to files outside the context:
if (path.indexOf("../") != -1) {
throw new MalformedURLException("Invalid path ('../' is not allowed) : " + path);
}
URL u;
// Try to get a file first and fall back to a resource URL
String actualPath = this.servletContext.getRealPath(path);
if (actualPath != null) {
u = new File(actualPath).toURL();
} else {
u = this.servletContext.getResource(path);
}
if (u != null) {
Source source = resolver.resolveURI(u.toExternalForm());
if ( parameters != null
&& BooleanUtils.toBoolean("force-traversable")
&& this.servletContext != null
&& !(source instanceof TraversableSource) ) {
final Set children = this.servletContext.getResourcePaths(path + '/');
if ( children != null ) {
source = new TraversableContextSource(source, children, this, path, scheme);
}
}
return source;
}
final String message = location + " could not be found. (possible context problem)";
getLogger().info(message);
throw new MalformedURLException(message);
} catch (ServiceException se) {
throw new SourceException("Unable to lookup source resolver.", se);
} finally {
this.manager.release(resolver);
}
}
If I use jetty 8
String actualPath = this.servletContext.getRealPath(path);
never returns null - even if the path we ask for does not exist.
If I use jetty 9:
- if there is a single resource root (webapp directory) and no webjars - the path is returned
- if there is a multi resource setup (with webjars) - every webjar is scanned for sitemap.xmap resource. The resource is nowhere to be found - null is returned which by jetty/servlet spec api docs is a PROPER response.
if the path is null ContextSourceFactory falls back to:
u = this.servletContext.getResource(path);
... which is also null in this problematic case.
This response is also valid by ServletContext spec.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
-------------------------------------
Summary: Cocoon 2.2 in servlet 3.0 environment fails to initialize when webjars present on classpath.
Key: COCOON-2353
URL: https://issues.apache.org/jira/browse/COCOON-2353
Project: Cocoon
Issue Type: Bug
Components: * Cocoon Core
Affects Versions: 2.2
Reporter: Leszek Gawron
have found a problem that prevents deploying cocoon to 3.0 containers if the webapp contains webjars - by webjar I mean a jar containing META-INF/resources folder which is specially treated by sevlet container (the resources from that folder are served by container itself bypassing any webapp setup).
This happens on jetty 9.x. No matter if I set webapp to be 2.5 servlet compliant or 3.0.
Does not happen on jetty 8 which is ancient as of now.
I try running my app in embedded Jetty 9 - it works - as long as there is no actual .war - there is no scanning for META-INF resources.
As soon as I build a war this is how a configured context looks like:
startup of context ***@5bcab519{/,[
file:///C:/cygwin/tmp/jetty-0.0.0.0-8080-root.war-_-any-1513195852101013802.dir/webapp/,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/modernizr-2.8.3.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/openlayers-3.2.0.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/bootstrap-3.3.2.jar!/META-INF/resources,
jar:file:///C:/temp/jetty/mywebapp/smart-libs/jquery-1.11.1.jar!/META-INF/resources],UNAVAILABLE}
{C:\temp\jetty-gemini\gemini/root.war}
suddenly there is more than one root for static resources.
This yields following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cocoon.Processor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Unable to initialize Avalon component with role org.apache.cocoon.Processor; nested exception is org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:759)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:434)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:843)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:533)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:816)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1404)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1366)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:520)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561)
at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
at org.eclipse.jetty.server.Server.start(Server.java:411)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.Server.doStart(Server.java:378)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1516)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1441)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jetty.start.Main.invokeMain(Main.java:214)
at org.eclipse.jetty.start.Main.start(Main.java:457)
at org.eclipse.jetty.start.Main.main(Main.java:75)
Caused by: org.springframework.beans.factory.BeanCreationException: Unable to initialize Avalon component with role org.apache.cocoon.Processor; nested exception is org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.apache.cocoon.core.container.spring.avalon.AvalonBeanPostProcessor.postProcessBeforeInitialization(AvalonBeanPostProcessor.java:258)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
... 54 more
Caused by: org.apache.avalon.framework.configuration.ConfigurationException: Cannot resolve context://sitemap.xmap
at org.apache.cocoon.components.treeprocessor.TreeProcessor.configure(TreeProcessor.java:230)
at org.apache.avalon.framework.container.ContainerUtil.configure(ContainerUtil.java:202)
at org.apache.cocoon.core.container.spring.avalon.AvalonBeanPostProcessor.postProcessBeforeInitialization(AvalonBeanPostProcessor.java:246)
... 57 more
Caused by: java.net.MalformedURLException: context://sitemap.xmap could not be found. (possible context problem)
at org.apache.cocoon.components.source.impl.ContextSourceFactory.getSource(ContextSourceFactory.java:128)
at org.apache.cocoon.components.source.CocoonSourceResolver.resolveURI(CocoonSourceResolver.java:153)
at org.apache.cocoon.components.source.CocoonSourceResolver.resolveURI(CocoonSourceResolver.java:183)
at org.apache.cocoon.components.treeprocessor.TreeProcessor.configure(TreeProcessor.java:228)
... 59 more
This is the problematic ContextSourceFactory code:
public Source getSource(String location, Map parameters) throws IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Creating source object for " + location);
}
// Lookup resolver
SourceResolver resolver = null;
try {
resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
// Remove the protocol and the first '/'
final int pos = location.indexOf(":/");
final String scheme = location.substring(0, pos);
final String path = location.substring(pos + 2);
// fix for #24093, we don't give access to files outside the context:
if (path.indexOf("../") != -1) {
throw new MalformedURLException("Invalid path ('../' is not allowed) : " + path);
}
URL u;
// Try to get a file first and fall back to a resource URL
String actualPath = this.servletContext.getRealPath(path);
if (actualPath != null) {
u = new File(actualPath).toURL();
} else {
u = this.servletContext.getResource(path);
}
if (u != null) {
Source source = resolver.resolveURI(u.toExternalForm());
if ( parameters != null
&& BooleanUtils.toBoolean("force-traversable")
&& this.servletContext != null
&& !(source instanceof TraversableSource) ) {
final Set children = this.servletContext.getResourcePaths(path + '/');
if ( children != null ) {
source = new TraversableContextSource(source, children, this, path, scheme);
}
}
return source;
}
final String message = location + " could not be found. (possible context problem)";
getLogger().info(message);
throw new MalformedURLException(message);
} catch (ServiceException se) {
throw new SourceException("Unable to lookup source resolver.", se);
} finally {
this.manager.release(resolver);
}
}
If I use jetty 8
String actualPath = this.servletContext.getRealPath(path);
never returns null - even if the path we ask for does not exist.
If I use jetty 9:
- if there is a single resource root (webapp directory) and no webjars - the path is returned
- if there is a multi resource setup (with webjars) - every webjar is scanned for sitemap.xmap resource. The resource is nowhere to be found - null is returned which by jetty/servlet spec api docs is a PROPER response.
if the path is null ContextSourceFactory falls back to:
u = this.servletContext.getResource(path);
... which is also null in this problematic case.
This response is also valid by ServletContext spec.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)