1

I use Spring Boot with Jetty and 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>

During startup, I get a number of warnings like:

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

There are spurious jars in these warnings. Why tomcat scans anything if it is absent from the configuration files and it is Jetty which runs? Is the scan needed for e.g. JSP/JSTL? Can it be disabled? I can't use this because no Tomcat libraries are available in the application.

EDIT: Tomcat (?) sources are apparently called by Jasper, used in turn by Jetty. Thus, I put this into pom.xml in order to disable Jar scanning by Jetty:

    <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>

but it did not have any effect.

scriptfoo
  • 476
  • 5
  • 17
  • 1
    Apparently there are tomcat libraries available. Something must be pulling them in. Run `mvn dependency:tree` and figure out which dependencies are there. – M. Deinum Mar 18 '21 at 11:16
  • `mvn dependency:tree | grep tomcat` shows nothing. Can Tomcat hide somehow in another Jar? – scriptfoo Mar 18 '21 at 11:21
  • I nowhere mentioned the grepping... Could be part of a different jar. Although spring would need to start it, so could be old dependencies? Have you tried cleaning everything and rebuilding it? – M. Deinum Mar 18 '21 at 13:19
  • The stack trace shows a call sequence Jetty -> Jasper -> Tomcat (or at least, package names suggest that). Possibly Jetty should be reconfigured. I updated the question accordingly. – scriptfoo Mar 18 '21 at 13:25

1 Answers1

3

Your org.apache.tomcat.util.scan.StandardJarScanner is coming from the apache-jsp-<ver>.jar on the classpath.

Apache Jasper JSP needs to scan your classpath for TLDs when it does the JSPC steps.

Since you are using spring-boot, there's no real separation of WebAppClassLoader and SystemClassLoader, so it's forced to scan the entire classloader hierarchy to find those TLDs.

This scan is independent of Jetty, so that means the webInfIncludeJarPattern and containerIncludeJarPattern configurations will have no impact.

The best advice here is to precompile your JSP's with jspc during build-time and just have the runtime Jasper JSP never have the need to kick off JSPC and it's associated TLD scan.

If you still want runtime JSPC, consider setting the following property at Server startup, before your Context has started to initialize.

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

That will tell the StandardJarScanFilter to skip all files ending in .jar.

Note that there is also a Constants.SCAN_JARS_PROPERTY which you get to specify specific jars to scan. (I don't know if this property supports globs, or relative references)

Joakim Erdfelt
  • 46,896
  • 7
  • 86
  • 136