如何在Tomcat 8.5中使用JarScanFilter跳过指定库的扫描?
我之前从Tomcat 8.0升级到8.5版本时也踩过这个一模一样的坑,刚好能给你捋清楚原因和解决办法:
问题根源
Tomcat 8.5对JarScanner的清单文件扫描逻辑做了严格调整——在8.0.x版本里,JarScanner碰到清单里引用但实际不存在的Jar文件时会自动忽略,不会抛出异常;但8.5.x版本会严格校验这些依赖,一旦发现找不到对应的Jar就直接抛出FileNotFoundException。而你环境里的derby相关Jar(比如derby.jar)的清单文件里刚好引用了一系列derbyLocale_*.jar,但这些本地化Jar并没有实际部署在你的Tomcat中,所以就触发了这个异常。
具体解决方法
方法1:针对单个应用配置JarScanFilter(推荐)
如果只想解决当前应用的问题,直接修改该应用的META-INF/context.xml(如果想全局生效也可以改Tomcat的conf/context.xml),添加JarScanner的过滤规则:
<Context> <!-- 配置JarScanner过滤规则 --> <JarScanner> <JarScanFilter defaultPlugs="false" jarsToScan="*.jar" jarsToSkip="derbyLocale_*.jar"/> </JarScanner> </Context>
defaultPlugs="false":禁用Tomcat默认的Jar扫描过滤规则,避免和自定义规则冲突jarsToScan="*.jar":保持默认的全扫描逻辑,只排除特定JarjarsToSkip="derbyLocale_*.jar":明确跳过所有匹配该模式的Jar文件
方法2:全局配置跳过指定Jar
如果你希望所有应用都生效,修改Tomcat的conf/catalina.properties文件,找到tomcat.util.scan.StandardJarScanFilter.jarsToSkip属性,在已有列表末尾添加derbyLocale_*.jar:
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\ annotations-api.jar,ant-junit*.jar,ant-launcher.jar,ant.jar,\ ...,derbyLocale_*.jar
注意要保持换行和反斜杠的格式,确保配置能被正确解析。
方法3:移除不必要的Derby Jar(可选)
如果你的应用完全不需要使用Derby数据库,直接删除Tomcatlib目录下的derby.jar等相关Derby文件,从根源上避免对它的清单扫描。但一定要确认你的应用完全不依赖Derby,否则会引发其他运行错误。
验证配置是否生效
可以开启Tomcat的调试日志,查看JarScanner的扫描详情:
修改conf/logging.properties,添加:
org.apache.tomcat.util.scan.level = FINE
启动Tomcat后,查看日志就能看到哪些Jar被跳过,确认derbyLocale_*.jar是否被正确排除。
内容的提问来源于stack exchange,提问作者Andreas N

