You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级Tomcat至9.0.70后Flyway 8.5.13抛出ClassLoader空指针异常

Tomcat升级至9.0.70后Flyway启动报NullPointerException排查

环境配置

  • Spring Boot 2.6.7
  • Flyway 8.5.13(PostgreSQL驱动42.2.9)
  • Java 11.0.17
  • Tomcat 从9.0.69升级至9.0.70后触发问题

报错堆栈

Caused by: java.lang.NullPointerException
                at org.flywaydb.core.internal.resource.classpath.ClassPathResource.read(ClassPathResource.java:108)
                at org.flywaydb.core.internal.resolver.ChecksumCalculator.calculateChecksumForResource(ChecksumCalculator.java:64)
                at org.flywaydb.core.internal.resolver.ChecksumCalculator.calculate(ChecksumCalculator.java:43)
                at org.flywaydb.core.internal.resolver.sql.SqlMigrationResolver.getChecksumForLoadableResource(SqlMigrationResolver.java:127)
                at org.flywaydb.core.internal.resolver.sql.SqlMigrationResolver.addMigrations(SqlMigrationResolver.java:169)
                at org.flywaydb.core.internal.resolver.sql.SqlMigrationResolver.resolveMigrations(SqlMigrationResolver.java:71)
                at org.flywaydb.core.internal.resolver.sql.SqlMigrationResolver.resolveMigrations(SqlMigrationResolver.java:50)

异常触发点源码

抛出NPE的ClassPathResource.read方法片段:

InputStream inputStream = null;
try {
    Enumeration<URL> urls = classLoader.getResources(fileNameWithAbsolutePath);
    while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        if (url.getPath() != null && url.getPath().contains(parentURL)) {
            inputStream = url.openStream();
            break;
        }
    }
} catch (IOException e) {
    throw new FlywayException(e);
}

if (inputStream == null) {
    throw new FlywayException("Unable to obtain inputstream for resource: " + fileNameWithAbsolutePath);
}

关键现象

迁移文件已被org.flywaydb.core.internal.scanner.classpath.ClassPathScanner和org.flywaydb.core.internal.resource.ResourceNameValidator正确识别,但读取资源时触发NPE。

可能原因

  1. String.contains(null)触发NPE:
    堆栈显示NPE发生在ClassPathResource.java:108,对应源码中url.getPath().contains(parentURL)这一行。String.contains(CharSequence)方法传入null参数会直接抛出NullPointerException,说明此时parentURL变量为null。
  2. Tomcat 9.0.70类加载器路径解析变更:
    Tomcat 9.0.70对类加载器获取资源的逻辑做了调整,导致Flyway在构建ClassPathResource时无法正确获取parentURL的值,最终传入null到contains方法中触发异常。
  3. Flyway 8.5.x版本兼容性问题:
    Flyway 8.5.x系列未适配Tomcat 9.0.70的类加载器行为变更,没有处理parentURL为null的场景。

解决方案

  1. 临时补丁修复:
    修改ClassPathResource.read方法中的判断逻辑,增加parentURL != null的前置检查:
    if (url.getPath() != null && parentURL != null && url.getPath().contains(parentURL)) {
    
  2. 升级Flyway版本:
    升级到Flyway 9.x及以上版本,这些版本已修复与Tomcat新版本的兼容性问题。
  3. 回退Tomcat版本:
    若暂时无法升级Flyway,可先回退到Tomcat 9.0.69,待兼容性问题解决后再升级。

内容的提问来源于stack exchange,提问作者Martin Zeller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:01:06