Драйвер JDBC не найден в упакованном приложении JavaFX "jlink"

Я установил драйвер 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

intelliJ_project и Linux_app

ОБНОВЛЕНИЕ2:

Зависимость pom.xml выглядит следующим образом:

        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.3.3</version>
        </dependency>

Содержит ли ваш модуль-info.java uses java.sql.Driver;?

VGR 23.04.2024 15:35

Мало информации. Является ли код вашего приложения модульным (JPMS)? Какой драйвер JDBC? Какие версии? Напишите небольшое приложение для демонстрации с минимальным кодом, который вы сможете опубликовать здесь целиком.

Basil Bourque 23.04.2024 16:37

@VGR добавил директиву uses - те же ошибки

Leder 06.05.2024 09:00

Пожалуйста, отредактируйте свой вопрос и включите зависимость из вашего pom.xml, в которой указан драйвер JDBC.

VGR 08.05.2024 04:31
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
167
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот частично ручное, несовершенное решение, которое все еще можно реализовать.

Шаги:

(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/

  • mariadb-java-client-3.3.3.jar
  • кофеин-2.9.3.jar
  • проверка качества-3.32.0.jar
  • error_prone_annotations-2.10.0.jar
  • jcl-over-slf4j-2.0.7.jar
  • jna-5.13.0.jar
  • jna-платформа-5.13.0.jar
  • slf4j-api-2.0.7.jar
  • вафля-jna-3.3.0.jar

(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) (тип = основной).

ОБНОВЛЕНИЕ — АВТОМАТИЗАЦИЯ в MAVEN

измените ваш pom.xml

<?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)

эталонный шаг: (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?

Leder 10.05.2024 16:50

(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.

life888888 10.05.2024 17:07

(1) Для модульных приложений используйте плагин Badass-JLink. (2) Для немодульного приложения используйте плагин Badass Runtime. (3) Некоторые проблемы с немодульным jar-файлом (JDBC-драйвер), необходимо использовать плагин Badass Runtime Plugin.

life888888 10.05.2024 17:18

Теперь я обновляю ответ, вы можете сделать это с помощью одной команды mvn.

life888888 11.05.2024 09:25

привет @life888888 Я успешно протестировал команду ./target/app/bin/app К сожалению, zip-файл создается в maven до того, как файл mariadb-java-client-3.3.3.jar копируется в каталог lib! Итак, в архиве отсутствует jar: Как я могу изменить pom.xml, чтобы сгенерировать полный zip-файл?

Leder 08.07.2024 13:38

Ниже приводится несовершенный подход: (1) Быстрый метод вручную. Удалите app.zip, а затем вручную сожмите файл target/app. (2) Метод Pom.xml, добавьте exec, удалите zip, а затем сожмите цель/приложение для создания файла app.zip.

life888888 09.07.2024 04:12

Другие вопросы по теме

Docker-Compose: пользовательский интерфейс Vue не подключается к Node js Express CORS API
Использование столбцов с плавающей запятой в миграциях Laravel 11
Оптимизация простого запроса MariaDB и то, что на самом деле стоит в объяснении оператора формата json
Утечка памяти при возникновении IntegrityError
Приложение Laravel испытывает таймауты базы данных при использовании методов firstOrNew или firstOrCreate в рабочей среде с большим количеством записей
Значение автоматического увеличения для столбца, не являющегося первичным ключом
Как подключить mariadb, работающий внутри Docker Compose, со скриптом Python, работающим вне Docker на хост-машине
Slurmctld: ошибка: ошибка mysql_real_connect: 1045 Доступ запрещен для пользователя «root» @ «localhost» (с использованием пароля: НЕТ)
Контейнер MariaDB Docker позволяет создавать базу данных и пользователя, но не выдает грант?
Ускорить запрос UPDATE (одна таблица с индексом)