Spring Boot 与 Jetty:禁用 o.a.tomcat.util.scan.StandardJarScanner

问题描述

我将 Spring Boot 与 Jetty 和 JSP/JSTL 结合使用:

        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                        <exclusion>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-starter-tomcat</artifactId>
                        </exclusion>
                </exclusions>
        </dependency>
        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jetty</artifactId>
                <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>apache-jsp</artifactId>
        </dependency>
        <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>apache-jstl</artifactId>
        </dependency>

在启动过程中,我收到许多警告,例如:

WARN 18439 --- [           main] o.a.tomcat.util.scan.StandardJarScanner  : Failed to scan [file:/home/user/.m2/repository/.../guava.jar] from classloader hierarchy

这些警告中有虚假的罐子。如果配置文件中没有配置文件并且运行的是 Jetty,为什么 tomcat 会扫描任何内容?是否需要扫描,例如JSP/JSTL?可以禁用吗?我无法使用 this,因为应用程序中没有可用的 Tomcat 库。

编辑:Tomcat (?) 源显然是由 Jasper 调用的,由 Jetty 依次使用。因此,我将其放入 pom.xml 以禁用 Jetty 的 Jar 扫描:

    <plugin>  
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <configuration>
            <webApp>

                <!-- no need to scan anything as we're using servlet 2.5 and moreover,we're not using Servl
                <!-- for more relevant information regarding scanning of classes refer to https://java.net/j
                <webInfIncludeJarPattern>^$</webInfIncludeJarPattern>
                <containerIncludeJarPattern>^$</containerIncludeJarPattern>
                <!--<webInfIncludeJarPattern>.*/spring-[^/]*\.jar$|.*/.*jsp-api-[^/]\.jar$|./.*jsp-[^/]\.jar
            </webApp>
        </configuration>
    </plugin>

但是没有任何效果

解决方法

您的 org.apache.tomcat.util.scan.StandardJarScanner 来自类路径上的 apache-jsp-<ver>.jar

Apache Jasper JSP 在执行 JSPC 步骤时需要扫描您的类路径以查找 TLD。

由于您使用的是 spring-boot,WebAppClassLoader 和 SystemClassLoader 并没有真正的分离,因此它被迫扫描整个类加载器层次结构以找到这些 TLD。

此扫描独立于 Jetty,因此这意味着 webInfIncludeJarPatterncontainerIncludeJarPattern 配置将没有影响。

这里最好的建议是在构建时使用 jspc 预编译您的 JSP,并且让运行时 Jasper JSP 永远不需要启动 JSPC 及其关联的 TLD 扫描。

如果您仍然需要运行时 JSPC,请考虑在服务器启动时设置以下属性,在您的上下文开始初始化之前。

System.setProperty(
  org.apache.tomcat.util.scan.Constants.SKIP_JARS_PROPERTY,"*.jar");

这会告诉 StandardJarScanFilter 跳过所有以 .jar 结尾的文件。

请注意,还有一个 Constants.SCAN_JARS_PROPERTY 可以指定要扫描的特定 jar。 (不知道这个属性是否支持globs,或者相对引用)