Community
Participate
Working Groups
org.springframework.web.SpringServletContainerInitializer (SSCI), described in the Spring docs ([1]), is automatically loaded and driven by any servlet 3.0 container which has Spring web on the servlet container's class path. Its purpose is to find and drive user-provided org.springframework.web.WebApplicationInitializer implementations. SSCI is loaded using the current thread context class loader ([2]). [1] http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/SpringServletContainerInitializer.html [2] http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html?is-external=true#load(java.lang.Class)
See https://bugs.eclipse.org/bugs/show_bug.cgi?id=357102#c2 for the diagnostics produced.
The stack trace: [2012-01-18 16:02:07.790] start-signalling-2 The ServletContentInitializer [org.springframework.web.SpringServletContainerInitializer] could not be created java.lang.ClassNotFoundException: org.springframework.web.SpringServletContainerInitializer at org.eclipse.gemini.web.tomcat.internal.loading.BundleWebappClassLoader.loadClass(BundleWebappClassLoader.java:306) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at org.apache.catalina.startup.ContextConfig.getServletContainerInitializer(ContextConfig.java:1543) at ... points to the following class loading logic in the ContextConfig.getServletContainerInitializer method (see [1]): Class<?> clazz = Class.forName(className,true, context.getLoader().getClassLoader()); where context is a field of type org.apache.catalina.Context declared as: /** * The Context we are associated with. */ protected Context context = null; So it seems that if this class load is to succeed, we need to be able to load org.springframework.web.SpringServletContainerInitializer from the class loader obtained from the Context via getLoader().getClassLoader(). [1] http://svn.apache.org/repos/asf/tomcat/tc7.0.x/trunk/java/org/apache/catalina/startup/ContextConfig.java
I suggest we start by debugging ContextConfig.webConfig to see how Tomcat ends up finding Spring web. One question is: if the WAR file has access to Spring web, why can't the class SSCI be loaded?
It turns out that Tomcat makes a hierarchical class loader assumption and ends up searching the parent class loader of the web application and finds Spring web because of the way integration tests are run under Ant. This would not be a problem using the normal launcher (i.e. outside an integration test environment) because Spring web would not be on the application class path. The fix is to specify a different parent class loader by setting the property osgi.parentClassloader to "ext". This makes all the OSGi bundles in the system have a parent class loader of the JRE extension class loader (which is the parent of the application class loader). However, Gemini Web uses the application class loader as the parent for WebBundleClassLoader and so it will be necessary to change Gemini Web to ensure WebBundleClassLoader's parent class loader is the same as that of the OSGi bundles.
This was cause by junk in the app class loader when running tests. Changing the parent class loader of all bundles in tests (including web app classloaders) fixes this.
See 2390176a622634228de0c732a0272a9113698dca
Previous SHA is for web. This is for Gemini Web 534397ad2a49d57d2de4f46fb507814d07034a38