Я установил драйвер MariaDB-JDBC-Java Driver V 3.3.3 из репозитория maven. Когда я выдаю mvn clean javafx:jlink
, полученное приложение Linux не запускается с ошибкой, не находя драйвер:
java.lang.ClassNotFoundException: org.mariadb.jdbc.Driver
Команда mvn clean javafx:run
отлично работает в Linux и Windows.
Скажите, пожалуйста, почему цель mvn "javafx:jlink" не работает, как только я записываю зависимость Java-коннектора mariadb в pom.xml?
Я попытался заменить Java-клиент mariadb Java-коннектором mysql в pom.xml
, и он ведет себя точно так же.
Я ожидал, что упакованное Java-приложение подключится через драйвер к контейнеру mariadb, как это успешно происходит в строке cmd и IntelliJ IDEA - как для Windows, так и для Arch Linux.
------------------модуль-info.java
module org.leder.gldisplaymanager {
requires javafx.controls;
requires javafx.fxml;
requires java.sql;
opens org.leder.gldisplaymanager to javafx.fxml;
exports org.leder.gldisplaymanager;
exports org.leder.gldisplaymanager.gui;
opens org.leder.gldisplaymanager.gui to javafx.fxml;
uses java.sql.Driver;
}
ОБНОВЛЕНИЕ: я скомпилировал минимальный пример импорта проекта IntelliJ и выполнения приложения Linux следующим образом:
ожидаемый результат:
java.sql.SQLNonTransientConnectionException: Socket fail to connect to host:address=(host=localhost)(port=3306)(type=primary). Verbindungsaufbau abgelehnt
фактический результат:
java.sql.SQLException: No suitable driver found for jdbc:mariadb://localhost/display_manager
ОБНОВЛЕНИЕ2:
Зависимость pom.xml выглядит следующим образом:
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.3.3</version>
</dependency>
Мало информации. Является ли код вашего приложения модульным (JPMS)? Какой драйвер JDBC? Какие версии? Напишите небольшое приложение для демонстрации с минимальным кодом, который вы сможете опубликовать здесь целиком.
@VGR добавил директиву uses
- те же ошибки
Пожалуйста, отредактируйте свой вопрос и включите зависимость из вашего pom.xml, в которой указан драйвер JDBC.
Вот частично ручное, несовершенное решение, которое все еще можно реализовать.
(1) откройте свой intelliJ_project и Linux_app
(2) скачать mariadb.zip
(3) разархивируйте mariadb.zip
(4) cd mariadb
(5) mvn package
сгенерировать вывод -> target/mariadb-1.0-SNAPSHOT.jar
(6) mvn dependency:copy-dependencies -DoutputDirectory=target/libs
генерировать → target/libs включает все файлы jar в этом каталоге
(7) mvn javafx:jlink
создать → каталог цели/приложения
(8) выполнять команды
cp target/libs/mariadb-java-client-3.3.3.jar target/app/lib/
cp target/libs/caffeine-2.9.3.jar target/app/lib/
cp target/libs/checker-qual-3.32.0.jar target/app/lib/
cp target/libs/error_prone_annotations-2.10.0.jar target/app/lib/
cp target/libs/jcl-over-slf4j-2.0.7.jar target/app/lib/
cp target/libs/jna-5.13.0.jar target/app/lib/
cp target/libs/jna-platform-5.13.0.jar target/app/lib/
cp target/libs/slf4j-api-2.0.7.jar target/app/lib/
cp target/libs/waffle-jna-3.3.0.jar target/app/lib/
cp target/app/bin/app target/app/bin/app.org
Скопируйте файлы jar MariaDB в arget/app/lib/
(9) редактировать файл target/app/bin/app
#!/usr/bin/env sh
##############################################################################
##
## hellofx start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG = "$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG = "$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED = "`pwd`"
cd "`dirname \"$PRG\"`/.." >/dev/null
APP_HOME = "`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME = "hellofx"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and HELLOFX_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS = ""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD = "maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH = "$APP_HOME/lib/*"
JAVA_HOME = "$APP_HOME"
JAVACMD = "$JAVA_HOME/bin/java"
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD = "$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS = "$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVA_HOME = "$APP_HOME"
JAVACMD = "$JAVA_HOME/bin/java"
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP = ""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS = "$ROOTDIRS$SEP$dir"
SEP = "|"
done
OURCYGPATTERN = "(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN = "$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i` = "\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $CDS_JVM_OPTS $JAVA_OPTS $HELLOFX_OPTS -classpath "\"$CLASSPATH\"" org.leder.mariadb.HelloApplication "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
(10) Тестовый запуск
./target/app/bin/app
вы получите ожидаемый результат: java.sql.SQLNonTransientConnectionException: сокету не удалось подключиться к хосту: адрес = (хост = локальный хост) (порт = 3306) (тип = основной).
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.leder</groupId>
<artifactId>mariadb</artifactId>
<version>1.0-SNAPSHOT</version>
<name>mariadb</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.0</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.6</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>org.leder.mariadb/org.leder.mariadb.HelloApplication</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>default-cli</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<sourceFile>${project.build.directory}/libs/caffeine-2.9.3.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/caffeine-2.9.3.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/checker-qual-3.32.0.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/checker-qual-3.32.0.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/error_prone_annotations-2.10.0.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/error_prone_annotations-2.10.0.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/jcl-over-slf4j-2.0.7.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/jcl-over-slf4j-2.0.7.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/jna-5.13.0.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/jna-5.13.0.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/jna-platform-5.13.0.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/jna-platform-5.13.0.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/slf4j-api-2.0.7.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/slf4j-api-2.0.7.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/waffle-jna-3.3.0.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/waffle-jna-3.3.0.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.build.directory}/libs/mariadb-java-client-3.3.3.jar</sourceFile>
<destinationFile>${project.build.directory}/app/lib/mariadb-java-client-3.3.3.jar</destinationFile>
</fileSet>
<fileSet>
<sourceFile>${project.basedir}/src/main/dist/app</sourceFile>
<destinationFile>${project.build.directory}/app/bin/app</destinationFile>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
эталонный шаг: (9) отредактируйте файл target/app/bin/app <- скопируйте этот файл
(а) создать каталог dist в mariadb/src/main
(б) поставить приложение в (а)
(c) путь mariadb/src/main/dist/app
mvn clean javafx:jlink com.coderplus.maven.plugins:copy-rename-maven-plugin:1.0:copy
./target/app/bin/app
Вы можете сделать это одной командой mvn, можете пропустить шаги: (1) ~ (9)
(1) содержимое приложения изменено из плагина GradleThe Badass Runtime Plugin
。 Я взят из https://github.com/beryx-gist/badass-runtime-example-javafx ( beryx-gist /
крутой пример-время выполнения-javafx
Публика )
(2) Этот ответ недостаточно хорош. Если вы уже знаете, как выполнять действия вручную, вы можете переписать приведенное выше содержимое в автоматизированную конфигурацию Maven.
(3) конечный каталог приложения
app
├── bin
│ ├── app (New app file)
│ ├── app.org (original app file)
...
├── lib
│ ├── caffeine-2.9.3.jar
│ ├── checker-qual-3.32.0.jar
│ ├── error_prone_annotations-2.10.0.jar
│ ├── jcl-over-slf4j-2.0.7.jar
│ ├── jna-5.13.0.jar
│ ├── jna-platform-5.13.0.jar
│ ├── slf4j-api-2.0.7.jar
│ ├── waffle-jna-3.3.0.jar
│ ├── mariadb-java-client-3.3.3.jar
...
Мне нужно некоторое время, чтобы проверить данные шаги. Но какова основная причина? Это Мейвен? Я буду в порядке, если перейду на Gradle?
(1) Я не меняю конфигурацию или код вашего проекта. (2) Если вы хотите быстро запустить, да, используйте Gradle, начните с github.com/beryx-gist/badass-runtime-example-javafx (beryx-gist / badass-runtime-example-javafx Public) ( 3) Основная причина: существует два типа приложений: (а) немодульное приложение (б) модульное приложение. Какой-нибудь инструмент или плагин может преобразовать немодульный jar в модульный jar, но mariadb-java-client-3.3.3.jar сложно описать одним словом. Итак, быстрый и простой способ — относиться к нему как к немодульной банке. Только один вариант — badass-runtime
.
(1) Для модульных приложений используйте плагин Badass-JLink. (2) Для немодульного приложения используйте плагин Badass Runtime. (3) Некоторые проблемы с немодульным jar-файлом (JDBC-драйвер), необходимо использовать плагин Badass Runtime Plugin.
Теперь я обновляю ответ, вы можете сделать это с помощью одной команды mvn.
привет @life888888 Я успешно протестировал команду ./target/app/bin/app
К сожалению, zip-файл создается в maven до того, как файл mariadb-java-client-3.3.3.jar
копируется в каталог lib
! Итак, в архиве отсутствует jar: Как я могу изменить pom.xml
, чтобы сгенерировать полный zip-файл?
Ниже приводится несовершенный подход: (1) Быстрый метод вручную. Удалите app.zip, а затем вручную сожмите файл target/app. (2) Метод Pom.xml, добавьте exec, удалите zip, а затем сожмите цель/приложение для создания файла app.zip.
Содержит ли ваш модуль-info.java
uses java.sql.Driver;
?