没有找到适合的驱动程序用于应用程序镜像上的jdbc:sqlite

huangapple go评论76阅读模式
英文:

No suitable driver found for jdbc:sqlite on app image

问题

我有一个连接到SQLite的JavaFX应用程序使用以下代码

```java
Connection connection = DriverManager.getConnection("jdbc:sqlite:data.sqlite");

我在我的pom文件中添加了SQLite驱动程序的依赖项:

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.32.3.2</version>
</dependency>

我可以使用Maven Goals javafx:compilejavafx:run 顺利运行应用程序,一切都按预期工作,应用程序可以无问题地查询数据库。data.sqlite 文件被创建在项目的根文件夹中(与 src/pom.xml 同一文件夹)。

然而,当我尝试运行使用 jlink 构建的可执行文件时,我得到了线程标题中描述的错误。首先,我运行了Maven目标 javafx:jlink。这会在 target/image/ 中生成一些内容。我导航到 target/image/bin 并运行 ./java -m <name-of-my-module>/<group-id>.App,这是我构建的文件的运行命令。然后我得到了:

No suitable driver found for jdbc:sqlite:data.sqlite

还有一个 NullPointerException,因为数据库初始化例程尝试访问我的数据库连接。如何解决这个问题?提前感谢您的帮助。

编辑:似乎解决方案与在调用 DriverManager.getConnection() 之前添加 Class.forName() 语句有关。我尝试了以下操作:

Class.forName("org.sqlite.JDBC");
Connection connection = DriverManager.getConnection("jdbc:sqlite:data.sqlite");

通过这样做,现在应用程序可以运行了!但是,它仍然崩溃。我得到了 ClassNotFoundException: org.sqlite.JDBC。有什么提示吗...?


<details>
<summary>英文:</summary>

I have a JavaFX app that connects to SQLite using 

```java
Connection connection = DriverManager.getConnection(&quot;jdbc:sqlite:data.sqlite&quot;);

I have the dependency for SQLite driver on my pom file:

&lt;dependency&gt;
    &lt;groupId&gt;org.xerial&lt;/groupId&gt;
    &lt;artifactId&gt;sqlite-jdbc&lt;/artifactId&gt;
    &lt;version&gt;3.32.3.2&lt;/version&gt;
&lt;/dependency&gt;

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 &lt;name-of-my-module&gt;/&lt;group-id&gt;.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(&quot;org.sqlite.JDBC&quot;);
Connection connection = DriverManager.getConnection(&quot;jdbc:sqlite:data.sqlite&quot;);

By doing that, now the app renders! However, it still crashes. I get ClassNotFoundException: org.sqlite.JDBC. Any hints...?

答案1

得分: 3

这可能不会直接与jlink一起工作,因为据我所见,SQLite尚未模块化。我在这里描述了一种替代方法https://github.com/dlemmermann/JPackageScriptFX,它也在内部使用jlink,但只是为了创建一个专用的运行时。使用这种方法,连接SQLite可以正常工作。我知道这一点,因为我的应用程序也使用相同版本的SQLite驱动程序而没有问题。

英文:

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.

答案2

得分: 0

我通过使用Draque Thompson的Module Info Inject解决了这个问题。基本上,这个程序会为你的.jar创建一个module-info.class,让JLink将其视为一个模块。(如果解释不够清楚,我对Java的模块系统了解不深,抱歉)。

所以,我所做的基本上是:

  1. 克隆Module-Info-Inject并运行它。
  2. 选择所需的jar文件夹,然后点击"Inject"。
  3. 在生成的module-info.class文件上获取模块的名称。在我的情况下,它是sqlite.jdbc
  4. 将新模块添加到我的项目的module-info.java中。

生成的SQLite驱动程序的module-info.class文件如下所示:

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

在我的项目的module-info.java中要求该模块:

module com.demo {
    requires sqlite.jdbc;

    / * ... * /

    exports pkg.app;
}
英文:

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:

  1. Clone Module-Info-Inject and run it.
  2. Select the desired jar folder and click "Inject".
  3. On the generated module-info.class file, get the module's name. In my case it was sqlite.jdbc.
  4. Add the new module to my project's 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;
}

huangapple
  • 本文由 发表于 2020年8月14日 07:20:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63404475.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定