Reputation: 2554
I have a JavaFX app that connects to SQLite using
Connection connection = DriverManager.getConnection("jdbc:sqlite:data.sqlite");
I have the dependency for SQLite driver on my pom file:
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.32.3.2</version>
</dependency>
I can run the App smoothly using Maven Goals javafx:compile
and javafx:run
, everything works as expected and the app has no trouble querying the db. The data.sqlite
file is created on the project's root folder (same folder as src/
and pom.xml
).
However, when I try to run an executable file built with jlink
, I get the error described on the thread's title. First, I ran maven goal javafx:jlink
. This generates some stuff at target/image/
. I navigated to target/image/bin
and ran ./java -m <name-of-my-module>/<group-id>.App
, which is the command for running the file I built. Then I get:
No suitable driver found for jdbc:sqlite:data.sqlite
And a NullPointerException
because of the database init routines that try to access my database connection. How can I fix this? Thanks in advance.
EDIT: It seems that the solution has something to do with adding a Class.forName()
statement before calling DriverManager.getConnection()
. I tried doing the following:
Class.forName("org.sqlite.JDBC");
Connection connection = DriverManager.getConnection("jdbc:sqlite:data.sqlite");
By doing that, now the app renders! However, it still crashes. I get ClassNotFoundException: org.sqlite.JDBC
. Any hints...?
Upvotes: 1
Views: 769
Reputation: 2554
I was able to solve this by using Draque Thompson's Module Info Inject. Basically what the program does is creating a module-info.class
for your .jar
, letting JLink see it as a module. (Sorry if the explanation is lacking, I don't have deep knowledge of Java's module system).
So basically what I done was:
module-info.class
file, get the module's name. In my case it was sqlite.jdbc
.module-info.java
.The generated module-info.class
file for SQLite driver:
module sqlite.jdbc {
requires transitive java.logging;
requires transitive java.sql;
exports org.sqlite;
exports org.sqlite.core;
exports org.sqlite.date;
exports org.sqlite.javax;
exports org.sqlite.jdbc3;
exports org.sqlite.jdbc4;
exports org.sqlite.util;
provides java.sql.Driver with org.sqlite.JDBC;
}
Requiring the module in my project's module-info.java
:
module com.demo {
requires sqlite.jdbc;
/ * ... * /
exports pkg.app;
}
Upvotes: 0
Reputation: 10650
I fear this will not work directly with jlink because as far as I have seen SQLite is not yet modularized. I have described an alternative approach here https://github.com/dlemmermann/JPackageScriptFX which also uses jlink internally but only to create a dedicated runtime. With this approach linking SQLite works. I know that because my own applications also use the exact same version of the SQLite driver without problems.
Upvotes: 4