升级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。
可能原因
- String.contains(null)触发NPE:
堆栈显示NPE发生在ClassPathResource.java:108,对应源码中url.getPath().contains(parentURL)这一行。String.contains(CharSequence)方法传入null参数会直接抛出NullPointerException,说明此时parentURL变量为null。 - Tomcat 9.0.70类加载器路径解析变更:
Tomcat 9.0.70对类加载器获取资源的逻辑做了调整,导致Flyway在构建ClassPathResource时无法正确获取parentURL的值,最终传入null到contains方法中触发异常。 - Flyway 8.5.x版本兼容性问题:
Flyway 8.5.x系列未适配Tomcat 9.0.70的类加载器行为变更,没有处理parentURL为null的场景。
解决方案
- 临时补丁修复:
修改ClassPathResource.read方法中的判断逻辑,增加parentURL != null的前置检查:if (url.getPath() != null && parentURL != null && url.getPath().contains(parentURL)) { - 升级Flyway版本:
升级到Flyway 9.x及以上版本,这些版本已修复与Tomcat新版本的兼容性问题。 - 回退Tomcat版本:
若暂时无法升级Flyway,可先回退到Tomcat 9.0.69,待兼容性问题解决后再升级。
内容的提问来源于stack exchange,提问作者Martin Zeller
相关产品推荐
相关产品推荐

