Flyway10.12.0+HSQLDB2.7.2搭配maven-shade-plugin3.5.2打包后运行失败
JavaFX+Flyway 10+HSQLDB打包Fat Jar后运行失败问题
问题描述
在JavaFX应用中使用Flyway 10.12.0通过API操作HSQLDB 2.7.2,搭配maven-shade-plugin 3.5.2打包成Fat Jar后运行失败。Flyway 9.22.3版本仅依赖flyway-core就能正常工作,但升级到10.12.0后,必须同时引入flyway-core和flyway-database-hsqldb两个依赖。开发环境直接运行无问题,但打包后的Fat Jar执行时抛出**"No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb"**异常,该报错和开发环境下缺失flyway-database-hsqldb依赖时的提示完全一致。
错误堆栈
FlywayException catch for flyway.migrate() : No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb org.flywaydb.core.api.FlywayException: No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb at org.flywaydb.core.internal.jdbc.DriverDataSource.<init>(DriverDataSource.java:158) at org.flywaydb.core.internal.jdbc.DriverDataSource.<init>(DriverDataSource.java:96) at org.flywaydb.core.api.configuration.ClassicConfiguration.setDataSource(ClassicConfiguration.java:1093) at org.flywaydb.core.api.configuration.FluentConfiguration.dataSource(FluentConfiguration.java:626) at fr.bla.utils.DatabaseMigration.configure(DatabaseMigration.java:23) at fr.bla.MyMain.initializationAsynchronousTask(MyMain.java:82) at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804) at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1491) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:2073) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2035) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187) 2024-04-29 13:38:00,898 ERROR f.s.s.MyMain [ForkJoinPool.commonPool-worker-1] Error in splash screen initialization virtual thread : org.flywaydb.core.api.FlywayException: No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb java.util.concurrent.CompletionException: org.flywaydb.core.api.FlywayException: No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315) at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320) at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1807) at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:507) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1491) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:2073) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2035) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187) Caused by: org.flywaydb.core.api.FlywayException: No database found to handle jdbc:hsqldb:file:C:/Users/toMyDb at org.flywaydb.core.internal.jdbc.DriverDataSource.<init>(DriverDataSource.java:158) at org.flywaydb.core.internal.jdbc.DriverDataSource.<init>(DriverDataSource.java:96) at org.flywaydb.core.api.configuration.ClassicConfiguration.setDataSource(ClassicConfiguration.java:1093) at org.flywaydb.core.api.configuration.FluentConfiguration.dataSource(FluentConfiguration.java:626) at fr.bla.utils.DatabaseMigration.configure(DatabaseMigration.java:23) at fr.bla.MyMain.initializationAsynchronousTask(MyMain.java:82) at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
Flyway API使用代码
Flyway flyway = Flyway.configure() .dataSource( databasePath, // 格式为 jdbc:hsqldb:file:... JVMApplicationProperties.getDbUser(), JVMApplicationProperties.getDbPassord() ) .locations("classpath:" + ApplicationPaths.getDATABASE_MIGRATION_PATH()) .baselineOnMigrate(true) .load(); flyway.migrate();
Maven Shade插件配置(原配置)
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${shade.version}</version> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>fr.bla.Launcher</mainClass> </transformer> </transformers> <artifactSet> <excludes> <exclude>org.apache.maven.plugins:maven-compiler-plugin</exclude> <exclude>org.openjfx:javafx-maven-plugin</exclude> <exclude>org.apache.maven.plugins:maven-shade-plugin</exclude> <exclude>org.codehaus.mojo:exec-maven-plugin</exclude> <exclude>org.junit.jupiter:junit-jupiter-api</exclude> <exclude>org.mockito:mockito-core</exclude> <exclude>org.mockito:mockito-junit-jupiter</exclude> <exclude>org.apache.maven.surefire:surefire-plugin</exclude> <exclude>org.jacoco:jacoco-maven-plugin</exclude> <exclude>org.testfx:testfx-junit5</exclude> <exclude>org.hamcrest:hamcrest</exclude> </excludes> </artifactSet> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>
正常工作的依赖配置(Flyway 9.22.3)
<properties> <maven.compiler.version>3.13.0</maven.compiler.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.release>22</maven.compiler.release> <javafx.version>22</javafx.version> <javafx.maven.version>0.0.8</javafx.maven.version> <hsqldb.version>2.7.2</hsqldb.version> <logback.version>1.5.6</logback.version> <shade.version>3.5.2</shade.version> <lombok.version>1.18.32</lombok.version> <flyway.version>9.22.3</flyway.version> </properties> <dependencies> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>${hsqldb.version}</version> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>${flyway.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>${logback.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> ... </dependencies>
迁移脚本示例
CREATE TABLE software ( softwareuuid UUID PRIMARY KEY, currentversion VARCHAR(128), lastversion VARCHAR(128), createdat TIMESTAMP NOT NULL, updatedat TIMESTAMP NOT NULL );
问题原因及解决办法
原因
Flyway 10+版本采用**SPI(服务提供者接口)**机制加载数据库特定实现类,flyway-database-hsqldb中包含META-INF/services/org.flywaydb.core.api.database.DatabaseProvider文件,声明了HSQLDB的数据库提供者实现。maven-shade-plugin默认不会合并多个JAR中的同名SPI配置文件,导致Fat Jar中缺失该声明,Flyway无法识别JDBC URL对应的数据库类型。
解决步骤
- 修改Maven Shade插件配置,添加
ServicesResourceTransformer以合并SPI服务文件:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>${shade.version}</version> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>fr.bla.Launcher</mainClass> </transformer> <!-- 新增:合并SPI服务配置文件 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <artifactSet> <excludes> <exclude>org.apache.maven.plugins:maven-compiler-plugin</exclude> <exclude>org.openjfx:javafx-maven-plugin</exclude> <exclude>org.apache.maven.plugins:maven-shade-plugin</exclude> <exclude>org.codehaus.mojo:exec-maven-plugin</exclude> <exclude>org.junit.jupiter:junit-jupiter-api</exclude> <exclude>org.mockito:mockito-core</exclude> <exclude>org.mockito:mockito-junit-jupiter</exclude> <exclude>org.apache.maven.surefire:surefire-plugin</exclude> <exclude>org.jacoco:jacoco-maven-plugin</exclude> <exclude>org.testfx:testfx-junit5</exclude> <exclude>org.hamcrest:hamcrest</exclude> </excludes> </artifactSet> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>
- 确认依赖完整性,确保
flyway-database-hsqldb已添加到pom.xml:
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-database-hsqldb</artifactId> <version>${flyway.version}</version> </dependency>
- 验证打包结果:打开生成的Fat Jar,检查
META-INF/services/org.flywaydb.core.api.database.DatabaseProvider文件,确认包含org.flywaydb.database.hsqldb.HSQLDBDatabaseProvider条目。
内容的提问来源于stack exchange,提问作者2023
相关产品推荐
相关产品推荐

