I have installed MariaDB-JDBC-Java Driver V 3.3.3 from maven repo. When I issue mvn clean javafx:jlink
the resulting Linux app does not start with an error, not finding the Driver:
java.lang.ClassNotFoundException: org.mariadb.jdbc.Driver
The command mvn clean javafx:run
works just fine in Linux and Windows.
Please tell me why mvn target "javafx:jlink" is broken as soon as I write the dependency of the mariadb java connector into pom.xml?
I tried to substitue the mariadb java client with the mysql java connector in pom.xml
and it has exactly the same behaviour.
I expected the packaged java app to connect via driver to the mariadb container as it is successfully doing on cmd line and IntelliJ IDEA - both Windows and Arch Linux.
-----------------module-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;
}
UPDATE: I compiled a minimal example for IntelliJ project import and Linux app execution as follows -
expected result:
java.sql.SQLNonTransientConnectionException: Socket fail to connect to host:address=(host=localhost)(port=3306)(type=primary). Verbindungsaufbau abgelehnt
actual result:
java.sql.SQLException: No suitable driver found for jdbc:mariadb://localhost/display_manager
intelliJ_project and Linux_app
UPDATE2:
pom.xml dependency is as follows:
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.3.3</version>
</dependency>
Here is a partially manual, imperfect solution that can still be executed.
(1) open your intelliJ_project and Linux_app
(2) download mariadb.zip
(3) unzip mariadb.zip
(4) cd mariadb
(5) mvn package
generate output -> target/mariadb-1.0-SNAPSHOT.jar
(6) mvn dependency:copy-dependencies -DoutputDirectory=target/libs
generate -> target/libs include all jar files in this directory
(7) mvn javafx:jlink
generate -> target/app directory
(8) execute commands
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
Copy MariaDB jar files to arget/app/lib/
(9) edit target/app/bin/app file
#!/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) Test Run
./target/app/bin/app
you will get expected result: java.sql.SQLNonTransientConnectionException: Socket fail to connect to host:address=(host=localhost)(port=3306)(type=primary).
<?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>
reference step: (9) edit target/app/bin/app file <-- copy this file
(a) create dir dist under mariadb/src/main
(b) put app in (a)
(c) path mariadb/src/main/dist/app
mvn clean javafx:jlink com.coderplus.maven.plugins:copy-rename-maven-plugin:1.0:copy
./target/app/bin/app
You can do it in one mvn command, you can skip Steps: (1) ~ (9)
(1) app contents is modify from Gradle pluginThe Badass Runtime Plugin
。 I am reference from https://github.com/beryx-gist/badass-runtime-example-javafx (beryx-gist /
badass-runtime-example-javafx
Public)
(2) This answer is not good enough. If you already know how to perform the manual steps, you can rewrite the above content into an automated Maven configuration.
(3) final app dir
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
...