Skip to content

Commit c4d3ac0

Browse files
author
Phillip Webb
committed
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 spring-projectsgh-256
1 parent 6cbb80f commit c4d3ac0

File tree

2 files changed

+134
-21
lines changed

2 files changed

+134
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.context.embedded.tomcat;
18+
19+
import java.util.Collections;
20+
import java.util.LinkedHashSet;
21+
import java.util.Set;
22+
import java.util.StringTokenizer;
23+
24+
import javax.servlet.ServletContext;
25+
26+
import org.apache.tomcat.JarScanner;
27+
import org.apache.tomcat.JarScannerCallback;
28+
import org.springframework.util.Assert;
29+
30+
/**
31+
* {@link JarScanner} decorator allowing alternative default jar pattern matching.
32+
*
33+
* @author Phillip Webb
34+
* @see #apply(TomcatEmbeddedContext, String)
35+
*/
36+
class SkipPatternJarScanner implements JarScanner {
37+
38+
private final JarScanner jarScanner;
39+
40+
private final SkipPattern pattern;
41+
42+
SkipPatternJarScanner(JarScanner jarScanner, String pattern) {
43+
Assert.notNull(jarScanner, "JarScanner must not be null");
44+
this.jarScanner = jarScanner;
45+
this.pattern = (pattern == null ? new SkipPattern() : new SkipPattern(pattern));
46+
}
47+
48+
@Override
49+
public void scan(ServletContext context, ClassLoader classloader,
50+
JarScannerCallback callback, Set<String> jarsToSkip) {
51+
this.jarScanner.scan(context, classloader, callback,
52+
(jarsToSkip == null ? this.pattern.asSet() : jarsToSkip));
53+
}
54+
55+
/**
56+
* Apply this decorator the specified context.
57+
* @param context the context to apply to
58+
* @param pattern the jar skip pattern or {@code null} for defaults
59+
*/
60+
public static void apply(TomcatEmbeddedContext context, String pattern) {
61+
context.setJarScanner(new SkipPatternJarScanner(context.getJarScanner(), pattern));
62+
}
63+
64+
private static class SkipPattern {
65+
66+
private Set<String> patterns = new LinkedHashSet<String>();
67+
68+
protected SkipPattern() {
69+
add("ant-*.jar");
70+
add("aspectj*.jar");
71+
add("commons-beanutils*.jar");
72+
add("commons-codec*.jar");
73+
add("commons-collections*.jar");
74+
add("commons-dbcp*.jar");
75+
add("commons-digester*.jar");
76+
add("commons-fileupload*.jar");
77+
add("commons-httpclient*.jar");
78+
add("commons-io*.jar");
79+
add("commons-lang*.jar");
80+
add("commons-logging*.jar");
81+
add("commons-math*.jar");
82+
add("commons-pool*.jar");
83+
add("geronimo-spec-jaxrpc*.jar");
84+
add("h2*.jar");
85+
add("hamcrest*.jar");
86+
add("hibernate*.jar");
87+
add("jmx*.jar");
88+
add("jmx-tools-*.jar");
89+
add("jta*.jar");
90+
add("junit-*.jar");
91+
add("httpclient*.jar");
92+
add("log4j-*.jar");
93+
add("mail*.jar");
94+
add("org.hamcrest*.jar");
95+
add("slf4j*.jar");
96+
add("tomcat-embed-core-*.jar");
97+
add("tomcat-embed-logging-*.jar");
98+
add("tomcat-jdbc-*.jar");
99+
add("tomcat-juli-*.jar");
100+
add("tools.jar");
101+
add("wsdl4j*.jar");
102+
add("xercesImpl-*.jar");
103+
add("xmlParserAPIs-*.jar");
104+
add("xml-apis-*.jar");
105+
}
106+
107+
public SkipPattern(String patterns) {
108+
StringTokenizer tokenizer = new StringTokenizer(patterns, ",");
109+
while (tokenizer.hasMoreElements()) {
110+
add(tokenizer.nextToken());
111+
}
112+
}
113+
114+
protected void add(String patterns) {
115+
Assert.notNull(patterns, "Patterns must not be null");
116+
if (patterns.length() > 0 && !patterns.trim().startsWith(",")) {
117+
this.patterns.add(",");
118+
}
119+
this.patterns.add(patterns);
120+
}
121+
122+
public Set<String> asSet() {
123+
return Collections.unmodifiableSet(this.patterns);
124+
}
125+
126+
}
127+
128+
}

spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,7 @@ public class TomcatEmbeddedServletContainerFactory extends
8989

9090
private String protocol = DEFAULT_PROTOCOL;
9191

92-
private static String DEFAULT_SKIP_JARS = "tomcat-embed-core-*.jar,tomcat-embed-logging-*.jar,tomcat-juli-*.jar,tomcat-jdbc-*.jar,"
93-
+ "tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,"
94-
+ "commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,"
95-
+ "commons-logging*.jar,commons-math*.jar,commons-pool*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant-*.jar,"
96-
+ "aspectj*.jar,jmx*.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools-*.jar,jta*.jar,log4j-*.jar,mail*.jar,slf4j*.jar,"
97-
+ "xercesImpl-*.jar,xmlParserAPIs-*.jar,xml-apis-*.jar,junit-*.jar,hamcrest*.jar,org.hamcrest*.jar";
98-
99-
private String skipJars = DEFAULT_SKIP_JARS;
92+
private String tldSkip;
10093

10194
/**
10295
* Create a new {@link TomcatEmbeddedServletContainerFactory} instance.
@@ -146,14 +139,14 @@ public EmbeddedServletContainer getEmbeddedServletContainer(
146139
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
147140
File docBase = getValidDocumentRoot();
148141
docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
149-
applySkipJars();
150142
TomcatEmbeddedContext context = new TomcatEmbeddedContext();
151143
context.setName(getContextPath());
152144
context.setPath(getContextPath());
153145
context.setDocBase(docBase.getAbsolutePath());
154146
context.addLifecycleListener(new FixContextListener());
155147
context.setParentClassLoader(this.resourceLoader != null ? this.resourceLoader
156148
.getClassLoader() : ClassUtils.getDefaultClassLoader());
149+
SkipPatternJarScanner.apply(context, this.tldSkip);
157150
WebappLoader loader = new WebappLoader(context.getParentClassLoader());
158151
loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
159152
loader.setDelegate(true);
@@ -173,14 +166,6 @@ protected void prepareContext(Host host, ServletContextInitializer[] initializer
173166
postProcessContext(context);
174167
}
175168

176-
private void applySkipJars() {
177-
// Tomcat 8.0
178-
System.setProperty("tomcat.util.scan.StandardJarScanFilter.jarsToSkip",
179-
this.skipJars);
180-
// Tomcat 7.0
181-
System.setProperty("tomcat.util.scan.DefaultJarScanner.jarsToSkip", this.skipJars);
182-
}
183-
184169
private void addDefaultServlet(Context context) {
185170
Wrapper defaultServlet = context.createWrapper();
186171
defaultServlet.setName("default");
@@ -302,11 +287,11 @@ public void setBaseDirectory(File baseDirectory) {
302287
/**
303288
* A comma-separated list of jars to ignore for TLD scanning. See Tomcat's
304289
* catalina.properties for typical values. Defaults to a list drawn from that source.
305-
*
306-
* @param skipJars the jars to skip when scanning for tlds etc
290+
* @param tldSkip the jars to skip when scanning for TLDs etc
307291
*/
308-
public void setSkipJars(String skipJars) {
309-
this.skipJars = skipJars;
292+
public void setTldSkip(String tldSkip) {
293+
Assert.notNull(tldSkip, "TldSkip must not be null");
294+
this.tldSkip = tldSkip;
310295
}
311296

312297
/**

0 commit comments

Comments
 (0)