如何在JavaFX应用程序中集成MySQL JDBC驱动程序和JLink?

qlvxas9a  于 2023-06-28  发布在  Java
关注(0)|答案(1)|浏览(204)

基本上,当我在eclipse上运行我的模块化项目时,它工作得很好,但是当我使用jlink创建运行时映像时,它会抛出一个mysql连接错误。

Caused by: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/timp_db
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:708)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:230)
        at projectTMIP/database.DBConnect.getConnection(DBConnect.java:14)
        ... 56 more

这是我的module-info.java看起来像

module projectTMIP {
    requires javafx.controls;
    requires java.sql;
    requires javafx.fxml;
    requires javafx.graphics;

    opens model to javafx.graphics, javafx.fxml;
    opens controller to javafx.fxml;

    exports controller;

    requires transitive javafx.base;
}

这是我在我的根项目上导航的eclipse终端上使用的命令。

jlink --module-path "path/to/jmod";"path/to/mysql/connector.jar";bin --add-modules projectTMIP --output output/image --launcher run=projectTMIP/model.Main

我希望生成一个运行时映像,其中包含mysqlconnector.jar

wmomyfyw

wmomyfyw1#

***警告:*使用jpackage工具可能会使部署应用程序变得更加复杂,因为该工具只能为其执行的操作系统创建可执行文件/安装程序。

jlink工具只适用于 explicit 模块。换句话说,模块必须有一个module-info描述符。因此,您不能在运行时映像中包含MySQL JDBC驱动程序,因为该库不是模块化的。您可以尝试“破解”依赖项以使其模块化,但这可能很困难并且容易出错。
也就是说,jpackage工具可以处理模块化和非模块化应用程序。这在这种情况下很重要,因为JDBC驱动程序是服务提供者,这意味着命名模块可以通过服务加载器机制加载它们,即使提供者位于未命名模块中。为了在代码中包含MySQL JDBC驱动程序,配置jpackage将所有需要的显式模块放在自定义运行时映像中(它在幕后使用jlink),然后通过--input选项将驱动程序放在类路径上。

示例

这里有一个非常基本的例子来展示我上面描述的内容。请注意,本示例中的所有工具调用都是直接在命令行上执行的,而不是通过IDE或构建工具执行的。
该示例不包括JavaFX,因为它对所演示的内容并不重要。

源码

模块信息:

module sample {
    requires java.sql;
}

示例.主

package sample;

import java.sql.DriverManager;

public class Main {

    public static void main(String[] args) throws Exception {
        try (var con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test")) {
            System.out.println("Made connection!");
        }
    }
}

项目布局

C:\...\PROJECT
│   
├───lib
│       mysql-connector-j-8.0.33.jar
│       
└───src
    └───sample
        │   module-info.java
        │   
        └───sample
                Main.java

创建可执行文件

首先编译项目:

javac --module-source-path src --module sample -d out/modules

然后打包应用程序:

jpackage --type app-image --name TestApp --module-path out/modules --add-modules java.naming --module sample/sample.Main --input lib --dest out --win-console

几点注意事项:
1.我包含了--win-console,因为我想在运行可执行文件时看到控制台输出(我使用的是Windows)。
1.我包含--add-modules java.naming是因为MySQL JDBC驱动程序似乎需要该模块才能运行。您可能会发现需要包含或不需要包含更多模块;如果需要,只需将它们添加到--add-modules参数中,或者,如果更有意义,将适当的requires指令添加到代码的module-info描述符中。

运行Executable

我目前没有一个MySQL服务器可用于测试,所以下面显示的输出是一个异常堆栈跟踪。但是如果您查看异常,您会看到错误是无法建立连接。这一事实,加上堆栈跟踪中显示的MySQL JDBC驱动程序代码,表明MySQL JDBC驱动程序已成功找到。
命令(Windows):

.\out\TestApp\TestApp.exe

输出(没有运行MySQL服务器):

Exception in thread "main" com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:175)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:446)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:239)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:188)
        at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
        at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
        at sample/sample.Main.main(Unknown Source)
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
        at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:150)
        at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:166)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:121)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:945)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:815)
        ... 6 more
Caused by: java.net.ConnectException: Connection refused: connect
        at java.base/sun.nio.ch.Net.connect0(Native Method)
        at java.base/sun.nio.ch.Net.connect(Unknown Source)
        at java.base/sun.nio.ch.Net.connect(Unknown Source)
        at java.base/sun.nio.ch.NioSocketImpl.connect(Unknown Source)
        at java.base/java.net.SocksSocketImpl.connect(Unknown Source)
        at java.base/java.net.Socket.connect(Unknown Source)
        at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63)
        ... 9 more
Failed to launch JVM

应用布局

下面是由上面的jpackage命令生成的应用程序的布局:

C:\...\PROJECT\OUT\TESTAPP
│   TestApp.exe
│   
├───app
│       .jpackage.xml
│       mysql-connector-j-8.0.33.jar
│       TestApp.cfg
│       
└───runtime
    │   release
    │   
    ├───bin
    │   │   api-ms-win-core-console-l1-1-0.dll
    │   │   api-ms-win-core-console-l1-2-0.dll
    │   │   api-ms-win-core-datetime-l1-1-0.dll
    │   │   api-ms-win-core-debug-l1-1-0.dll
    │   │   api-ms-win-core-errorhandling-l1-1-0.dll
    │   │   api-ms-win-core-fibers-l1-1-0.dll
    │   │   api-ms-win-core-file-l1-1-0.dll
    │   │   api-ms-win-core-file-l1-2-0.dll
    │   │   api-ms-win-core-file-l2-1-0.dll
    │   │   api-ms-win-core-handle-l1-1-0.dll
    │   │   api-ms-win-core-heap-l1-1-0.dll
    │   │   api-ms-win-core-interlocked-l1-1-0.dll
    │   │   api-ms-win-core-libraryloader-l1-1-0.dll
    │   │   api-ms-win-core-localization-l1-2-0.dll
    │   │   api-ms-win-core-memory-l1-1-0.dll
    │   │   api-ms-win-core-namedpipe-l1-1-0.dll
    │   │   api-ms-win-core-processenvironment-l1-1-0.dll
    │   │   api-ms-win-core-processthreads-l1-1-0.dll
    │   │   api-ms-win-core-processthreads-l1-1-1.dll
    │   │   api-ms-win-core-profile-l1-1-0.dll
    │   │   api-ms-win-core-rtlsupport-l1-1-0.dll
    │   │   api-ms-win-core-string-l1-1-0.dll
    │   │   api-ms-win-core-synch-l1-1-0.dll
    │   │   api-ms-win-core-synch-l1-2-0.dll
    │   │   api-ms-win-core-sysinfo-l1-1-0.dll
    │   │   api-ms-win-core-timezone-l1-1-0.dll
    │   │   api-ms-win-core-util-l1-1-0.dll
    │   │   api-ms-win-crt-conio-l1-1-0.dll
    │   │   api-ms-win-crt-convert-l1-1-0.dll
    │   │   api-ms-win-crt-environment-l1-1-0.dll
    │   │   api-ms-win-crt-filesystem-l1-1-0.dll
    │   │   api-ms-win-crt-heap-l1-1-0.dll
    │   │   api-ms-win-crt-locale-l1-1-0.dll
    │   │   api-ms-win-crt-math-l1-1-0.dll
    │   │   api-ms-win-crt-multibyte-l1-1-0.dll
    │   │   api-ms-win-crt-private-l1-1-0.dll
    │   │   api-ms-win-crt-process-l1-1-0.dll
    │   │   api-ms-win-crt-runtime-l1-1-0.dll
    │   │   api-ms-win-crt-stdio-l1-1-0.dll
    │   │   api-ms-win-crt-string-l1-1-0.dll
    │   │   api-ms-win-crt-time-l1-1-0.dll
    │   │   api-ms-win-crt-utility-l1-1-0.dll
    │   │   java.dll
    │   │   jimage.dll
    │   │   jli.dll
    │   │   msvcp140.dll
    │   │   net.dll
    │   │   nio.dll
    │   │   syslookup.dll
    │   │   ucrtbase.dll
    │   │   vcruntime140.dll
    │   │   vcruntime140_1.dll
    │   │   verify.dll
    │   │   zip.dll
    │   │
    │   ├───client
    │   │       jvm.dll
    │   │
    │   └───server
    │           jvm.dll
    │
    ├───conf
    │   │   logging.properties
    │   │   net.properties
    │   │
    │   └───security
    │       │   java.policy
    │       │   java.security
    │       │
    │       └───policy
    │           │   README.txt
    │           │
    │           ├───limited
    │           │       default_local.policy
    │           │       default_US_export.policy
    │           │       exempt_local.policy
    │           │
    │           └───unlimited
    │                   default_local.policy
    │                   default_US_export.policy
    │
    ├───legal
    │   ├───java.base
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       aes.md
    │   │       asm.md
    │   │       ASSEMBLY_EXCEPTION
    │   │       c-libutl.md
    │   │       cldr.md
    │   │       icu.md
    │   │       LICENSE
    │   │       public_suffix.md
    │   │       unicode.md
    │   │       wepoll.md
    │   │       zlib.md
    │   │
    │   ├───java.logging
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       ASSEMBLY_EXCEPTION
    │   │       LICENSE
    │   │
    │   ├───java.naming
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       ASSEMBLY_EXCEPTION
    │   │       LICENSE
    │   │
    │   ├───java.security.sasl
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       ASSEMBLY_EXCEPTION
    │   │       LICENSE
    │   │
    │   ├───java.sql
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       ASSEMBLY_EXCEPTION
    │   │       LICENSE
    │   │
    │   ├───java.transaction.xa
    │   │       ADDITIONAL_LICENSE_INFO
    │   │       ASSEMBLY_EXCEPTION
    │   │       LICENSE
    │   │
    │   └───java.xml
    │           ADDITIONAL_LICENSE_INFO
    │           ASSEMBLY_EXCEPTION
    │           bcel.md
    │           dom.md
    │           jcup.md
    │           LICENSE
    │           xalan.md
    │           xerces.md
    │
    └───lib
        │   classlist
        │   jrt-fs.jar
        │   jvm.cfg
        │   jvm.lib
        │   modules
        │   tzdb.dat
        │   tzmappings
        │
        └───security
                blocked.certs
                cacerts
                default.policy
                public_suffix_list.dat

相关问题