How to fix "JARs that were scanned but no TLDs were found in them " in Tomcat 9.0.0M10

110,157

Solution 1

This is not a bug or any kind of problem in tomcat. Tomcat is just informing you that there are jars that do not contain TLDs and you can add them to the scanner's skip list to improve startup performance. So you have two options:

  1. You can safely ignore that hint. Yet if it annoy you, you can set that specific logger to a higher logging level, and thus prevent tomcat from logging it. Just add org.apache.jasper.servlet.TldScanner.level = SEVERE to the end of logging.properties.

  2. Enable the debug logging to make tomcat list those jars and add them to the skip list. Set:

    org.apache.jasper.compiler.TldLocationsCache.level = FINE
    org.apache.jasper.servlet.TldScanner.level = FINE
    

And add the printed jars names (without the path) to tomcat.util.scan.StandardJarScanFilter.jarsToSkip=... in tomcat_dir/conf/catalina.properties

Solution 2

Setting the logging to FINE, FINEST or ALL to find all jars to exclude is not neccessary.

Here is a script that finds all jars not containing TLDs (change the TOMCAT_HOME variable to match your installation) and outputs a list on the form

jar1.jar,\
jar2.jar,\
...

that can be pasted into catalina.properties (omit the last ',\'):

#!/bin/sh
TOMCAT_HOME=/opt/tomcat
for i in `find $TOMCAT_HOME -follow -name "*jar"`
do
    jar tvf $i | grep -i tld > /dev/null
    if [ $? -ne 0 ]; then
        echo "$(basename $i),\\"
    fi
done

However, if I am correctly informed, there is a possibility in tomcat 9 to exclude all jars by changing (in catalina.properties):

tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\

to

tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar

(comment away the list on the lines below) and then override that decision for jars containg TLDs by changing:

tomcat.util.scan.StandardJarScanFilter.jarsToScan=\
log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar

and add the list obtained by modifying the script above to list the jars that do contain TLDs:

#!/bin/sh
TOMCAT_HOME=/opt/tomcat
for i in `find $TOMCAT_HOME -follow -name "*jar"`
do
    jar tvf $i | grep -i tld > /dev/null
    if [ $? -eq 0 ]; then
        echo "$(basename $i),\\"
    fi
done

Solution 3

change conf\context.xml file

<Context>
    <!-- only if you do not use jsp tag -->
    <JarScanner>
        <JarScanFilter defaultPluggabilityScan="false" defaultTldScan="false"/>
    </JarScanner>
</Context>

see: https://tomcat.apache.org/tomcat-9.0-doc/config/jar-scan-filter.html

Share:
110,157
Coder ACJHP
Author by

Coder ACJHP

Just trying to be Coder 🌟

Updated on September 03, 2020

Comments

  • Coder ACJHP
    Coder ACJHP over 3 years

    I'm new to Java EE and trying to work on ServletContextListener and listener job is connection to database bla bla .When I am trying to start the server (Tomcat 9) it is stuck on :

    "INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time."

    So I changed some properties in "Logging properties file" like this :

        # Licensed to the Apache Software Foundation (ASF) under one or more
    # contributor license agreements.  See the NOTICE file distributed with
    # this work for additional information regarding copyright ownership.
    # The ASF licenses this file to You 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.
    
    handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
    
    .handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
    
    ############################################################
    # Handler specific properties.
    # Describes specific configuration info for Handlers.
    ############################################################
    
    1catalina.org.apache.juli.AsyncFileHandler.level = FINE
    1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
    1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
    
    2localhost.org.apache.juli.AsyncFileHandler.level = FINE
    2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
    2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
    
    3manager.org.apache.juli.AsyncFileHandler.level = FINE
    3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
    3manager.org.apache.juli.AsyncFileHandler.prefix = manager.
    
    4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
    4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
    4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.
    
    java.util.logging.ConsoleHandler.level = FINE
    java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
    
    
    ############################################################
    # Facility specific properties.
    # Provides extra control for each logger.
    ############################################################
    
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = FINE
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler
    
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = FINE
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler
    
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = FINE
    org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler
    
    # For example, set the org.apache.catalina.util.LifecycleBase logger to log
    # each component that extends LifecycleBase changing state:
    #org.apache.catalina.util.LifecycleBase.level = FINE
    
    # To see debug messages in TldLocationsCache, uncomment the following line:
    org.apache.jasper.compiler.TldLocationsCache.level = FINE
    org.apache.jasper.servlet.TldScanner.level = FINE
    
    # To see debug messages for HTTP/2 handling, uncomment the following line:
    #org.apache.coyote.http2.level = FINE
    
    # To see debug messages for WebSocket handling, uncomment the following line:
    #org.apache.tomcat.websocket.level = FINE
    

    All answers acceptable. Thanks for all.