Allow per context TLD skip patterns

Change TomcatEmbeddedServletContainerFactory to allow per context
skip patterns to be defined, rather than using a global system property.

This commit also renames `skipPatterns` to `tldSkip` to align it with
Tomcat context.xml configuration.

Updates gh-256
pull/276/head
Phillip Webb 11 years ago
parent b34102c30c
commit b3f5d556bc

@ -0,0 +1,128 @@
/*
* Copyright 2012-2014 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.boot.context.embedded.tomcat;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.servlet.ServletContext;
import org.apache.tomcat.JarScanner;
import org.apache.tomcat.JarScannerCallback;
import org.springframework.util.Assert;
/**
* {@link JarScanner} decorator allowing alternative default jar pattern matching.
*
* @author Phillip Webb
* @see #apply(TomcatEmbeddedContext, String)
*/
class SkipPatternJarScanner implements JarScanner {
private final JarScanner jarScanner;
private final SkipPattern pattern;
SkipPatternJarScanner(JarScanner jarScanner, String pattern) {
Assert.notNull(jarScanner, "JarScanner must not be null");
this.jarScanner = jarScanner;
this.pattern = (pattern == null ? new SkipPattern() : new SkipPattern(pattern));
}
@Override
public void scan(ServletContext context, ClassLoader classloader,
JarScannerCallback callback, Set<String> jarsToSkip) {
this.jarScanner.scan(context, classloader, callback,
(jarsToSkip == null ? this.pattern.asSet() : jarsToSkip));
}
/**
* Apply this decorator the specified context.
* @param context the context to apply to
* @param pattern the jar skip pattern or {@code null} for defaults
*/
public static void apply(TomcatEmbeddedContext context, String pattern) {
context.setJarScanner(new SkipPatternJarScanner(context.getJarScanner(), pattern));
}
private static class SkipPattern {
private Set<String> patterns = new LinkedHashSet<String>();
protected SkipPattern() {
add("ant-*.jar");
add("aspectj*.jar");
add("commons-beanutils*.jar");
add("commons-codec*.jar");
add("commons-collections*.jar");
add("commons-dbcp*.jar");
add("commons-digester*.jar");
add("commons-fileupload*.jar");
add("commons-httpclient*.jar");
add("commons-io*.jar");
add("commons-lang*.jar");
add("commons-logging*.jar");
add("commons-math*.jar");
add("commons-pool*.jar");
add("geronimo-spec-jaxrpc*.jar");
add("h2*.jar");
add("hamcrest*.jar");
add("hibernate*.jar");
add("jmx*.jar");
add("jmx-tools-*.jar");
add("jta*.jar");
add("junit-*.jar");
add("httpclient*.jar");
add("log4j-*.jar");
add("mail*.jar");
add("org.hamcrest*.jar");
add("slf4j*.jar");
add("tomcat-embed-core-*.jar");
add("tomcat-embed-logging-*.jar");
add("tomcat-jdbc-*.jar");
add("tomcat-juli-*.jar");
add("tools.jar");
add("wsdl4j*.jar");
add("xercesImpl-*.jar");
add("xmlParserAPIs-*.jar");
add("xml-apis-*.jar");
}
public SkipPattern(String patterns) {
StringTokenizer tokenizer = new StringTokenizer(patterns, ",");
while (tokenizer.hasMoreElements()) {
add(tokenizer.nextToken());
}
}
protected void add(String patterns) {
Assert.notNull(patterns, "Patterns must not be null");
if (patterns.length() > 0 && !patterns.trim().startsWith(",")) {
this.patterns.add(",");
}
this.patterns.add(patterns);
}
public Set<String> asSet() {
return Collections.unmodifiableSet(this.patterns);
}
}
}

@ -89,14 +89,7 @@ public class TomcatEmbeddedServletContainerFactory extends
private String protocol = DEFAULT_PROTOCOL;
private static String DEFAULT_SKIP_JARS = "tomcat-embed-core-*.jar,tomcat-embed-logging-*.jar,tomcat-juli-*.jar,tomcat-jdbc-*.jar,"
+ "tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,"
+ "commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,"
+ "commons-logging*.jar,commons-math*.jar,commons-pool*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant-*.jar,"
+ "aspectj*.jar,jmx*.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools-*.jar,jta*.jar,log4j-*.jar,mail*.jar,slf4j*.jar,"
+ "xercesImpl-*.jar,xmlParserAPIs-*.jar,xml-apis-*.jar,junit-*.jar,hamcrest*.jar,org.hamcrest*.jar";
private String skipJars = DEFAULT_SKIP_JARS;
private String tldSkip;
/**
* Create a new {@link TomcatEmbeddedServletContainerFactory} instance.
@ -146,7 +139,6 @@ public class TomcatEmbeddedServletContainerFactory extends
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
File docBase = getValidDocumentRoot();
docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
applySkipJars();
TomcatEmbeddedContext context = new TomcatEmbeddedContext();
context.setName(getContextPath());
context.setPath(getContextPath());
@ -154,6 +146,7 @@ public class TomcatEmbeddedServletContainerFactory extends
context.addLifecycleListener(new FixContextListener());
context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader
.getClassLoader() : ClassUtils.getDefaultClassLoader());
SkipPatternJarScanner.apply(context, this.tldSkip);
WebappLoader loader = new WebappLoader(context.getParentClassLoader());
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
loader.setDelegate(true);
@ -173,14 +166,6 @@ public class TomcatEmbeddedServletContainerFactory extends
postProcessContext(context);
}
private void applySkipJars() {
// Tomcat 8.0
System.setProperty("tomcat.util.scan.StandardJarScanFilter.jarsToSkip",
this.skipJars);
// Tomcat 7.0
System.setProperty("tomcat.util.scan.DefaultJarScanner.jarsToSkip", this.skipJars);
}
private void addDefaultServlet(Context context) {
Wrapper defaultServlet = context.createWrapper();
defaultServlet.setName("default");
@ -302,11 +287,11 @@ public class TomcatEmbeddedServletContainerFactory extends
/**
* A comma-separated list of jars to ignore for TLD scanning. See Tomcat's
* catalina.properties for typical values. Defaults to a list drawn from that source.
*
* @param skipJars the jars to skip when scanning for tlds etc
* @param tldSkip the jars to skip when scanning for TLDs etc
*/
public void setSkipJars(String skipJars) {
this.skipJars = skipJars;
public void setTldSkip(String tldSkip) {
Assert.notNull(tldSkip, "TldSkip must not be null");
this.tldSkip = tldSkip;
}
/**

Loading…
Cancel
Save