Tomcat:At least one JAR was scanned for TLDs yet contained no TLDs
启动Tomcat的时候,经常见到这样的BUG:
14-Apr-2019 13:53:25.198 信息 [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars 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. 返回顶部 收缩SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
以前不知道怎么处理,怎么处理才是正确的,最近研究了点点Tomcat源码,也算知其一,知其二,不知其三四五六七了,下面先贴上解决方案:
解决方案:
catalina-home/conf/Catalina.properties中有这样一个属性:jarsToSkip
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\ bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,\ annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,\ catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,\ catalina-tribes.jar,\ jasper.jar,jasper-el.jar,ecj-*.jar,\ tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,\ tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,\ tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,\ tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,\ tomcat-jdbc.jar,\ tools.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,\ jstl.jar,taglibs-standard-spec-*.jar,\ geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,\ ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,\ jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,\ xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,\ junit.jar,junit-*.jar,ant-launcher.jar,\ cobertura-*.jar,asm-*.jar,dom4j-*.jar,icu4j-*.jar,jaxen-*.jar,jdom-*.jar,\ jetty-*.jar,oro-*.jar,servlet-api-*.jar,tagsoup-*.jar,xmlParserAPIs-*.jar,\ xom-*.jar 返回顶部 收缩我们只需要将上面的属性改成:
tomcat.util.scan.StandardJarScanFilter.jarsToSkip= * .jar 返回顶部 收缩
再次启动Tomcat,查看容器启动时候效果:发现果然没有了之前的那个提示信息.
Why?
这个提示信息取消掉它出现,这是其一解决方案,其二呢?这样做会带来什么效果
可能JSP后端的动态渲染技术一定程度上会影响响应速度,如果jar包中没有tld,没有自定义tld等标签的话,我们可以放心使用上述方式。上述方式原理呢下面简单记录下:
解析上述tld代码方法位于:TldScanner#scanJars.
解析方式会按照
解释说明: 会扫描该项目所有加载到的jar包,包括jre/lib下的包,遍历每个jar检测是否有tld,而Catalina.properties配置中的两个jarsToSkip和jarsToScan作用呢?
check方法中tldSkipSet就是取的jarsToSkip的值,tldScanSet取的就是jarsToSkip的值;tldSkipSet通过正则表达式匹配当前check的jar包,所有的jar都会匹配上*.jar,但是tldScanSet就不一定可以匹配上,Catalina.properties中jarsToScan都是日志相关的jar包,无法和当前正在校验的jar包正则匹配上,所有这个jar包Tomcat不会做任何扫描处理。上述方法在一定程度上提高了Tomcat启动速度,如果在当前项目加载jar包特别多的情况下提升应该明显。
public boolean check(JarScanType jarScanType, String jarName) { Lock readLock = configurationLock.readLock(); readLock.lock(); try { final boolean defaultScan; final Set<String> toSkip; final Set<String> toScan; switch (jarScanType) { case TLD: { defaultScan = defaultTldScan; toSkip = tldSkipSet; toScan = tldScanSet; break; } case PLUGGABILITY: { defaultScan = defaultPluggabilityScan; toSkip = pluggabilitySkipSet; toScan = pluggabilityScanSet; break; } case OTHER: default: { defaultScan = true; toSkip = defaultSkipSet; toScan = defaultScanSet; } } if (defaultScan) { if (Matcher.matchName(toSkip, jarName)) { if (Matcher.matchName(toScan, jarName)) { return true; } else { return false; } } return true; } else { if (Matcher.matchName(toScan, jarName)) { if (Matcher.matchName(toSkip, jarName)) { return false; } else { return true; } } return false; } } finally { readLock.unlock(); } }
How?
假如当前情况下使用到的jar包中有使用tld文件,我们又不想全部扫描所有jar,并且不想看到上述信息At least one JAR 出现,解决方案是:
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=*.jar tomcat.util.scan.StandardJarScanFilter.jarsToScan=yourjarFile.jar 返回顶部 收缩
总结
通过修改Catalina.properties可以提高程序启动速度,如果有使用到tld文件,再配置比较合适。
