如何修复Tomcat 9.0.0M10中出现的“已扫描但未在其中找到TLD”的JAR文件问题

38

我是Java EE的新手,并尝试使用ServletContextListener来连接数据库。但是当我尝试启动服务器(Tomcat 9)时,它卡在以下信息处:

"INFO: 至少已扫描一个JAR以查找TLDs,但未包含任何TLDs。启用此记录器的调试日志记录可获取扫描了哪些JARs但其中未找到TLDs的完整列表。在扫描期间跳过不需要的JAR可以提高启动时间和JSP编译时间。"

因此,我像这样更改了“Logging properties file”中的一些属性:

    # 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

所有答案都可以接受。谢谢大家。


相关问题:https://dev59.com/J2Yq5IYBdhLWcg3wkRco,https://dev59.com/DWcs5IYBdhLWcg3wXi5E - Stephen C
@StephenC Tomcat 9和8之间没有区别吗? - Coder ACJHP
@StephenC 因为我尝试了所有的方法,但仍然得到相同的结果,谢谢。 - Coder ACJHP
4个回答

40

这不是Tomcat中的bug或任何问题,Tomcat只是在通知您有一些JAR文件没有包含TLDs,并且您可以将它们添加到扫描器的跳过列表中以提高启动性能。因此,您有两个选项:

  1. 您可以安全地忽略该提示。但如果它让您感到烦恼,您可以将特定的记录器设置为更高的日志级别,从而防止Tomcat记录它。只需在logging.properties末尾添加org.apache.jasper.servlet.TldScanner.level = SEVERE即可。

  2. 启用调试日志记录以使Tomcat列出这些JAR文件并将它们添加到跳过列表中。设置:

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

将打印的 jar 包名称(不包括路径)添加到 tomcat_dir/conf/catalina.properties 中的 tomcat.util.scan.StandardJarScanFilter.jarsToSkip=... 配置项中。


谢谢您的解释,我会尝试并告知您。 - Coder ACJHP
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=1org.apache.jasper.servlet.TldScanner,2org.apache.jasper.compiler.TldLocationsCache - Coder ACJHP
抱歉,像这样的:"org.apache.jasper.compiler.TldLocationsCache.jar,org.apache.jasper.servlet.TldScanner.jar" - Coder ACJHP
2
不,你必须列出“要跳过的JAR文件”,而不是Tomcat类。首先,您需要启用调试日志记录以查找JAR文件的名称,然后将它们作为逗号分隔的列表添加到tomcat.util.scan.StandardJarScanFilter.jarsToSkip=属性中。 - Svetlin Zarev
现在我更好地理解了。非常感谢你。 - Coder ACJHP

15

将日志级别设置为FINE、FINEST或ALL以查找所有需要排除的jar包是不必要的。

这里是一个脚本,可以找到所有不包含TLDs的jar包(请将TOMCAT_HOME变量更改为匹配您的安装),并以列表形式输出。

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

可以复制到catalina.properties中(省略最后一个',\'):

#!/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

然而,如果我被正确告知的话,在Tomcat 9中有一种可能性可以通过更改catalina.properties文件来排除所有的JAR包:

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

(在下面的行中注释掉列表),然后通过更改以下内容,覆盖包含 TLDs 的 jars 的决策:


注:TLD指顶级域名(Top Level Domain)
tomcat.util.scan.StandardJarScanFilter.jarsToScan=\
log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar

并且将通过修改上面的脚本获得的列表添加到包含TLD的jar列表中:

#!/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

1
请注意,如果任何JAR文件包含一个包含字母“tld”的文件,而实际上并不是.tld文件,则这些JAR文件也被认为包含一个.tld文件。 - Nzall

5

1
只是想补充一点:如果您想在应用程序中使用web.xml片段(例如在Tomcat中部署为War的Spring Boot应用程序),则需要添加以下内容:<JarScanFilter defaultPluggabilityScan="true" defaultTldScan="false"/> - Sorin Postelnicu

-4

我解决了同样的问题。 我认为这是权限问题,所以需要给予webapps/project文件夹完全访问权限。


请重新用一种方式提出你的问题,避免使用“我认为…”这样的猜测性语言。目前看来,这更像是一条评论。 - geisterfurz007

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接