From 1b17677e0b5bb326840c033825c236e3366562cb Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 31 Oct 2016 21:42:58 -0700 Subject: [PATCH] Polish TLD skip pattern support See gh-5010 --- .../autoconfigure/web/ServerProperties.java | 6 +- .../web/ServerPropertiesTests.java | 5 +- .../tomcat/SkipPatternJarScanner.java | 143 ++---------------- .../embedded/tomcat/TldSkipPatterns.java | 139 +++++++++++++++++ ...TomcatEmbeddedServletContainerFactory.java | 31 ++-- 5 files changed, 168 insertions(+), 156 deletions(-) create mode 100644 spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TldSkipPatterns.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index a1a854a0e9..1e75bf40c0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -675,9 +675,9 @@ public class ServerProperties private int acceptCount = 0; /** - * Comma-separated list of additional patterns that match jars to ignore for - * TLD scanning. The special '?' and '*' characters can be used in the pattern - * to match one and only one character and zero or more characters respectively. + * Comma-separated list of additional patterns that match jars to ignore for TLD + * scanning. The special '?' and '*' characters can be used in the pattern to + * match one and only one character and zero or more characters respectively. */ private List additionalTldSkipPatterns = new ArrayList(); diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java index e67990ab85..43a65bfa05 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java @@ -493,7 +493,6 @@ public class ServerPropertiesTests { Map map = new HashMap(); map.put("server.tomcat.additional-tld-skip-patterns", "foo.jar,bar.jar"); bindProperties(map); - testCustomTomcatTldSkip("foo.jar", "bar.jar"); } @@ -503,7 +502,6 @@ public class ServerPropertiesTests { map.put("server.tomcat.additional-tld-skip-patterns[0]", "biz.jar"); map.put("server.tomcat.additional-tld-skip-patterns[1]", "bah.jar"); bindProperties(map); - testCustomTomcatTldSkip("biz.jar", "bah.jar"); } @@ -511,7 +509,8 @@ public class ServerPropertiesTests { TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory(); this.properties.customize(container); assertThat(container.getTldSkipPatterns()).contains(expectedJars); - assertThat(container.getTldSkipPatterns()).contains("junit-*.jar", "spring-boot-*.jar"); + assertThat(container.getTldSkipPatterns()).contains("junit-*.jar", + "spring-boot-*.jar"); } @Test diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/SkipPatternJarScanner.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/SkipPatternJarScanner.java index 57d96402d3..f5665b4871 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/SkipPatternJarScanner.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/SkipPatternJarScanner.java @@ -17,9 +17,6 @@ package org.springframework.boot.context.embedded.tomcat; import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; import java.util.Set; import javax.servlet.ServletContext; @@ -49,18 +46,19 @@ class SkipPatternJarScanner extends StandardJarScanner { private final JarScanner jarScanner; - private final SkipPattern pattern; + private final Set patterns; SkipPatternJarScanner(JarScanner jarScanner, Set patterns) { Assert.notNull(jarScanner, "JarScanner must not be null"); + Assert.notNull(jarScanner, "Patterns must not be null"); this.jarScanner = jarScanner; - this.pattern = (patterns == null ? new SkipPattern(defaultPatterns()) : new SkipPattern(patterns)); - setPatternToTomcat8SkipFilter(this.pattern); + this.patterns = patterns; + setPatternToTomcat8SkipFilter(); } - private void setPatternToTomcat8SkipFilter(SkipPattern pattern) { + private void setPatternToTomcat8SkipFilter() { if (ClassUtils.isPresent(JAR_SCAN_FILTER_CLASS, null)) { - new Tomcat8TldSkipSetter(this).setSkipPattern(pattern); + new Tomcat8TldSkipSetter(this).setSkipPattern(this.patterns); } } @@ -73,105 +71,13 @@ class SkipPatternJarScanner extends StandardJarScanner { Assert.notNull(scanMethod, "Unable to find scan method"); try { scanMethod.invoke(this.jarScanner, context, classloader, callback, - (jarsToSkip == null ? this.pattern.asSet() : jarsToSkip)); + (jarsToSkip == null ? this.patterns : jarsToSkip)); } catch (Exception ex) { throw new IllegalStateException("Tomcat 7 reflection failed", ex); } } - /** - * Return the default skip patterns to use. - * @return the default skip patterns - */ - static Set defaultPatterns() { - return new LinkedHashSet(Arrays.asList( - // Same as Tomcat - "ant-*.jar", - "aspectj*.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", - "h2*.jar", - "hamcrest*.jar", - "hibernate*.jar", - "jmx*.jar", - "jmx-tools-*.jar", - "jta*.jar", - "junit-*.jar", - "httpclient*.jar", - "log4j-*.jar", - "mail*.jar", - "org.hamcrest*.jar", - "slf4j*.jar", - "tomcat-embed-core-*.jar", - "tomcat-embed-logging-*.jar", - "tomcat-jdbc-*.jar", - "tomcat-juli-*.jar", - "tools.jar", - "wsdl4j*.jar", - "xercesImpl-*.jar", - "xmlParserAPIs-*.jar", - "xml-apis-*.jar", - - // Additional - "antlr-*.jar", - "aopalliance-*.jar", - "aspectjrt-*.jar", - "aspectjweaver-*.jar", - "classmate-*.jar", - "dom4j-*.jar", - "ecj-*.jar", - "ehcache-core-*.jar", - "hibernate-core-*.jar", - "hibernate-commons-annotations-*.jar", - "hibernate-entitymanager-*.jar", - "hibernate-jpa-2.1-api-*.jar", - "hibernate-validator-*.jar", - "hsqldb-*.jar", - "jackson-annotations-*.jar", - "jackson-core-*.jar", - "jackson-databind-*.jar", - "jandex-*.jar", - "javassist-*.jar", - "jboss-logging-*.jar", - "jboss-transaction-api_*.jar", - "jcl-over-slf4j-*.jar", - "jdom-*.jar", - "jul-to-slf4j-*.jar", - "log4j-over-slf4j-*.jar", - "logback-classic-*.jar", - "logback-core-*.jar", - "rome-*.jar", - "slf4j-api-*.jar", - "spring-aop-*.jar", - "spring-aspects-*.jar", - "spring-beans-*.jar", - "spring-boot-*.jar", - "spring-core-*.jar", - "spring-context-*.jar", - "spring-data-*.jar", - "spring-expression-*.jar", - "spring-jdbc-*.jar,", - "spring-orm-*.jar", - "spring-oxm-*.jar", - "spring-tx-*.jar", - "snakeyaml-*.jar", - "tomcat-embed-el-*.jar", - "validation-api-*.jar", - "xml-apis-*.jar")); - } - /** * Apply this decorator the specified context. * @param context the context to apply to @@ -194,43 +100,12 @@ class SkipPatternJarScanner extends StandardJarScanner { this.jarScanner = jarScanner; } - public void setSkipPattern(SkipPattern pattern) { + public void setSkipPattern(Set patterns) { StandardJarScanFilter filter = new StandardJarScanFilter(); - filter.setTldSkip(pattern.asCommaDelimitedString()); + filter.setTldSkip(StringUtils.collectionToCommaDelimitedString(patterns)); this.jarScanner.setJarScanFilter(filter); } } - /** - * Skip patterns used by Spring Boot. - */ - private static class SkipPattern { - - private Set patterns = new LinkedHashSet(); - - SkipPattern(Set patterns) { - for (String pattern : patterns) { - add(pattern); - } - } - - 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 String asCommaDelimitedString() { - return StringUtils.collectionToCommaDelimitedString(this.patterns); - } - - public Set asSet() { - return Collections.unmodifiableSet(this.patterns); - } - - } - } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TldSkipPatterns.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TldSkipPatterns.java new file mode 100644 index 0000000000..35c0f2c74d --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TldSkipPatterns.java @@ -0,0 +1,139 @@ +/* + * Copyright 2012-2016 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; + +/** + * TLD Skip Patterns used by Spring Boot. + * + * @author Phillip Webb + */ +final class TldSkipPatterns { + + private static final Set TOMCAT; + + static { + // Same as Tomcat + Set patterns = new LinkedHashSet(); + patterns.add("ant-*.jar"); + patterns.add("aspectj*.jar"); + patterns.add("commons-beanutils*.jar"); + patterns.add("commons-codec*.jar"); + patterns.add("commons-collections*.jar"); + patterns.add("commons-dbcp*.jar"); + patterns.add("commons-digester*.jar"); + patterns.add("commons-fileupload*.jar"); + patterns.add("commons-httpclient*.jar"); + patterns.add("commons-io*.jar"); + patterns.add("commons-lang*.jar"); + patterns.add("commons-logging*.jar"); + patterns.add("commons-math*.jar"); + patterns.add("commons-pool*.jar"); + patterns.add("geronimo-spec-jaxrpc*.jar"); + patterns.add("h2*.jar"); + patterns.add("hamcrest*.jar"); + patterns.add("hibernate*.jar"); + patterns.add("jmx*.jar"); + patterns.add("jmx-tools-*.jar"); + patterns.add("jta*.jar"); + patterns.add("junit-*.jar"); + patterns.add("httpclient*.jar"); + patterns.add("log4j-*.jar"); + patterns.add("mail*.jar"); + patterns.add("org.hamcrest*.jar"); + patterns.add("slf4j*.jar"); + patterns.add("tomcat-embed-core-*.jar"); + patterns.add("tomcat-embed-logging-*.jar"); + patterns.add("tomcat-jdbc-*.jar"); + patterns.add("tomcat-juli-*.jar"); + patterns.add("tools.jar"); + patterns.add("wsdl4j*.jar"); + patterns.add("xercesImpl-*.jar"); + patterns.add("xmlParserAPIs-*.jar"); + patterns.add("xml-apis-*.jar"); + TOMCAT = Collections.unmodifiableSet(patterns); + } + + private static final Set ADDITIONAL; + + static { + // Additional typical for Spring Boot applications + Set patterns = new LinkedHashSet(); + patterns.add("antlr-*.jar"); + patterns.add("aopalliance-*.jar"); + patterns.add("aspectjrt-*.jar"); + patterns.add("aspectjweaver-*.jar"); + patterns.add("classmate-*.jar"); + patterns.add("dom4j-*.jar"); + patterns.add("ecj-*.jar"); + patterns.add("ehcache-core-*.jar"); + patterns.add("hibernate-core-*.jar"); + patterns.add("hibernate-commons-annotations-*.jar"); + patterns.add("hibernate-entitymanager-*.jar"); + patterns.add("hibernate-jpa-2.1-api-*.jar"); + patterns.add("hibernate-validator-*.jar"); + patterns.add("hsqldb-*.jar"); + patterns.add("jackson-annotations-*.jar"); + patterns.add("jackson-core-*.jar"); + patterns.add("jackson-databind-*.jar"); + patterns.add("jandex-*.jar"); + patterns.add("javassist-*.jar"); + patterns.add("jboss-logging-*.jar"); + patterns.add("jboss-transaction-api_*.jar"); + patterns.add("jcl-over-slf4j-*.jar"); + patterns.add("jdom-*.jar"); + patterns.add("jul-to-slf4j-*.jar"); + patterns.add("log4j-over-slf4j-*.jar"); + patterns.add("logback-classic-*.jar"); + patterns.add("logback-core-*.jar"); + patterns.add("rome-*.jar"); + patterns.add("slf4j-api-*.jar"); + patterns.add("spring-aop-*.jar"); + patterns.add("spring-aspects-*.jar"); + patterns.add("spring-beans-*.jar"); + patterns.add("spring-boot-*.jar"); + patterns.add("spring-core-*.jar"); + patterns.add("spring-context-*.jar"); + patterns.add("spring-data-*.jar"); + patterns.add("spring-expression-*.jar"); + patterns.add("spring-jdbc-*.jar,"); + patterns.add("spring-orm-*.jar"); + patterns.add("spring-oxm-*.jar"); + patterns.add("spring-tx-*.jar"); + patterns.add("snakeyaml-*.jar"); + patterns.add("tomcat-embed-el-*.jar"); + patterns.add("validation-api-*.jar"); + patterns.add("xml-apis-*.jar"); + ADDITIONAL = Collections.unmodifiableSet(patterns); + } + + static final Set DEFAULT; + + static { + Set patterns = new LinkedHashSet(); + patterns.addAll(TOMCAT); + patterns.addAll(ADDITIONAL); + DEFAULT = Collections.unmodifiableSet(patterns); + } + + private TldSkipPatterns() { + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index 103acdbf8a..c0cddd65f1 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -127,7 +127,7 @@ public class TomcatEmbeddedServletContainerFactory private String protocol = DEFAULT_PROTOCOL; private Set tldSkipPatterns = new LinkedHashSet( - SkipPatternJarScanner.defaultPatterns()); + TldSkipPatterns.DEFAULT); private Charset uriEncoding = DEFAULT_CHARSET; @@ -554,23 +554,12 @@ public class TomcatEmbeddedServletContainerFactory * 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 tldSkip the jars to skip when scanning for TLDs etc - * @deprecated since 1.5.0 in favor of {@link #setTldSkipPatterns(List)} + * @deprecated since 1.5.0 in favor of {@link #setTldSkipPatterns(Collection)} */ @Deprecated public void setTldSkip(String tldSkip) { Assert.notNull(tldSkip, "TldSkip must not be null"); - setTldSkipPatterns(Arrays.asList( - StringUtils.commaDelimitedListToStringArray(tldSkip))); - } - - /** - * Set the patterns that match jars to ignore for TLD scanning. See Tomcat's - * catalina.properties for typical values. Defaults to a list drawn from that source. - * @param patterns the jar patterns to skip when scanning for TLDs etc - */ - public void setTldSkipPatterns(List patterns) { - Assert.notNull(patterns, "patterns must not be null"); - this.tldSkipPatterns = new LinkedHashSet(patterns); + setTldSkipPatterns(StringUtils.commaDelimitedListToSet(tldSkip)); } /** @@ -581,13 +570,23 @@ public class TomcatEmbeddedServletContainerFactory return this.tldSkipPatterns; } + /** + * Set the patterns that match jars to ignore for TLD scanning. See Tomcat's + * catalina.properties for typical values. Defaults to a list drawn from that source. + * @param patterns the jar patterns to skip when scanning for TLDs etc + */ + public void setTldSkipPatterns(Collection patterns) { + Assert.notNull(patterns, "Patterns must not be null"); + this.tldSkipPatterns = new LinkedHashSet(patterns); + } + /** * Add patterns that match jars to ignore for TLD scanning. See Tomcat's * catalina.properties for typical values. * @param patterns the additional jar patterns to skip when scanning for TLDs etc */ - public void addAdditionalTldSkipPatterns(String... patterns) { - Assert.notNull(patterns, "patterns must not be null"); + public void addTldSkipPatterns(String... patterns) { + Assert.notNull(patterns, "Patterns must not be null"); this.tldSkipPatterns.addAll(Arrays.asList(patterns)); }