环境:OpenJDK 11、JavaFX 11、MySQL 8.0、Gradle 6.2.2、IntellijIDEA、Windows 8.1
问题: 当我在 IDE 中运行我的程序时,它可以正常工作并毫无问题地连接到数据库,但是一旦我尝试运行使用 jLink 和 jPackage 构建的 .exe,它就会显示错误。
“ConnectionManager”类中的一些代码用于连接到本地 MySQL 数据库:
final String url = "jdbc:mysql://localhost:3306/", user = "root", password = "password", databaseName = "sifana";
final String databaseNameWithTimezone = databaseName + "?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC";
public static Connection connection;
private Connection createDatabase() throws SQLException {
String sql = "create database if not exists sifana";
Connection connection = DriverManager.getConnection(url + "?zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=UTC", user, password);
Statement statement = connection.createStatement();
statement.executeUpdate(sql);
statement.close();
return connection;
}
构建.gradle:
plugins {
id 'java'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'com.github.johnrengelman.shadow' version "5.0.0"
id 'org.beryx.jlink' version '2.17.2'
}
group 'yayarh'
version '1.0'
sourceCompatibility = '11'
targetCompatibility = '11'
mainClassName = "$moduleName/yayarh.Launcher"
repositories {
mavenCentral()
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation group: 'com.jfoenix', name: 'jfoenix', version: '9.0.9'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.19'
implementation group: 'org.controlsfx', name: 'controlsfx', version: '11.0.0'
}
application {
'yayarh.Launcher'
applicationDefaultJvmArgs = ["--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
"--add-exports=javafx.controls/com.sun.javafx.scene.control=com.jfoenix",
"--add-exports=javafx.base/com.sun.javafx.binding=com.jfoenix",
"--add-exports=javafx.graphics/com.sun.javafx.stage=com.jfoenix",
"--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
"--add-exports=javafx.base/com.sun.javafx.event=com.jfoenix"]
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
jlink {
launcher {
name = 'Sifana'
jvmArgs = applicationDefaultJvmArgs
}
jpackage {
installerOptions = [
'--description', 'Place a description here',
'--copyright', 'All copyrights to...',
'--vendor', 'vendor',
]
installerType = project.findProperty('installerType')
if (installerType == 'msi') {
imageOptions += ['--icon', 'src/main/resources/yayarh/images/sifana_ico.ico']
installerOptions += [
'--win-per-user-install', '--win-dir-chooser',
'--win-menu', '--win-shortcut'
]
}
}
}
jpackage {
doFirst {
project.getProperty('installerType') // throws exception if its missing
}
}
jar {
manifest {
attributes "Main-Class": 'yayarh.Launcher'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
javafx {
version = '11'
modules = ['javafx.controls', 'javafx.fxml']
}
错误堆栈跟踪:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at yayarh.merged.module/com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) at yayarh.merged.module/com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
at yayarh.merged.module/com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
at yayarh.merged.module/com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
at yayarh.merged.module/com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
at yayarh.merged.module/com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at sifana/yayarh.classes.ConnectionManager.createDatabase(ConnectionMana
ger.java:25)
at sifana/yayarh.classes.ConnectionManager.initiateConnection(ConnectionManager.java:18)
at sifana/yayarh.Main.start(Main.java:25)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
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.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at yayarh.merged.module/com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
at yayarh.merged.module/com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
at yayarh.merged.module/com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
at yayarh.merged.module/com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:338)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.ja
va:486)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1340)
at yayarh.merged.module/com.mysql.cj.NativeSession.connect(NativeSession.java:157)
at yayarh.merged.module/com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
at yayarh.merged.module/com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
... 17 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
at yayarh.merged.module/com.mysql.cj.protocol.ExportControlled.performTlsHandshake(ExportControlled.java:336)
at yayarh.merged.module/com.mysql.cj.protocol.StandardSocketFactory.performTlsHandshake(StandardSocketFactory.java:188)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeSocketConnection.performTlsHandshake(NativeSocketConnection.java:99)
at yayarh.merged.module/com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:329)
... 24 more
请注意,从 IDE 运行时它可以完美运行。