diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index b4c32f7a315..42bd98c1f9a 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -34,6 +34,7 @@ import org.apache.catalina.core.StandardContext; import org.apache.catalina.core.StandardEngine; import org.apache.catalina.core.StandardHost; import org.apache.catalina.core.StandardService; +import org.apache.catalina.loader.WebappLoader; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat.FixContextListener; import org.apache.coyote.AbstractProtocol; @@ -139,9 +140,12 @@ public class TomcatEmbeddedServletContainerFactory extends context.setPath(getContextPath()); context.setDocBase(docBase.getAbsolutePath()); context.addLifecycleListener(new FixContextListener()); - if (this.resourceLoader != null) { - context.setParentClassLoader(this.resourceLoader.getClassLoader()); - } + context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader + .getClassLoader() : ClassUtils.getDefaultClassLoader()); + WebappLoader loader = new WebappLoader(context.getParentClassLoader()); + loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName()); + context.setLoader(loader); + if (isRegisterDefaultServlet()) { addDefaultServlet(context); } diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java new file mode 100644 index 00000000000..6b81c3fd13b --- /dev/null +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.bootstrap.context.embedded.tomcat; + +import java.net.URL; +import java.net.URLClassLoader; + +import org.apache.catalina.loader.WebappClassLoader; + +/** + * Extension of Tomcat's {@link WebappClassLoader} that does not consider the + * {@link ClassLoader#getSystemClassLoader() system classloader}. This is required to to + * ensure that any custom context classloader is always used (as is the case with some + * executable archives). + * + * @author Phillip Webb + */ +public class TomcatEmbeddedWebappClassLoader extends WebappClassLoader { + + public TomcatEmbeddedWebappClassLoader() { + super(); + this.system = new EmbeddedSystemClassLoader(); + } + + public TomcatEmbeddedWebappClassLoader(ClassLoader parent) { + super(parent); + this.system = new EmbeddedSystemClassLoader(); + } + + private static class EmbeddedSystemClassLoader extends URLClassLoader { + + public EmbeddedSystemClassLoader() { + super(new URL[] {}); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + throw new ClassNotFoundException( + "System ClassLoader disabled for embedded context, unable to load " + + name); + } + + } + +}