Search code examples
javafxflywaymaven-shade-plugin

Maven-shade 3.5.2 + Flyway 10.12.0 (for HSQLDB 2.7.2 by API) doesn't work (JavaFX app.)


Flyway 10.12.0 (for HSQLDB 2.7.2 by API) doesn't work with maven-shade-plugin 3.5.2

v9.22.3 OK - 1 dependency : flyway-core

v10.12.0 NOK - 2 dependencies : flyway-core+flyway-database-hsqldb Flyway relative issue

It works in development. The error with the fat jar is the same as in development without flyway-database-hsql dependency :


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.(DriverDataSource.java:158)
    at org.flywaydb.core.internal.jdbc.DriverDataSource.(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.(DriverDataSource.java:158)
    at org.flywaydb.core.internal.jdbc.DriverDataSource.(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 code using API :

 Flyway flyway = Flyway.configure()
    .dataSource(
        databasePath,    // as jdbc:hsqldb:file:...
        JVMApplicationProperties.getDbUser(),
        JVMApplicationProperties.getDbPassord()
     )
     .locations("classpath:" + ApplicationPaths.getDATABASE_MIGRATION_PATH())
    .baselineOnMigrate(true)
     .load();
 flyway.migrate();

Maven-shade configuration :

<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>

@PiersWilliams here are my depedencies and versions when it's OK

<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>
    <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>

@jewelsea my first script V1_0__create_base.sql :

CREATE TABLE software (
softwareuuid UUID PRIMARY KEY,
currentversion VARCHAR(128),
lastversion VARCHAR(128),
createdat TIMESTAMP NOT NULL,
updatedat TIMESTAMP NOT NULL
);

Solution

  • As of version 10.0.0, Flyway has abandoned the use of Java reflection in favor of the Service Loader.

    The Service Loader allows you to dynamically load implementations of Flyway interfaces, such as database drivers, naming strategies, etc. This transition to the Service Loader was driven by performance and compatibility issues encountered with the use of Java reflection.

    So this tag is needed with Maven Shade :

    <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
    
    <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>
               <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
            </transformers>
            <filters>
                <filter>
                    <artifact>*:*</artifact>
                    <excludes>
                        <exclude>META-INF/maven/**</exclude>
                        <exclude>META-INF/*.SF</exclude>
                        <exclude>META-INF/*.DSA</exclude>
                        <exclude>META-INF/*.RSA</exclude>
                    </excludes>
                </filter>
            </filters>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

    Source found from Google code comment