Java Projekt mit JavaFX und jfoenix ausführbar machen

Bang_Markus

Mitglied
Guten Morgen,
ich habe ein Java Projekt das ich bisher immer über Eclipse ausführe.
Da ich jetzt langsam aber sicher zum ersten Testlauf bei dem Kunden komme muss ich diese Datei ausführbar machen.
Hierfür brauch ich einen Ansatz wie man hier vorgeht.

Hab mich mal einen Tag mit Maven beschäftigt aber komme da auch nciht weiter, die JAR Datei lässt sich erstellen aber bekomme immer den Fehler
"Fehler: Hauptklasse lagerverwaltung.HMI_Main konnte nicht gefunden oder geladen werden"
Die Main Klasse liegt bei: src.lagerverwaltung.HMI_Main.java

Also kurz und knapp ich brauch Unterstützung.

Eclipse-Version: 2022-12 (4.26.0)
Verwendet: JavaFX-sdk-19.0; jfoenix-9.0.10; mysql-connector-j-8.0.32
 

KonradN

Super-Moderator
Mitarbeiter
Was hast Du denn genau gemacht? Maven zu nutzen ist aus meiner Sicht schon mit der beste Weg, denn man gibt heutzutage keine jar Dateien mehr weiter zur Ausführung. Statt dessen wird alles in einer Applikation gekapselt. Das nett sich bei Java dann Image und wird per JLink erstellt. (Und dann in der Regel noch per JPackage zu einem App-Image gemacht, so dass man eine exe hat zum starten).

Das Problem könnte bei Dir z.B,. schon sein, dass Du die Pfade des typischen Maven Projektes hast und die Sourcen aber in dem Eclipse typischen src Verzeichnis belassen hast. Dann wäre schlicht nichts übersetzt worden. Maven erwartet die Sourcen unter src/main/java und die Ressourcen unter src/main/resources.

Also der Weg, Maven zu nutzen, ist erst einmal der, zu dem ich auf jeden Fall raten würde. Alleine schon, weil da das Projekt einfach gepostet werden kann - das Helfen wird uns also stark vereinfacht. Da ggf. einfach einmal die pom.xml als Ganzes hier posten.

Bei JavaFX Projekten gibt es aus meiner Sicht zwei Möglichkeiten:
a) Getting Started von OpenJFX.io: https://openjfx.io/openjfx-docs/
Hier wird mit einem speziellen Plugin gearbeitet. Das macht alles sehr einfach und übersichtlich aber kommt an seine Grenzen, sobald eine Abhängigkeit eingebunden wird, die keine Modulbeschreibung hat.
b) Moditect Plugin - Man kann auch mit dem Moditect Plugin arbeiten. Das hat den Vorteil, dass man alten Abhängigkeiten eine Modulbeschreibung unterschieben kann. Das ist der Weg, den ich immer gehe. Da habe ich dann ein Projekt gebaut, das ich als Startpunkt nehme: https://github.com/kneitzel/JavaFXMavenApp
Das wird ggf. in Zukunft immer weniger notwendig werden, da jetzt auch die Enterprise Welt (Jakarta EE 10, Spring, ...) Module unterstützt und so z.B. die Logger Implementationen hoffentlich bald Modulbeschreibungen bekommen werden....

Aber egal, welchen Weg Du gehst: die pom.xml wäre im ersten Schritt für uns wichtig um Dir helfen zu können.


Ich selbst würde Dir natürlich den Weg b empfehlen. Da sind auch so Dinge mit drin wie statische Codeanalyse und so. Wenn Du ein Produkt weiter gibst, dann ist das ggf. auch etwas, mit dem Du Dich beschäftigen willst und so. Aber das ist natürlich Deine Entscheidung und das ist natürlich keine Magie - wenn Du sowas haben willst, dann ist es sehr einfach selbst schnell in dem Projekt integriert.
 

Bang_Markus

Mitglied
Also ich habe begonnen erstmal ein Backup zu machen sodass ich nichts an meinen Hauptprojekt kaputt mache.
Danach hab ich mich versucht mit Google und Youtube dadruch zu hangeln jedoch immer ohne Erfolg bzw. unterschiedlichen Fehlern.
U.a.:
  • kein Hauptmanifestattribut, in HMI-0.0.1-SNAPSHOT.jar
  • WARNUNG: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @6d86b085'
Bei dem 2. Fehler startet das Programm jedoch ohne icons.

Also ich wenn ich hier Tipps von Anfang an bekomme kann ich immer wieder bei mein Urcode Anfangen.

Wenn dann am Ende mal eine .exe Datei rauskommt wäre das natürlich klasse! :)
Dann werd ich mich mal mit dem Moditect Plugin beschäftigen.

Meine pom.xml sieht so aus:
Java:
<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>HMI</groupId>
  <artifactId>HMI</artifactId>
  <version>0.0.1-SNAPSHOT</version>
 
<properties>
   <maven.compiler.source>18</maven.compiler.source>
   <maven.compiler.target>18</maven.compiler.target>
 </properties>

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.jfoenix/jfoenix -->
    <dependency>
        <groupId>com.jfoenix</groupId>
        <artifactId>jfoenix</artifactId>
        <version>9.0.1</version>
    </dependency>
         <!--JavaFX-->
     <dependency>
         <groupId>org.openjfx</groupId>
         <artifactId>javafx</artifactId>
         <version>15.0.1</version>
         <type>pom</type>
     </dependency>
     <!--JavaFX-controls-->
     <dependency>
         <groupId>org.openjfx</groupId>
         <artifactId>javafx-controls</artifactId>
         <version>15.0.1</version>
     </dependency>   
</dependencies>
</project>
 

KonradN

Super-Moderator
Mitarbeiter
Ok, das ist erst einmal ein guter Anfang (Kein von Eclipse für ein bestehendes Projekt erzeugtes Maven Projekt bei dem zu viel herumkonfiguriert wurde. Maven hat einen Grundsatz; Konventionen vor Konfigurationen. Es gibt Konventionen und an die sollte man sich halten wenn möglich).

Wenn Du den Moditect Weg gehen willst, dann würde ich empfehlen: Geh einmal auf den Link oben und lade beim GitHub Projekt den Code als ZIP herunter. Dann hast Du direkt den Anfang.

/src/main/java kannst Du komplett das Verzeichnis de löschen - da war ja etwas Code von mir den Du nicht mehr brauchst. Die module-info.java behältst Du aber noch.

Dann kopierst Du von Deinem Source alles, was .java ist, in src/main/java. Alles was kein .java ist, kommt nach srd/main/resources/
(Die Ordnerstruktur bleibt aber also die Namespaces und so!)

Dann kommen die Anpassungen, die notwendig sind:

pom.xml
  • Den Bereich direkt im Kopf (Zeile 7 - 13) passt Du an. Also eine groupId auswählen, die für Dich oder Deine Firma steht. archetyp ist sozusagen der Name des Projektes. Version machst Du so, wie Du es gerne haben willst. "-SNAPSHOT" sind Versionen bei der Entwicklung die also nicht wirklich eine fixe Version sind. Beim Release will man 1.0.0 oder so haben...
  • main.class / main.module anpassen. main.module kannst Du Dir einen Namen für Dein Modul überlegen. Egal was aber musst Du Dir merken!
  • java.version - mit welcher Version arbeitest Du? Ich habe da 17 als letzte LTS Version drin.
  • Dann kommen die ganzen Versionen von den Abhängigkeiten und Plugins - die erst einmal lassen. Da muss dann nur jfoenix dazu kommen. Die letzte Version ist aber 9.0.10 und so nichts dagegen spricht, solltest Du in den Properties dies eintragen.
  • Die Dependencies bekommen dann natürlich auch einen Eintrag für jfoenix - die Version sollte abe aus den Properties kommen - Zugreifen tust Du per ${property.name} wie Du es ja auch bei den anderen Abhängigkeiten siehst.

module-info.java
  • Hier solltest Du dann den Modulnamen, den Du schon in der pom gesetzt hast, setzen (Also statt "FXAppModule").
  • Und es muss mindestens noch ein requires com.jfoenix; rein (Die Abhängigkeit hat eine Modulbeschreibung - das macht es deutlich leichter!)
  • Alle deine Namespaces willst Du exportieren - also dieses exports de.kneitzel; zeigt, wie ich den Namespace de.kneitzel exportiert hatte. Das machst Du für alle Namespaces. Wenn Du den FXMLLoader nutzt, dann musst Du mindestens das package mit dem Controller öffnen - das wäre das opens. (Alternativ kannst Du auch den Kopf anpassen zu "open module xyz {" - dann wäre alles geöffnet, das auch exportiert wird)

Das könnte es schon gewesen sein. Ggf. noch fehlende requires einbauen. Und dann kannst Du schauen, ob es schon läuft. Das Maven Ziel package sollte alles bauen. Und Du solltest dann im target Ordner die beiden Images sehen. Dazu kann ich später etwas mehr sagen.

Beim Start in der IDE kann es zu Problemen kommen, dass die JavaFX Runtime nicht gefunden wird - Schau Dir dazu einmal auf GitHub diese Klasse für den Start an: https://github.com/kneitzel/JavaFXMavenApp/blob/main/src/main/java/de/kneitzel/Main.java
Sieht erst einmal wie Quatsch aus aber ist leider ein Workaround, der notwendig sein kann.
 

Bang_Markus

Mitglied
Ich hab das ganze jetzt so abgearbeitet kam auch gut zurecht, danke dafür schonmal!
Beim Starten der HMI_Main bekomme ich jedoch einen Controller Fehler
Den Controller von Home.fxml habe ich mit .src.main.java.lagerverwaltung.LagerApp_Home_Controller angegeben

Hab erstmal nur den einen Controller angepasst die anderen mache ich wenn der erste fehlerdrei ist.


1677840843872.png
 

KonradN

Super-Moderator
Mitarbeiter
src/main/java ist der Ordner, ab dem die Java Sourcen liegen. Ab da hast Du dann die Namespaces. Der Contoller ist also lagerverwaltung.LagerApp_Home_Controller wäre der Name der Klasse, den Du in der fxml als Controller angeben müsstest.
 

Bang_Markus

Mitglied
Fehler behoben, muss bevor ich "Play" drück erst wieder Programm Rechtsklick -> Run As -> Maven build... -> bei Goals: package einschreiben dann Run -> danach konnte ich mit "Play" starten.
 

KonradN

Super-Moderator
Mitarbeiter
Also die IDE sollte auch selbst den Code immer bauen so dass das Bauen per Maven nicht immer erst manuell gemacht werden muss. So kenne ich es zumindest von IntelliJ und das sollte auch bei Eclipse nicht anders sein.
 

Bang_Markus

Mitglied
Guten Morgen,
soweit so gut.
Wenn ich jetzt die Jar Datei starten möchte (über die konsole) bekomme ich wieder den Fehler:
Fehler: Hauptklasse lagerverwaltung.HMI_Main konnte nicht gefunden oder geladen werden
Ursache: java.lang.NoClassDefFoundError: javafx/application/Application

Die Manifest Datei sieht so aus:

Manifest-Version: 1.0
Main-Class: lagerverwaltung.HMI_Main
Created-By: Maven JAR Plugin 3.2.2
Build-Jdk-Spec: 18


Das Projekt in Eclipse zu starten geht ohne Probleme.
 

KonradN

Super-Moderator
Mitarbeiter
Noch einmal ganz deutlich: Du startest nicht die jar Datei!

Das Problem bei dem Start liesse sich zwar beheben (es fehlen vermutlich einfach die Abhängigkeiten, sprich wenn Du den Classpath angibst, dann würde sich das jar File auch starten lassen), aber ab Java 9 hat man ja die erstellten Images und die wird das Maven Projekt auch entsprechend erzeugen.

Wenn Du das Maven Projekt übernommen hast, das ich da auf GitHub bereit stelle, dann solltest Du im target Ordner finden:
jlink-image -> Das enthält alles, was jlink produziert hat. Das Verzeichnis liesse sich weiter geben. Dort in bin sollte ein Script sein, dass die Applikation startet (mit dem Namen den den als ArtefactID vergeben hast - javafxapp wäre das ursprünglich bei der pom von mir).

Aber das ist ab Java 14 nicht das eigentliche, was man weitergibt. Da wurde jpackage eingeführt und das nutzt meine pom auch. Das Ergebnis findet sich in target/jpackage.
Unter Windows sollte da also eine Verzeichnisstruktur sein, die Du weiter geben kannst. Ausgeführt werden muss sie exe im bin Verzeichnis. (Bin aber auf einem Mac unterwegs - da kann ich jetzt so nicht nachsehen. Beim Mac kommt da ein .app Verzeichnis raus, das der Mac als typische App identifiziert, die so direkt gestartet werden kann mit Doppelklick.)

Diese Images enthalten auch alles, was die Applikation an Java und so braucht. Du kannst das also direkt weiter geben ohne dass auf dem Zielrechner noch irgendwas mehr installiert werden muss.
 

Bang_Markus

Mitglied
Okay gut das hatte ich vergessen.


Ich habe dein Projekt übernommen und mein Projekt eingefügt und deine Dateien so wie du geschrieben hattest, gelöscht.
Im Ordner target befindet sich kein Ordner jlink und auch kein Ordner jpackage.

So sieht mein target Ordner aus:
1678086725186.png
 

KonradN

Super-Moderator
Mitarbeiter
Dann zeig bitte einmal die pom.xml. Da scheinen dann ja nicht die Aufrufe von moditect und jpackage enthalten zu sein. Aber pmd und spotbugs sehe ich, also zumindest das scheint richtig übernommen worden zu sein.

Gab es evtl. Fehler beim Übersetzen? Evtl. mal das Log eines mvnw clean package (oder eben eines mvn clean package aus der IDE) zeigen.
 

Bang_Markus

Mitglied
Pom .xml

Java:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>Bang</groupId>
    <artifactId>WMS_HMI</artifactId>
    <version>1.0-SNAPSHOT</version>

    <organization>
        <name>Java Forum</name>
    </organization>

    <properties>
        <!-- Application Properties -->
        <link.name>${project.artifactId}</link.name>
        <launcher>${project.artifactId}</launcher>
        <appName>${project.artifactId}</appName>
        <main.class>lagerverwaltung.HMI_Main.java</main.class>
        <main.module>WMS</main.module>
        <java.version>18</java.version>
        <required.maven.version>3.6.3</required.maven.version>

        <!-- Dependency versions -->
        <junit.version>5.9.1</junit.version>
        <lombok.version>1.18.26</lombok.version>
        <javafx.version>19.0.2.1</javafx.version>
        <jetbrains.annotations.version>23.1.0</jetbrains.annotations.version>
        <lombok.version>1.18.26</lombok.version>
        <jfoenix.version>9.0.10</jfoenix.version>
        <sql.version>4.0</sql.version>

        <!-- Plugin dependencies -->
        <maven.clean.plugin>3.2.0</maven.clean.plugin>
        <maven.compiler.plugin>3.10.1</maven.compiler.plugin>
        <maven.dependency.plugin>3.3.0</maven.dependency.plugin>
        <maven.deploy.plugin>3.0.0-M2</maven.deploy.plugin>
        <maven.enforcer.plugin>3.1.0</maven.enforcer.plugin>
        <maven.install.plugin>3.0.0-M1</maven.install.plugin>
        <maven.jar.plugin>3.2.2</maven.jar.plugin>
        <maven.resources.plugin>3.2.0</maven.resources.plugin>
        <maven.site.plugin>4.0.0-M1</maven.site.plugin>
        <maven.surfire.plugin>3.0.0-M6</maven.surfire.plugin>
        <moditect.maven.plugin>1.0.0.RC2</moditect.maven.plugin>
        <jpackage.maven.plugin>0.1.3</jpackage.maven.plugin>
        <maven.pmd.version>3.16.0</maven.pmd.version>
        <pmd.version>6.52.0</pmd.version>
        <codehaus.version.plugin>2.11.0</codehaus.version.plugin>
        <spotbugs.maven.plugin>4.7.2.0</spotbugs.maven.plugin>
        <spotbugs.version>4.7.3</spotbugs.version>

        <!-- other properties -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

    </properties>

    <dependencies>
    
        <dependency>
            <groupId>com.jfoenix</groupId>
            <artifactId>jfoenix</artifactId>
            <version>${jfoenix.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-web</artifactId>
            <version>${javafx.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- Dependency used for @NotNull / @Nullable -->
        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>${jetbrains.annotations.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>${maven.enforcer.plugin}</version>
                <executions>
                    <execution>
                        <id>enforce-versions</id>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <requireMavenVersion>
                                    <version>${required.maven.version}</version>
                                </requireMavenVersion>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin}</version>
                <configuration>
                    <release>${java.version}</release>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>${maven.clean.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven.deploy.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <version>${maven.install.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven.jar.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>${maven.resources.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-site-plugin</artifactId>
                <version>${maven.site.plugin}</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven.surfire.plugin}</version>
                <configuration>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.github.spotbugs</groupId>
                <artifactId>spotbugs-maven-plugin</artifactId>
                <version>${spotbugs.maven.plugin}</version>
                <dependencies>
                    <!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
                    <dependency>
                        <groupId>com.github.spotbugs</groupId>
                        <artifactId>spotbugs</artifactId>
                        <version>${spotbugs.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <!-- spotbugs does not stop build when violations are found -->
                            <goal>spotbugs</goal>

                            <!-- check stops the build when violations are found -->
                            <!-- <goal>check</goal> -->
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <version>${maven.pmd.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-core</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-java</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-javascript</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>net.sourceforge.pmd</groupId>
                        <artifactId>pmd-jsp</artifactId>
                        <version>${pmd.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <sourceEncoding>${project.build.sourceEncoding}</sourceEncoding>
                    <minimumTokens>100</minimumTokens>
                    <targetJdk>${java.version}</targetJdk>
                    <linkXRef>false</linkXRef>
                    <rulesets>
                        <ruleset>pmd-ruleset.xml</ruleset>
                    </rulesets>
                </configuration>
                <executions>
                    <execution>
                        <phase>prepare-package</phase>
                        <goals>
                            <!-- pmd does not stop build when violations are found -->
                            <goal>pmd</goal>

                            <!-- check stops the build when violations are found -->
                            <!-- <goal>check</goal> -->
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>versions-maven-plugin</artifactId>
                <version>${codehaus.version.plugin}</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>display-dependency-updates</goal>
                            <goal>display-plugin-updates</goal>
                            <goal>display-property-updates</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

    <profiles>

        <!-- Profile that adds JLink and JPackage runs.

             Add -PImage or -DImage to use this profile.
             -->
        <profile>
            <id>Image</id>
            <activation>
                <property>
                    <name>Image</name>
                </property>
            </activation>
            <build>
                <plugins>

                    <!-- Copy dependencies -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-dependency-plugin</artifactId>
                        <version>${maven.dependency.plugin}</version>
                        <executions>
                            <execution>
                                <id>copy-dependencies</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>copy-dependencies</goal>
                                </goals>
                                <configuration>
                                    <outputDirectory>${project.build.directory}/modules</outputDirectory>
                                    <overWriteReleases>false</overWriteReleases>
                                    <overWriteSnapshots>false</overWriteSnapshots>
                                    <overWriteIfNewer>true</overWriteIfNewer>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Build image -->
                    <plugin>
                        <groupId>org.moditect</groupId>
                        <artifactId>moditect-maven-plugin</artifactId>
                        <version>${moditect.maven.plugin}</version>
                        <executions>
                            <execution>
                                <id>add-module-info-to-dependencies</id>
                                <phase>package</phase>
                                <configuration>
                                    <outputDirectory>${project.build.directory}/modules</outputDirectory>
                                    <overwriteExistingFiles>true</overwriteExistingFiles>
                                    <!-- Beispiel wie eine Dependency ohne module-info diese bekommen kann! -->
                                    <!--
                                    <modules>
                                        <module>
                                            <artifact>
                                                <groupId>org.json</groupId>
                                                <artifactId>json</artifactId>
                                            </artifact>
                                            <moduleInfo>
                                                <name>org.json</name>
                                            </moduleInfo>
                                        </module>
                                    </modules>
                                    -->

                                    <module>
                                        <mainClass>${main.class}</mainClass>
                                        <moduleInfoFile>${project.build.sourceDirectory}/module-info.java</moduleInfoFile>
                                    </module>

                                    <jdepsExtraArgs>
                                        --ignore-missing-deps
                                    </jdepsExtraArgs>
                                </configuration>
                                <goals>
                                    <goal>add-module-info</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>create-runtime-image</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>create-runtime-image</goal>
                                </goals>
                                <configuration>
                                    <modulePath>
                                        <path>${project.build.directory}/modules</path>
                                    </modulePath>
                                    <modules>
                                        <module>${main.module}</module>
                                    </modules>
                                    <launcher>
                                        <name>${launcher}</name>
                                        <module>${main.module}</module>
                                    </launcher>
                                    <compression>2</compression>
                                    <bindServices>true</bindServices>
                                    <jarInclusionPolicy>APP_WITH_DEPENDENCIES</jarInclusionPolicy>
                                    <stripDebug>true</stripDebug>
                                    <outputDirectory>${project.build.directory}/jlink-image</outputDirectory>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Build JPackage App-Image -->
                    <plugin>
                        <groupId>com.github.akman</groupId>
                        <artifactId>jpackage-maven-plugin</artifactId>
                        <version>${jpackage.maven.plugin}</version>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>jpackage</goal>
                                </goals>
                                <configuration>
                                    <name>${appName}</name>
                                    <type>IMAGE</type>
                                    <runtimeimage>${project.build.directory}/jlink-image</runtimeimage>
                                    <module>${main.module}/${main.class}</module>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

    </profiles>

</project>


Maven Clean Log

Code:
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< Bang:WMS_HMI >----------------------------
[INFO] Building WMS_HMI 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] Downloading from : https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.2.0/maven-clean-plugin-3.2.0.jar
[INFO] Downloaded from : https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.2.0/maven-clean-plugin-3.2.0.jar (36 kB at 86 kB/s)
[INFO]
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ WMS_HMI ---
[INFO] Downloading from : https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
[INFO] Downloaded from : https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar (169 kB at 2.7 MB/s)
[INFO] Deleting C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.222 s
[INFO] Finished at: 2023-03-06T08:34:27+01:00
[INFO] ------------------------------------------------------------------------
 

KonradN

Super-Moderator
Mitarbeiter
Ok, das erklärt es. Du hast die pom aus meinem JavaMavenProjekt genutzt - also die nicht JavaFX spezifische Variante. Die sollte aber prinzipiell auch gehen - bis auf den GraalVM Bereich. Den habe ich bei JavaFX bisher nicht zum laufen bekommen, da es da Problmee mit dem Reflection gibt.

Der Unterschied, der für Dich relevant ist, ist einfach, dass ich nicht mehr bei jedem package diese Images bauen lassen. Diese werden jetzt nur bei dem Profil Image mit aufgerufen.

Das Profil kann entweder mit -PImage oder über -DImage (dann wird eine Property Image gesetzt - diese aktiviert das Profil auch) ausgewählt werden.

Der Aufruf, der daher hier notwendig ist, ist ein mvnw -PImage package

Nur kurz zu den GitHub Repositories:
Unter https://github.com/kneitzel/JavaMavenApp have ich ein pures Java Projekt, mit dem ich verschiedene Dinge als Rahmen vorbereitet habe. Da geht es also zum einen über das Einbinden von diversen Dingen wie die Prüfung der Versionen oder eben die statische Codeanalyse.
Aber auch so Aufrufe wie JLink / JPackage oder eben native-Image von GraalVM habe ich da versucht, einzubinden.
Unter https://github.com/kneitzel/JavaFXMavenApp ist das dann auf JavaFX spezialisiert. Paar Dinge gehen da leider nicht direkt - z.B. bei GraalVM. Daher die Auftrennung in zwei Repositories.
 

Bang_Markus

Mitglied
Also wenn ich jetzt
Code:
mvn -PImage package
ausführe im Terminal bekomme ich folgendes Feedback



Code:
[INFO] --- maven-jar-plugin:3.2.2:jar (default-jar) @ WMS_HMI ---
[INFO] Building jar: C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target\WMS_HMI-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  53.841 s
[INFO] Finished at: 2023-03-06T09:52:43+01:00
[INFO] ------------------------------------------------------------------------
[WARNING] The requested profile "image" could not be activated because it does not exist.
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
[ERROR] The goal you specified requires a project to execute but there is no POM in this directory (C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\src\main\java\lagerverwaltung). Plea se verify you invoked Maven from the correct directory. -> [Help 1]
Du scheinst nur im falschen Verzeichnis zu sein. Es sieht so aus, als wäre dein Projekt in C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main abgelegt, aber Du bist in einem unterverzeichnis src/main/java/lagerverwaltung

Hätte nicht gedacht, als wir angefangen haben zu entwickeln das es so komplex ist es zu exportieren.
Ja, es kommen da eigentlich recht viele Dinge zusammen. Aber ich denke, dass Du sehr dicht dran bist und es in Kürze soweit haben wirst. Und wenn man es einmal aufgesetzt hat, dann solltest Du in der Lage sein, einfach weiter zu entwickeln ohne Dich noch sehr viel mehr um das Projekt selbst kümmern zu müssen.

Es gibt dann zwar paar Dinge, die man beachten kann, aber die können wir gerne im Anschluss ansprechen, wenn Du den Build erst einmal hinbekommen hast. Das sind dann aber dann Punkte, die man nach und nach angehen kann (bzw. sollte). Aber dazu kommen wir - so Du es wünscht - nachdem wir den Build hinbekommen haben.

Evtl. kann es auch von Interesse sein, sich noch etwas mehr mit der Entwicklungsumgebung vertraut zu machen. Ich bin aber kein Eclipse User (ich kenne es zwar und nutze es hin und wieder, aber ich bin garantiert nicht die Person, die hier Best Practices vermitteln kann. Ich mag zwar Vorgehen haben, aber die müssen nicht gut sein und bezüglich "bestes Vorgehen" würde ich nichts sagen können.) aber evtl. ist es für Die Interessant, z.B. IntelliJ auszuprobieren. Das ist die Entwicklungsumgebung meiner Wahl und die empfehle ich in der Regel auch immer. (Aber das ist natürlich keine Aussage zur Wertigkeit. Eclipse Bashing wird hier im Forum manchmal betrieben, aber das ist wirklich als Spass zu sehen. So lange Du eine vernünftige IDE nutzt bist Du auf jeden Fall nicht falsch. Und die IDEs für Java sind dann vor allem Eclipse / Netbeans / IntelliJ als die großen drei Platzhirsche. Aber IDEs wie Visual Studio Code und Co sind auch ok.)

Also was ich sagen / anbieten möchte: Bezüglich IntelliJ könnte ich das Handling von Maven recht detailliert zeigen - bezüglich Eclipse würde ich das eher anderen überlassen.
 

Bang_Markus

Mitglied
Hab das jetzt im richtigen Pfad ausgeführt und auch mein Beitrag nochmal bearbeitet denke da kam es zu einer Überschneidung von deinen und meinen Beitrag.


Würde es Sinn machen von Eclipse zu InteliJ zu wechseln (nur für den Export)?

Noch als Hinweis mein Projekt ist nur die Grafische Oberfläche das Backend macht mein Kollege, wir mussten das aufgrund von mehreren Problemen bezgl. kommunikation mit einer SPS trennen.

Am Ende steht:
Java:
[INFO]
[INFO] --- maven-jar-plugin:3.2.2:jar (default-jar) @ WMS_HMI ---
[INFO] Building jar: C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target\WMS_HMI-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  53.841 s
[INFO] Finished at: 2023-03-06T09:52:43+01:00
[INFO] ------------------------------------------------------------------------
[WARNING] The requested profile "image" could not be activated because it does not exist.
 

KonradN

Super-Moderator
Mitarbeiter
Du hast einen Tippfehler: Das Profil heisst Image und nicht image (Also Gross-/Kleinschreibung).

Aber evtl. willst Du das, was in diesem Image Profil unter <build><plugins> steht kopieren (also diese <plugin>...</plugin> Einträge) und diese in das <build><plugins> des Projektes kopieren. Dann brauchst Du kein Profil mehr angeben.

Würde es Sinn machen von Eclipse zu InteliJ zu wechseln (nur für den Export)?
Nein, nur für den Export macht es keinen Sinn. Da reicht ja ein Aufruf auf der Kommandozeile. Da würde ich wirklich auf eine IDE bleiben. Wenn die Entwicklung weiter unter Eclipse laufen soll, dann wäre das nur eine Konfiguration, die ich da vornehmen würde.

Also wenn ich das bei Eclipse richtig sehe, dann ist das eine Run COnfiguration und die könnte dann z.B. so aussehen:
Bildschirm­foto 2023-03-06 um 10.25.48.png

Also goals sind clean und package (Nur package kann auf Probleme laufen, weil er dann versucht Images zu erzeugen und die, die schon vorhanden sind, sorgen dann für einen Fehler ... das habe ich aber noch nicht ganz nachvollziehen können.)
Und bei Profiles kommt dann das Images rein (so Du es nicht verschiebst und nicht mehr mit dem Profil arbeiten willst).

Das wäre dann eine Run Configuration, die man nutzen kann. Im Reiter Common hat man dann auch die Möglichkeit, dass dies angezeigt wird im Kontextmenü von Run oder so ...
 

Bang_Markus

Mitglied
Ahh der klassische Rechtschreibfehler...

Hab das mit "clean package" mal probiert aber dann kann er die Datei "spotbugXml.xml" nicht löschen. Sobald ich Eclipse schließe kann ich diese Datei händisch löschen.

Java:
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< Bang:WMS_HMI >----------------------------
[INFO] Building WMS_HMI 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ WMS_HMI ---
[INFO] Deleting C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.728 s
[INFO] Finished at: 2023-03-06T11:05:42+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:3.2.0:clean (default-clean) on project WMS_HMI: Failed to clean project: Failed to delete C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target\spotbugsXml.xml -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException


Wenn ich den Inhalt des targets Ordner händisch lösche und dann "clean package" ausführe kommt:
Die Fehlenden Module rufe ich in der module-info.java auf mit:
requires mysql.connector.j;
requires javafx.fxml;
requires sqljdbc4;

Als Libary sind sie ebenfalls hinterlegt

Code:
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------------< Bang:WMS_HMI >----------------------------
[INFO] Building WMS_HMI 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ WMS_HMI ---
[INFO] Deleting C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target
[INFO]
[INFO] --- maven-enforcer-plugin:3.1.0:enforce (enforce-versions) @ WMS_HMI ---
[INFO]
[INFO] --- versions-maven-plugin:2.11.0:display-dependency-updates (default) @ WMS_HMI ---
[INFO] The following dependencies in Dependencies have newer versions:
[INFO]   org.jetbrains:annotations ........................... 23.1.0 -> 24.0.1
[INFO]   org.junit.jupiter:junit-jupiter-engine ................ 5.9.1 -> 5.9.2
[INFO]   org.openjfx:javafx-controls ...................... 19.0.2.1 -> 21-ea+5
[INFO]   org.openjfx:javafx-graphics ...................... 19.0.2.1 -> 21-ea+5
[INFO]   org.openjfx:javafx-web ........................... 19.0.2.1 -> 21-ea+5
[INFO]
[INFO] The following dependencies in Plugin Dependencies have newer versions:
[INFO]   net.sourceforge.pmd:pmd-core ........................ 6.52.0 -> 6.55.0
[INFO]   net.sourceforge.pmd:pmd-java ........................ 6.52.0 -> 6.55.0
[INFO]   net.sourceforge.pmd:pmd-javascript .................. 6.52.0 -> 6.55.0
[INFO]   net.sourceforge.pmd:pmd-jsp ......................... 6.52.0 -> 6.55.0
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.11.0:display-plugin-updates (default) @ WMS_HMI ---
[INFO]
[INFO] The following plugin updates are available:
[INFO]   com.github.spotbugs:spotbugs-maven-plugin ...... 4.7.2.0 -> 4.7.3.2
[INFO]   maven-compiler-plugin ............................ 3.10.1 -> 3.11.0
[INFO]   maven-dependency-plugin ............................ 3.3.0 -> 3.5.0
[INFO]   maven-deploy-plugin ............................. 3.0.0-M2 -> 3.1.0
[INFO]   maven-enforcer-plugin .............................. 3.1.0 -> 3.2.1
[INFO]   maven-install-plugin ............................ 3.0.0-M1 -> 3.1.0
[INFO]   maven-jar-plugin ................................... 3.2.2 -> 3.3.0
[INFO]   maven-pmd-plugin ................................. 3.16.0 -> 3.20.0
[INFO]   maven-resources-plugin ............................. 3.2.0 -> 3.3.0
[INFO]   maven-site-plugin ............................ 4.0.0-M1 -> 4.0.0-M5
[INFO]   maven-surefire-plugin ........................ 3.0.0-M6 -> 3.0.0-M9
[INFO]   org.codehaus.mojo:versions-maven-plugin .......... 2.11.0 -> 2.15.0
[INFO]
[INFO] All plugins have a version specified.
[INFO]
[INFO] Project requires minimum Maven version for build of: 3.6.3
[INFO] Plugins require minimum Maven version of: 3.6.3
[INFO]
[INFO] No plugins require a newer version of Maven than specified by the pom.
[INFO]
[INFO] Require Maven 3.8.6 to use the following plugin updates:
[INFO]   com.github.akman:jpackage-maven-plugin ............. 0.1.3 -> 0.1.5
[INFO]
[INFO]
[INFO] --- versions-maven-plugin:2.11.0:display-property-updates (default) @ WMS_HMI ---
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO] Major version changes allowed
[INFO]
[INFO] The following version properties are referencing the newest available version:
[INFO]   ${jfoenix.version} ........................................... 9.0.10
[INFO]   ${lombok.version} ........................................... 1.18.26
[INFO]   ${maven.clean.plugin} ......................................... 3.2.0
[INFO]   ${moditect.maven.plugin} .................................. 1.0.0.RC2
[INFO]   ${spotbugs.version} ........................................... 4.7.3
[INFO] The following version property updates are available:
[INFO]   ${codehaus.version.plugin} ......................... 2.11.0 -> 2.15.0
[INFO]   ${javafx.version} ............................... 19.0.2.1 -> 21-ea+5
[INFO]   ${jetbrains.annotations.version} ................... 23.1.0 -> 24.0.1
[INFO]   ${jpackage.maven.plugin} ............................. 0.1.3 -> 0.1.5
[INFO]   ${junit.version} ..................................... 5.9.1 -> 5.9.2
[INFO]   ${maven.compiler.plugin} ........................... 3.10.1 -> 3.11.0
[INFO]   ${maven.dependency.plugin} ........................... 3.3.0 -> 3.5.0
[INFO]   ${maven.deploy.plugin} ............................ 3.0.0-M2 -> 3.1.0
[INFO]   ${maven.enforcer.plugin} ............................. 3.1.0 -> 3.2.1
[INFO]   ${maven.install.plugin} ........................... 3.0.0-M1 -> 3.1.0
[INFO]   ${maven.jar.plugin} .................................. 3.2.2 -> 3.3.0
[INFO]   ${maven.pmd.version} ............................... 3.16.0 -> 3.20.0
[INFO]   ${maven.resources.plugin} ............................ 3.2.0 -> 3.3.0
[INFO]   ${maven.site.plugin} ........................... 4.0.0-M1 -> 4.0.0-M5
[INFO]   ${maven.surfire.plugin} ........................ 3.0.0-M6 -> 3.0.0-M9
[INFO]   ${pmd.version} ..................................... 6.52.0 -> 6.55.0
[INFO]   ${spotbugs.maven.plugin} ......................... 4.7.2.0 -> 4.7.3.2
[INFO]
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ WMS_HMI ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 140 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ WMS_HMI ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 25 source files to C:\Users\dgerstner\Documents\Java_Entwicklung\JavaFXMavenApp-main\target\classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[7,29] module not found: mysql.connector.j
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[9,20] module not found: javafx.fxml
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[10,14] module not found: sqljdbc4
[INFO] 3 errors
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.960 s
[INFO] Finished at: 2023-03-06T11:12:47+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project WMS_HMI: Compilation failure: Compilation failure:
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[7,29] module not found: mysql.connector.j
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[9,20] module not found: javafx.fxml
[ERROR] /C:/Users/dgerstner/Documents/Java_Entwicklung/JavaFXMavenApp-main/src/main/java/module-info.java:[10,14] module not found: sqljdbc4
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
 

KonradN

Super-Moderator
Mitarbeiter
In der geposteten Maven Projektdatei (pom.xml) war die Abhängigkeit zu mysql nicht vorhanden. javafx-fxml sehe ich auch nicht in der pom. Ebenso die letzte Bibliothek.

Wichtig ist: Du darfst die nicht in Eclipse hinzu fügen. Das muss alles in der pom.xml erfolgen. Also das wäre dann z.B.:

XML:
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.32</version>
</dependency>
für mysql Connector (Wobei ich da nicht sicher bin, dass da eine modul-info dabei ist. das muss ich selbst noch testen)

XML:
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx.version}</version>
        </dependency>
für javafx-fxml

Und ggf. das für den SQL Server Treiber:
Code:
<!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/sqljdbc4 -->
<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>sqljdbc4</artifactId>
    <version>4.0</version>
</dependency>

Die Versionen würde ich noch so - wie bei den anderen Abhängigkeiten auch - in die properties ziehen ...
 

KonradN

Super-Moderator
Mitarbeiter
Als kurze Info mit dem Smartphone: ich habe eine lange Antwort auf dem Rechner aber Router hat gerade Störung.

A) die mssql jdbc Angabe ist alt …
B) so Runtime Komponenten bringen leider immer noch oft keine Module-Info mit - das habe ich für Dich generiert.
C) falls Dich das zu sehr abschrecken sollte, wird es eine kleine Alternative geben … Ich lehne diese zwar ab, aber wenn das Modulsystem zu sehr zuschlägt, dann mag man es gerade am Anfang evtl. nicht haben …
 

KonradN

Super-Moderator
Mitarbeiter
Also mehrere Punkte (da ich jetzt die Zeit hatte, mir das einmal anzusehen):
1. Abhängigkeit zu mssql jdbc Treiber - da hast Du etwas sehr Altes!
2. Grüße vom Java Modulsystem
3. Ohne Modulsystem etwas bauen

1. Abhängigkeit zu mssql jdbc Treiber - da hast Du etwas sehr Altes!

Sorry, hatte bei dem SQL JDBC Treiber nicht richtig geschaut. Aber sicher, dass ihr die 4er Version nutzt / nutzen wollt? Die ist ja asbach (und auch nicht auf central).

Ist da nicht mssql-jdbc das, was ihr wollt:

Das dürfte dann dem entsprechen, das man auch unter https://learn.microsoft.com/de-de/s...c-driver-for-sql-server?view=sql-server-ver16 findet denke ich mal.

Das wäre dann eine Abhängigkeit wie:

XML:
<!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc -->
<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>12.2.0.jre11</version>
</dependency>

2. Grüße vom Java Modulsystem

Das Java Modulsystem erwartet (beim jlink), dass alle Abhängigkeiten auch wirklich Modulbeschreibungen haben. Das ist leider bei Dingen, die in der Regel erst zur Laufzeit dazu kommen, schlicht nicht der Fall (Aus meiner Sicht dadurch bedingt, dass es vor allem im Java Backend eingesetzt wird und da wurde das Modulsystem lange nicht unterstützt. Mit Jakarta EE 10 / Spring 6 / ... ändert sich das jetzt hoffentlich).

Egal wie dem auch sei: Um da mit JLink arbeiten zu können, müssen wir nun eine modul-info.java bereit stellen für diese Abhängigkeiten. Diese automatisch durch moditect generieren zu lassen wird problematisch, sobald man da über mehrere Pdafe zu gleichen Modulen kommt. Das war jetzt hier der Fall. Daher muss man für jede Abhängikeit das manuell machen. Das ist dann auf der jar Datei (z.B. von mvnrepository.com herunter geladen) ein einfacher Aufruf wie
jdeps --generate-module-info . --ignore-missing-deps ../mysql-connector-j-8.0.32.jar

Das erzeugt einem dann eine module-info.jar, die man dann mit bereit stellen kann im moditect plugin.

Dann ist die jar von microsoft signiert (eigentlich gut) aber das mag JLink nicht. Es wird halt was zusammen gebaut und das wird dann nicht mehr wirklich geprüft (Mein sehr oberflächiges Verständnis). Daher braucht JLink ein Argument zum ignorieren von signing Informationen. Das muss also auch noch hinzugefügt werden.

Damit kommen wir zu einem pom.xml, welches die Abhängigkeiten oben als dependencies hat:
XML:
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.0.32</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>12.2.0.jre11</version>
        </dependency>

Und dann beim Moditect Plugin:
XML:
                    <!-- Build image -->
                    <plugin>
                        <groupId>org.moditect</groupId>
                        <artifactId>moditect-maven-plugin</artifactId>
                        <version>${moditect.maven.plugin}</version>
                        <executions>
                            <execution>
                                <id>add-module-info-to-dependencies</id>
                                <phase>package</phase>
                                <configuration>
                                    <outputDirectory>${project.build.directory}/modules</outputDirectory>
                                    <overwriteExistingFiles>true</overwriteExistingFiles>

                                    <modules>

                                        <module>
                                            <artifact>
                                                <groupId>com.mysql</groupId>
                                                <artifactId>mysql-connector-j</artifactId>
                                            </artifact>
                                            <moduleInfoSource>
                                                module mysql.connector.j {
                                                requires java.management;

                                                requires transitive java.logging;
                                                requires transitive java.naming;
                                                requires transitive java.security.sasl;
                                                requires transitive java.sql;
                                                requires transitive java.transaction.xa;
                                                requires transitive java.xml;

                                                exports com.mysql.cj;
                                                exports com.mysql.cj.admin;
                                                exports com.mysql.cj.callback;
                                                exports com.mysql.cj.conf;
                                                exports com.mysql.cj.conf.url;
                                                exports com.mysql.cj.exceptions;
                                                exports com.mysql.cj.interceptors;
                                                exports com.mysql.cj.jdbc;
                                                exports com.mysql.cj.jdbc.admin;
                                                exports com.mysql.cj.jdbc.exceptions;
                                                exports com.mysql.cj.jdbc.ha;
                                                exports com.mysql.cj.jdbc.integration.c3p0;
                                                exports com.mysql.cj.jdbc.interceptors;
                                                exports com.mysql.cj.jdbc.jmx;
                                                exports com.mysql.cj.jdbc.result;
                                                exports com.mysql.cj.jdbc.util;
                                                exports com.mysql.cj.log;
                                                exports com.mysql.cj.protocol;
                                                exports com.mysql.cj.protocol.a;
                                                exports com.mysql.cj.protocol.a.authentication;
                                                exports com.mysql.cj.protocol.a.result;
                                                exports com.mysql.cj.protocol.result;
                                                exports com.mysql.cj.protocol.x;
                                                exports com.mysql.cj.result;
                                                exports com.mysql.cj.sasl;
                                                exports com.mysql.cj.util;
                                                exports com.mysql.cj.x.protobuf;
                                                exports com.mysql.cj.xdevapi;
                                                exports com.mysql.jdbc;

                                                provides java.sql.Driver with
                                                com.mysql.cj.jdbc.Driver;
                                                }
                                            </moduleInfoSource>
                                        </module>

                                        <module>
                                            <artifact>
                                                <groupId>com.microsoft.sqlserver</groupId>
                                                <artifactId>mssql-jdbc</artifactId>
                                            </artifact>
                                            <moduleInfoSource>
                                                module com.microsoft.sqlserver.jdbc {
                                                requires java.management;
                                                requires java.xml;

                                                requires transitive java.logging;
                                                requires transitive java.naming;
                                                requires transitive java.security.jgss;
                                                requires transitive java.sql;
                                                requires transitive java.transaction.xa;

                                                exports com.microsoft.sqlserver.jdbc;
                                                exports com.microsoft.sqlserver.jdbc.dataclassification;
                                                exports com.microsoft.sqlserver.jdbc.dns;
                                                exports com.microsoft.sqlserver.jdbc.osgi;
                                                exports com.microsoft.sqlserver.jdbc.spatialdatatypes;
                                                exports microsoft.sql;
                                                exports mssql.googlecode.cityhash;
                                                exports mssql.googlecode.concurrentlinkedhashmap;
                                                exports mssql.security.provider;

                                                provides java.sql.Driver with
                                                com.microsoft.sqlserver.jdbc.SQLServerDriver;

                                                }
                                            </moduleInfoSource>
                                        </module>
                                    </modules>

                                    <module>
                                        <mainClass>${main.class}</mainClass>
                                        <moduleInfoFile>${project.build.sourceDirectory}/module-info.java</moduleInfoFile>
                                    </module>

                                    <jdepsExtraArgs>
                                        --ignore-missing-deps
                                    </jdepsExtraArgs>
                                </configuration>
                                <goals>
                                    <goal>add-module-info</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>create-runtime-image</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>create-runtime-image</goal>
                                </goals>
                                <configuration>
                                    <modulePath>
                                        <path>${project.build.directory}/modules</path>
                                    </modulePath>
                                    <modules>
                                        <module>${main.module}</module>
                                    </modules>
                                    <launcher>
                                        <name>${launcher}</name>
                                        <module>${main.module}</module>
                                    </launcher>
                                    <compression>2</compression>
                                    <stripDebug>true</stripDebug>
                                    <outputDirectory>${project.build.directory}/jlink-image</outputDirectory>
                                    <jarInclusionPolicy>APP_WITH_DEPENDENCIES</jarInclusionPolicy>
                                    <ignoreSigningInformation>true</ignoreSigningInformation>
                                </configuration>
                            </execution>
    </executions>
</plugin>

Ich habe es mal komplett kopiert. Wichtig ist der Bereich, der die module-infos erzeugt (an der Stelle hast Du nur einen Kommentar) und bei derm create-runtime-image das ignoreSigningInformation.

Damit ließen sich bei mir die Images bauen.

Das wäre der Java Weg für eine Ausführung von Programmen per Images, die über JLink / JPackage erstellt wurden.

3. Ohne Modulsystem etwas bauen

Bei der Komplexität oben wird man sich ggf. Gedanken machen, ob man diese Komplexität haben will oder ob man darauf verzichten möchte. Was für Alternativen würde es geben?

  • Man kann natürlich ein jar File erzeugen, so wie es eh shcon erzeugt wird von Maven im target Ordner.
  • Man kann alle Abhängigkeiten von Maven bekommen: mvn dependency:copy-dependencies kopiert alle Abhängigkeiten zu trget/dependency
  • Dann kann man das eigentliche jar File, die Abhängigkeiten sowie ein JRE zusammen packen und ein Startscript mitgeben. Es wird also ein classpath gesetzt und dann java aufgerufen. Und dann kann man auch die üblichen Tools aus Java8 Zeiten nutzen wenn man möchte. Ich habe früher mit jar2exe genutzt, das zwar ein kleines bisschen Geld gekostet hat aber recht gut funktionierte (aber nicht mit aktuellen Java Versionen getestet!) Und da gibt es launch4j und so.

Wichtiger Workaround: JavaFX ist etwas eigen, was den Classloader angeht. Wenn die main Methode in der Klasse ist, die von Application erbt, dann meint er, dass JavaFX Komponenten fehlen. Da ist der Workaround, einfach eine Klasse mit main Methode zu haben, die dann die eigentliche Mainmethode aufruft.

Das möchte ich einfach an dieser Stelle erwähnen. Das geht prinzipiell dann auch ohne Maven (so ihr z.B. diese alte sqljdbc4 nutzen müsst, die nicht in central liegt und so). Das geht auch mit Eclipse under dem exportieren zu einem JAR File.

Aber ich würde diesen Weg nicht bestreiten. Mir graut es, wenn ich es nur lese und wenn jemand anderes es geschrieben hätte, hätte ich es kommentiert! Aber evtl. ist das ein Weg, mit dem Du besser klar kommen würdest, denn dieses Erstellen von module-info und das Unterschieben ist schlicht blöd. Gerade am Anfang. Und das kann so wie ich es gepostet habe auch noch nicht funktionieren. Ggf. fehlen noch paar Angaben in der module-info, die ich bereit gestellt habe. Das sagt er einem beim ausführen von Code - und ich führe da keinen Code aus sondern habe nur die module eingebunden.
(Die eigene module-info würde ich aber nutzt, damit ein benanntes Modul da ist und man packages öffnen kann. Wenn man z.B. mit fxml Dateien arbeitet und der FXMLLoader die Controller erzeugen soll, dann müssen die Packages, die die Controller enthalten, geöffnet worden sein (Also in module-info.java ein "open module xyz" oder neben den "exports namespace" auch "opens namespace" Einträge).
 

Bang_Markus

Mitglied
Also ich hab das jetzt mal versucht bei mir reinzunehmen aber so richtig komme ich da nicht weiter.
Ich denke das ich da jetzt noch zu viel Zeit investieren muss das es eine .exe oder ähnliches wird.
Da verfolge ich (erstmal) den Weg weiter eine ausführbare .jar zu bekommen, wo ich nach meinen Gefühl auch schon auf den richitg Weg bin.
Hier hab ich nur noch einen Fehler beim ausführen:

Fehler: Hauptklasse lagerverwaltung.HMI_Main konnte nicht gefunden oder geladen werden
Ursache: java.lang.NoClassDefFoundError: javafx/application/Application
 

KonradN

Super-Moderator
Mitarbeiter
Also Ausführbare Jar würde ich nicht machen, da du dann voraus setzt, dass eine passende Java Version installiert ist. Wenn Du über ein Jar gehst, dann würde ich es dennoch mit einem openjdk und Startscripten ausliefern. Aber zu Deiem Problem:

a) Sicher, dass die Abhängigkeiten da sind?
b) Den Punkt mit der Separaten Startklasse hast Du gesehen und gemacht?
Wichtiger Workaround: JavaFX ist etwas eigen, was den Classloader angeht. Wenn die main Methode in der Klasse ist, die von Application erbt, dann meint er, dass JavaFX Komponenten fehlen. Da ist der Workaround, einfach eine Klasse mit main Methode zu haben, die dann die eigentliche Mainmethode aufruft.
 

mihe7

Top Contributor
Bei der Komplexität oben wird man sich ggf. Gedanken machen, ob man diese Komplexität haben will oder ob man darauf verzichten möchte. Was für Alternativen würde es geben?
Kleine Anmerkung, weil ich zur Zeit doch tatsächlich auch mal das Vergügen habe, ein JavaFX-Projekt erstellen und ausliefern zu müssen: genau das, was Du beschreibst, mache ich momentan auch.

Sprich: per jlink ein Image erstellt (enthält neben java.base dann auch die JavaFX-Module sowie java.sql), die App als Classpath-Anwendung und dann per Startskript die Anwendung samt jdbc-Treiber aufgerufen.

Das gefällt mir so aber überhaupt nicht.

Aber: wenn ich das richtig sehe, könnte man das ggf. mit jpackage automatisieren (--add-module sowie --java-options bzw. --main-jar sehen da vielversprechend aus, ggf. noch mit --input, um die Treiber zu kopieren). Das muss ich aber erst mal ausprobieren, wenn ich Zeit habe.
 

KonradN

Super-Moderator
Mitarbeiter
Ich wollte Dich auch gerade mit rein ziehen um auch mal nach Deiner Sicht zu fragen. Dieses Unterschieben der module-info ist halt doch nicht ganz so toll. (Bei log4j hatte ich da ja auch noch mehrere Dinge an den module-infos anpassen müssen - die Fehlermeldungen sagen einem zwar meist, was fehlt, aber dennoch ...)

Das war Du da beschreibst mit dem jlink macht ja z.B. das moditect Plugin bei der POM. Das Moditect Plugin ist notwendig, sobald man Abhängigkeiten ohne Modulbeschreibung hat. Das ist bei allen Runtime Komponenten, die ich so gesehen habe, der Fall. (Wenn Du das nicht hast, dann reicht Dir das javafx Plugin! javafx:jlink und schon hast Du das Image! Aber sobald Du das hast, dann gibt es da wohl keine Lösung!)

Den Aufruf von JPackage habe ich dann auch in der POM. Die kannst Du auch einfach übernehmen:
XML:
                    <!-- Build JPackage App-Image -->
                    <plugin>
                        <groupId>com.github.akman</groupId>
                        <artifactId>jpackage-maven-plugin</artifactId>
                        <version>${jpackage.maven.plugin}</version>
                        <executions>
                            <execution>
                                <phase>package</phase>
                                <goals>
                                    <goal>jpackage</goal>
                                </goals>
                                <configuration>
                                    <name>${appName}</name>
                                    <type>IMAGE</type>
                                    <runtimeimage>${project.build.directory}/jlink-image</runtimeimage>
                                    <module>${main.module}/${main.class}</module>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

Du musst halt anpassen, wo das runtime Image liegt - das ist bei mir im target in jlink-image.

Aber was mich interessieren würde, wäre Deine Sicht auf dieses unterschieben der module-info: Wie sinnig ist das?
Es wäre verpflichtend für das JLink, aber die sinnhaftigkeit bezweifle ich. Zumal das dann auch immer ein "--ignore-missing-deps" bei dem jdeps Aufruf braucht und so (Sonst wäre es noch krasser von den Aufwänden her).

Da kann es dann doch tatsächlich besser sein, das einfach anderweitig zu kapseln, sprich: wieso nicht einfach ein java kopieren, Abhängigkeiten und erzeugte Lib kopieren. Aufruf per Script.
Oder wenn das nicht gut genug erscheint: Dann kapselt man den Aufruf in eine exe unter Windows. So ein kleiner Starter ist ja schnell und einfach gebaut (Kleines C++ Programm das da einen Aufruf macht, der aus einem Config-File gelesen wird. Hört sich erst mal nicht kompliziert an). Oder man nimmt etwas, das es schon gibt wie launch4j oder so.

Die Idee ist halt, dass man auf die Module verzichtet um dann das so zu verwirklichen.

Das kann man dann ggf. auch über ein Maven Plugin automatisieren. Das Binary würde man ebenso wie eine Liste mit JDKs zum Download bereit stellen. Dann kann das Plugin die Binaries herunter laden, config File erstellen, Dependencies und jar kopieren und dann das passende JDK herunter laden und entpacken. Hört sich sowas sinnvoll an? Oder habe ich mich da mit den Gedanken verrant?
 

KonradN

Super-Moderator
Mitarbeiter
Da verfolge ich (erstmal) den Weg weiter eine ausführbare .jar zu bekommen
Da evtl. noch ein wichtiger Hinweis: So eine jar mit Abhängigkeiten wäre nicht plattform unabhängig!

Die Abhängigkeiten, die geladen werden, enthalten bei JavaFX auch dll (bzw so bei Linux und .dylib bei macOS) Dateien. (javafx-graphics)

Daher hast Du mehrere jar Dateien. Die javafx-xxx-<version>.jar ist fast ganz leer und der eigentliche Inhalt ist in javafx-xxx-<version>-<system>.jar
Sprich: Du brauchst unter Windows die javafx-graphics-19-win.jar und die geht nur unter Windows.

Das nur als kleiner zusätzlicher Hinweis - nicht dass du da irgend eine falsche Vorstellung hast.
 

Bang_Markus

Mitglied
Das mit dem mssql jdbc hab ich in den Griff bekommen, da kommt auch kein Fehler mehr.

Den Befehl für die Modul Info hab ich auch ausgeführt

Java:
 jdeps --generate-module-info . --ignore-missing-deps ../mysql-connector-j-8.0.32.jar
Warning: --ignore-missing-deps specified. Missing dependencies from mysql.connector.j are ignored
writing to .\mysql.connector.j\module-info.java

Die Pom hab ich ebenfalls angepasst mit dem <ignoreSigningInformation>
Ich verzweifel langsam :D
Leider hab ich immernoch den Fehler:

Code:
[INFO] --- moditect-maven-plugin:1.0.0.RC2:add-module-info (add-module-infos) @ WMS_HMI ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.733 s
[INFO] Finished at: 2023-03-07T10:39:43+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.moditect:moditect-maven-plugin:1.0.0.RC2:add-module-info (add-module-infos) on project WMS_HMI: Unable to parse configuration of mojo org.moditect:moditect-maven-plugin:1.0.0.RC2:add-module-info for parameter module: Cannot find default setter in class org.moditect.mavenplugin.add.model.ModuleConfiguration -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginConfigurationException
 

KonradN

Super-Moderator
Mitarbeiter
Ich verzweifel langsam :D
Also das ist aus meiner Sicht normal. Das mit den Java Modulen ist einfach ein Murks. Nicht, weil Oracle das schlecht gemacht hat sondern einfach, weil es zu viele gibt, die auch nach Jahren (Wann ist Java 9 raus gekommen?) das schlicht ignorieren. Die ganze "Enterprise Welt" aus Jakarta EE, Spring Framework, ... haben das ignoriert - erst die letzten Versionen (Jakarta EE 10, Spring 6, ...) unterstützen auch das Java Modulsystem.

Unable to parse configuration of mojo org.moditect:moditect-maven-plugin:1.0.0.RC2:add-module-info for parameter module: Cannot find default setter in class org.moditect.mavenplugin.add.model.ModuleConfiguration
Das sieht mir danach aus, dass da beim Einbau der Ergebnisse in die Konfiguration irgend etwas falsch gelaufen ist. Zeige einfach einmal den plugin Eintrag vom moditect Plugin.
 

mihe7

Top Contributor
Wenn Du das nicht hast, dann reicht Dir das javafx Plugin! javafx:jlink und schon hast Du das Image! Aber sobald Du das hast, dann gibt es da wohl keine Lösung!
Richtig, zunächst hat die Anwendung gar nichts geschrieben, dann in ein File und - es kam, wie es kommen musste - jetzt soll dann doch eine DB ran. Zuvor war das easy: javafx:jlink -> Thema erledigt. Doch mit dem SQL-Treiber war der Spaß dann vorbei.

Ich dachte, Moditect schiebt nur eine module-info unter. Das mache ich ja nicht. Vielmehr ist es einfach ein angepasstes Runtime, mit dem die Classpath-Anwendung aufgerufen wird, also:
Da kann es dann doch tatsächlich besser sein, das einfach anderweitig zu kapseln, sprich: wieso nicht einfach ein java kopieren, Abhängigkeiten und erzeugte Lib kopieren. Aufruf per Script.
jlink verwende ich dann nur noch, um das verkleinerte/angepasste Runtime zu erzeugen.

Die Idee ist halt, dass man auf die Module verzichtet um dann das so zu verwirklichen.
Ja. Die Module interessieren bei meiner Anwendung sowieso nicht.

Das kann man dann ggf. auch über ein Maven Plugin automatisieren. Das Binary würde man ebenso wie eine Liste mit JDKs zum Download bereit stellen. Dann kann das Plugin die Binaries herunter laden, config File erstellen, Dependencies und jar kopieren und dann das passende JDK herunter laden und entpacken. Hört sich sowas sinnvoll an? Oder habe ich mich da mit den Gedanken verrant?
Das wäre das, was ich gesucht hätte :) Aber: ggf. funktioniert das tatsächlich mit jpackage, insbesondere --input scheint mir da eine Option zu sein, um die JDBC-Treiber in das Image zu bekommen. Dann noch entsprechende --java-options mitgeben; wie gesagt, ich muss das mal probieren.
 

KonradN

Super-Moderator
Mitarbeiter
Ich dachte, Moditect schiebt nur eine module-info unter. Das mache ich ja nicht. Vielmehr ist es einfach ein angepasstes Runtime, mit dem die Classpath-Anwendung aufgerufen wird,
Moditect macht zwei Dinge:
a) Es schiebt modul-info,jar unter. Dann hat man unter target/modules/ ein angepasstes jar (Da kann man dann rein schauen und findet das module-info.class File. Wenn man bei log4j-core schaut, dann schaut man ganz schön dumm, denn da war das nicht, da es ein multi-version jar ist ... da ist es dann unter META-INF/versions/17/module-info.class ...Ich habe eben ganz schön an mir gezweifelt :) )
b) Dann kommt der eigentliche jlink aufruf.

jlink verwende ich dann nur noch, um das verkleinerte/angepasste Runtime zu erzeugen.
Sprich: Du hast etwas gebaut mit den ganzen requires auf die java.* und so, die Du brauchst und dann lässt Du Dir das Image dafür bauen.
Das nutzt Du dann um mit einem java Aufruf deine Anwendung zu starten - incl. den Runtime Abhängigkeiten auf dem Classpath.

Und das nutzt Du dann mit JPackage um das App-Image zu erstellen?

Gibt es da einen praktikablen Ansatz, den Du durchführst? JLink Aufruf mit dem Hauptmodul aber es gibt kein --ignore-missing-deps oder so bei jlink. Dein Programm nutzt evtl, ein Auto-Module und hat dann ein requires drin, das fehlt. Oder kann man das über --limit-modules eingrenzen, dass er da nicht meckert? Muss ich mal selbst mit spielen. Ansonsten wäre halt der Ansatz, dass man wirklich ein ganzes JRE hernimmt. Da hat man doch auch ein kleines Paket um 30 - 40 MB. Da sparen paar kleine Module, die entfallen, doch nicht mehr viel.
 

mihe7

Top Contributor
Sprich: Du hast etwas gebaut mit den ganzen requires auf die java.* und so, die Du brauchst und dann lässt Du Dir das Image dafür bauen.
Das nutzt Du dann um mit einem java Aufruf deine Anwendung zu starten - incl. den Runtime Abhängigkeiten auf dem Classpath.
Genau.

Und das nutzt Du dann mit JPackage um das App-Image zu erstellen?
Nein, ich spiele nur gerade mit dem Gedanken, den Murks durch jpackage zu ersetzen.

Ich stelle mir das so vor: a) ein JRE via jlink erzeugen und b) jpackage bekommt neben dem Runtime-Image einmal das Jar der Anwendung (--main-jar) und außerdem via --input noch ein Verzeichnis, das es in das Image kopieren soll (dort wäre dann der JDBC-Treiber abgelegt), den ich dann c) via --java-options in den Classpath aufnehme (ggf. ginge das auch per Manifest im Jar).

Das wird alles noch ein wenig Spielerei werden.

Ach, und weil ich es gerade lese: mit dem multi-version-Käse hatte ich auch schon meine Freude - da musste man doch tatsächlich angeben, welche Version man gerne hätte :)

Ansonsten wäre halt der Ansatz, dass man wirklich ein ganzes JRE hernimmt. Da hat man doch auch ein kleines Paket um 30 - 40 MB. Da sparen paar kleine Module, die entfallen, doch nicht mehr viel.
Ja, das ist richtig. Aber so hätte man halt einen Launcher mit dabei...
 

KonradN

Super-Moderator
Mitarbeiter
Also ein paar schnelle Tests jetzt in der Mittagspause waren noch nicht so erfolgreich bei mir. Aber bei dem Image das JLink baut verstehe ich noch nicht, woher da der Pfad zu den jars kommt.

Man hat in release unter anderem die Auflistung der Module. die Verzeichnisse sind fast 1:1 JRE, Abhängigkeiten und das jar vom Projekt sind in jars.

Woher weiss der Starter, dass er die Dinge in jars findet? Der hat ja nur:
Code:
@echo off
set JLINK_VM_OPTIONS=
set DIR=%~dp0
"%DIR%\java" %JLINK_VM_OPTIONS% -m FXAppModule/de.kneitzel.Main %*
(Startscript von Windows)

Meine ersten Versuche waren jetzt einfach einmal, dass ich da so ein Image von Hand nachbaue - wobei ich als Basis einfach ein komplettes JRE genommen habe.

Aber irgendwie überzeugt mich dieser Ansatz nicht. Denn irgendwie stolpert man hier immer wieder über diverse Feinheiten des Modulsystems. Da ist es dann doch einfacher, das nur etwas zu kapseln und wirklich bei einem Aufruf zu bleiben wie:
java -cp jars/* my.cool.package.Main
Und dann kann man da in jars Laufzeitabhängigkeiten kopieren, z.B. wenn das Logging da eine Implementation haben will oder ein JDBC Treiber wie hier im Thread ...

Aber egal, was man macht - das will dann ja auch in einer CI/CD Pipeline bauen können so dass etwas fertiges hinten raus fällt.

Und dann wird irgendwie alles unschön - und dann kann man auch direkt bei der Moditect Variante bleiben und den Abhängigkeiten die modul-info unterschieben....
 

mihe7

Top Contributor
So, jetzt habe ich das auch mal per CLI getestet: das Teil ist irgendwie doof (oder gut, je nachdem wie mans sieht :)), denn --input und zugleich --runtime-image geht nicht, dafür ist das Ding in der Lage, selbst das Runtime-Image zu erstellen. Verstehe das, wer will.

Jedenfalls habe ich mir die JARs der App und der Classpath-Abhängigkeiten (hier z. B. sqlite und flywaydb) in den Ordner target\libs kopiert, anschließend rufe ich auf (hier mal mit Umbrüchen):
Code:
jpackage -t app-image ^
    --input target\libs ^
     -p %JFX_MODULES% ^
     --add-modules java.sql,javafx.controls,javafx.fxml ^
     -n %1 ^
     --main-jar "%JAR%" ^ 
     --main-class %MC%

Das Teil erstellt dann ein App-Image inkl. der JavaFX-Module und packt das Zeug für den Classpath in einen app-Ordner, der dann auch eine cfg-Datei enthält, die ihrerseits das main-JAR und die anderen JARs im Classpath auflistet und die main-Class benennt. Im Root des App-Images findet sich dann eine EXE, die man einfach starten kann.

Damit bin ich einen Schritt weiter und muss den Spaß jetzt nur noch nach Maven übersetzen. Das sollte das Plugin ja wohl hinbekommen.
 

mihe7

Top Contributor
So, das ist ja bald mehr Maven- als Java-Code :p
XML:
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>${maven.dependency.plugin}</version>
                <executions>
                    <!-- erstmal Abhängigkeiten für den Class-Path kopieren -->
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <excludeGroupIds>org.openjfx,com.fasterxml.jackson.core,com.fasterxml.jackson.dataformat</excludeGroupIds>
                            <includeScope>runtime</includeScope>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>${project.packaging}</type>
                                </artifactItem>
                            </artifactItems>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>

                    <!-- dazu noch das Projekt-JAR -->
                    <execution>
                        <id>copy</id>
                        <phase>install</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>${project.packaging}</type>
                                    <destFileName>${project.build.finalName}.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>com.github.akman</groupId>
                <artifactId>jpackage-maven-plugin</artifactId>
                <version>${jpackage.maven.plugin}</version>
                <configuration>
                    <name>${app.name}</name>
                    <type>IMAGE</type>
                    <modulepath>
                        <dependencysets>
                            <dependencyset>                                
                                <includenames>
                                    <includename>javafx\..*</includename>
                                </includenames>
                            </dependencyset>
                        </dependencysets>
                    </modulepath>
                    <addmodules>
                        <addmodule>java.sql</addmodule>
                        <addmodule>javafx.controls</addmodule>
                        <addmodule>javafx.fxml</addmodule>
                    </addmodules>
                    <mainclass>${main.class}</mainclass>
                    <input>${project.build.directory}/modules</input>
                    <mainjar>${jar.file}.jar</mainjar>
                </configuration>
            </plugin>

Ist halt nicht besonders schön, dass man alles selbst angeben muss. Aber zumindest läuft das jetzt in Maven und nicht mehr via Batch.
 

KonradN

Super-Moderator
Mitarbeiter
Diese JPackage Aufrufe kapseln aber dennoch den JLink Aufruf und die ganze Thematik mit den Modulbeschreibungen bleibt, oder habe ich das jetzt falsch verstanden?
 

mihe7

Top Contributor
Diese JPackage Aufrufe kapseln aber dennoch den JLink Aufruf und die ganze Thematik mit den Modulbeschreibungen bleibt, oder habe ich das jetzt falsch verstanden?
Ja, jlink wird automatisch ausgeführt. Darum ja auch addmodules und der bescheidene modulepath :)

Es wird also eine non-modulare Anwendung mit jpackage verpackt und für das Runtime wird angegeben, dass man gerne java.sql, javafx.controls, javafx.fxml (und alles wovon das Zeug abhängt) hätte.
 

KonradN

Super-Moderator
Mitarbeiter
Kriegst Du denn damit auch eine Abhängigkeit ohne Modulbeschreibung mit in das Image? Das wäre meine Kernfrage. Zum Testen kannst Du ja einfach mal schauen, ob eine Abhängigkeit wie
XML:
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230227</version>
</dependency>

eingebunden werden kann.

Wenn dies nicht der Fall ist, dann macht man doch lieber eine Anwendung mit benanntem Modul statt einem unbenannten Modul (Denn darauf läuft es doch heraus - nicht modulare Anwendungen gibt es ja nicht mehr ab Java 9 - so wäre mein Verständnis.)

Wobei ich gerade am überlegen bin als fixe Idee:
  • Abhängigkeiten ohne Modulbeschreibung ggf. als scope: runtime einbinden. Dann werden sie nicht mit gelinkt.
  • dann über das shade plugin (??) schauen, ob man diese Abhängigkeiten zum jar dazu nehmen kann.
  • Vermutlich muss man aber die eigene modul-info dann auch modifizieren und die requires Einträge auf die Automodule rausnehmen
Aber das kann ich gerade nicht weiter recherchieren - das war nur eine Idee, die mir auf dem Sofa gekommen ist, als ich im Dunkeln auf das wirken der Migräne Medikamente gewartet habe ... (Und nichts ist besser, als Arbeit abzudrücken: Mach Du mal :) )
 

mihe7

Top Contributor

Anhänge

  • fxmodtest.zip
    4,1 KB · Aufrufe: 0

KonradN

Super-Moderator
Mitarbeiter
Sieht gut aus - das javafx plugin kann man natürlich rauswerfen, da das ohne Modulbeschreibung Quatsch ist.

Beim JPackage plugin noch ein
Java:
                <executions>
                    <execution>
                        <phase>install</phase>
                        <goals>
                            <goal>jpackage</goal>
                        </goals>
                    </execution>
                </executions>

Das sieht dann doch super brauchbar und einfach aus. Da werde ich noch etwas mit herum spielen.

<Scherz>
Aber so was ich jetzt auf Anhieb sehe musst Du Dir Sorgen machen: Was lässt Du so lange zu, dass wir uns mit dem moditect Plugin herum plagen. Wenn das mal nicht Unterlassene Hilfeleistung oder gar Körperverletzung durch Unterlassung ist ....
</Scherz>

@mrBrown Ich erwähne Dich mal, denn ich meine bei der Modict Lösung warst Du damals auch involviert.

@Bang_Markus Im Augenblick halte ich es für sehr wahrscheinlich, dass dies auch die Lösung für Deine Problematik sein könnte. Da kommt halt wirklich ein App-Image raus - also genau das, was man zur Weitergabe haben will!
 

mihe7

Top Contributor
Sieht gut aus - das javafx plugin kann man natürlich rauswerfen, da das ohne Modulbeschreibung Quatsch ist.
Ja, das ist noch ein Überbleibsel. Im Original habe ich da nämlich tatäschlich noch eine module-info drin (die bei flyway aber fehlt). Hintergrund ist, dass die POM ursprünglich von NB erzeugt wurde.

Aber so was ich jetzt auf Anhieb sehe musst Du Dir Sorgen machen: Was lässt Du so lange zu, dass wir uns mit dem moditect Plugin herum plagen. Wenn das mal nicht Unterlassene Hilfeleistung oder gar Körperverletzung durch Unterlassung ist ....
Folgende Einlassung zu meiner Verteidigung: das liegt ganz einfach daran, dass ich zum ersten Mal ernsthaft in die Verlegenheit gekommen bin, mich mit JavaFX und dem Modulkäse herumschlagen zu müssen. Den Leidensweg hatte ich ja in #30 schon beschrieben; der hätte zwar funktioniert aber dieses manuelle Rumgemurkse außerhalb der IDE (bzw. Maven) kann ich ja überhaupt nicht leiden. Dann hast Du mich hier auf jpackage gebracht, wobei mich da erstmal die EXE interessiert hat (statt der .bat, die jlink rauswirft). Als ich mir die Optionen angesehen habe, kam mir dann halt die Idee, dass ich damit auch die Batch-Datei ersetzen könnte (s. #25).

Jedenfalls gefällt mir das so schon besser, denn jetzt kann ich für ein Update (vermutlich) auch einfach mein Jar weitergeben. Als das Teil noch modular war, hat jlink alle Module in eine einzige Datei lib\modules gepackt; da ist irgendwie nix mit kleinen Updates - es sei denn, es gibt wieder irgendeinen Schalter, den man umlegen muss, damit man einen Patch o. ä. rausbekommt.
 

KonradN

Super-Moderator
Mitarbeiter
@Bang_Markus Falls Du noch mitliest und noch immer an einer Lösung arbeitest: Die Variante von @mihe7 ist super! Ich hatte zuerst versäumt, da noch ein weiteres javafx Modul mit hinzu zu fügen, aber danach geht es super. Das wäre also definitiv meine Empfehlung ab Heute!

Es kommen zwar zwei Warnungen beim JPackage Aufruf, da man keine Modulbeschreibung hat, aber es funktioniert!

Ich bin da gerade sehr begeistert. Ich habe da meinen Zweig zum Testen genommen, in dem ich log4j mit Modulbeschreibung eingebunden habe. Und das ist einfach genial - anders kann ich das gerade nicht ausdrücken.

Was man noch machen muss ist: Die JavaFX Module muss man als solche angeben. Aber darüber hinaus werden Abhängigkeiten nicht weiter angegeben.

Wie die POM aussieht hat @mihe7 ja schon gezeigt - aber Du findest es auch unter

Das muss ich halt noch etwas aufräumen und dann ein PR in den main branch machen. Aber das sieht wirklich gut aus!

Sorry für die Irrwege, aber ich hatte das tatsächlich bis dahin so nicht gesehen und auch nicht für möglich gehalten.

Was ich mit getestet habe:
  • Abhängigkeit ohne Modulbeschreibung (log4j-core)
  • FXMLLoader mit Controller (benötigt noprmalerweise, dass das package des Controllers auch ein opens hat - unnamed modules haben ein requires auf alles im Classpath und ein exports aller eigener Namespaces aber keine opens).

Was ich jetzt in IntelliJ brauchte war diese Hilfsklasse nur mit main Methode, die die eigentliche main Methode aufruft. (Aber das fertig gebaute Image brauchte das nicht - alles sehr interessant :) )

Bei Fragen / Problemen einfach melden!
 

KonradN

Super-Moderator
Mitarbeiter
@mihe7: Paar DInge habe ich angepasst bzw. verstehe ich nicht ganz:

a) Bei copy dependencies meckert mein IntelliJ diesen Eintrag an:
XML:
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>${project.packaging}</type>
                                </artifactItem>
                            </artifactItems>
Unter https://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html finde ich das auch nicht, habe ich rausgelöscht und ist ok.

b) Um es bei IntelliJ zu starten, war es bei mir notwendig, eh diesen Workaround mit eigener Startklasse zu haben. Das ist nicht notwendig, wenn man das mit den Modulen richtig einträgt, wie es Dein JPackage Aufruf macht. Aber darauf kann man ja auch verzichten:

Also im dependency plugin:
XML:
                            <!-- excludeGroupIds>org.openjfx</excludeGroupIds -->

und dann beim jpackage plugin:
XML:
                    <!--
                    <modulepath>
                        <dependencysets>
                            <dependencyset>
                                <includenames>
                                    <includename>javafx\..*</includename>
                                </includenames>
                            </dependencyset>
                        </dependencysets>
                    </modulepath>
                    <addmodules>
                        <addmodule>javafx.controls</addmodule>
                        <addmodule>javafx.graphics</addmodule>
                        <addmodule>javafx.fxml</addmodule>
                    </addmodules>
                    -->

Damit hat man keine Probleme, wenn man ein zusätzliches Java Modul hinzu nimmt und dann vergisst es auch dort anzugeben.

Oder habe ich da etwas übersehen und ich habe da jetzt ein Problem, welches ich in meinen Tests noch nicht abgedeckt habe?

Edit: Der modulepath konnte natürlich auch weg.
 

mihe7

Top Contributor

KonradN

Super-Moderator
Mitarbeiter
Das ist auch nicht copy-dependencies sondern nur copy
Du hattest das dann vermutlich doppelt eingefügt, denn in dem zip von dir war das:
XML:
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <excludeGroupIds>org.openjfx</excludeGroupIds>
                            <includeScope>runtime</includeScope>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>${project.packaging}</type>
                                </artifactItem>
                            </artifactItems>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>

                    <!-- dazu noch das Projekt-JAR -->
                    <execution>
                        <id>copy</id>
                        <phase>install</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/modules</outputDirectory>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>${project.artifactId}</artifactId>
                                    <version>${project.version}</version>
                                    <type>${project.packaging}</type>
                                    <destFileName>${project.build.finalName}.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
Im oberen execute hat es IntelliJ angemeckert, im unteren war es ok.

Zu b) das müsste ich mir nochmal ansehen: Ich meine, es wurden sonst zu viele Module in das runtime genommen bzw. das openjfx-Jar auch nach target/modules kopiert.
Und ich weiss jetzt nur, dass ich nichts weiss ... ich habe jetzt aber ein Buch gefunden, welches ich versuchen werde in Ruhe durchzugehen damit ich da doch noch etwas mehr durchblicke. Selbst meine Aktivität war ganz offensichtlich zu viel "durchmogeln" mit Halbwissen ... Sonst hätte mich Deine Lösung wohl auch nicht so überrascht.

Aber wenn alles in den Abhängigkeiten ist, dann sollte es doch eigentlich nicht in den Modulen sein. Und da wir keine Liste an Modulen angegeben haben, hoffe ich doch sehr, dass wir alle drin haben. Aber den Punkt habe ich noch nicht getestet und das könnte ich wenigstens mal ausprobieren: Einfach mal schauen, ob ich mit de_de Settings Zahlen parsen kann oder ob man nur die default Englischen Settings hat (Da brauchte man ja sonst ein requires jdk.localedata; - aber ich hoffe doch, dass man jetzt alles hat und damit auch alles nutzen kann. Und da geht es ja auch nicht um wirklich viel Speicherplatz, so daß ich da lieber auf eine Stelle in der POM, wo ich alles angeben muss, verzichte.

Edit: Typos und das erwähnte Buch, das ich dann jetzt einmal lesen möchte, ist "The Java Module System" .
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Java Projekt nach JavaFX convertieren AWT, Swing, JavaFX & SWT 4
M Java Gui Projekt, Würfelspiel AWT, Swing, JavaFX & SWT 2
A Wie baue ich das Bus-System in ein Java Projekt ein? AWT, Swing, JavaFX & SWT 5
J Frage zu Java Projekt [2D Game] AWT, Swing, JavaFX & SWT 3
D Java Projekt als Jar AWT, Swing, JavaFX & SWT 3
M java projekt als exe kompilieren. AWT, Swing, JavaFX & SWT 2
Juelin Für Java-Spezialisten AWT, Swing, JavaFX & SWT 4
Juelin Java <-> Delphi AWT, Swing, JavaFX & SWT 3
H Exceptions seit java: 1.6.0_65 Umstellung AWT, Swing, JavaFX & SWT 3
H Exception: java.lang.ClassCastException AWT, Swing, JavaFX & SWT 2
M JavaFX java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found AWT, Swing, JavaFX & SWT 5
J Java GUI Dropdown-Menü anzeigen AWT, Swing, JavaFX & SWT 5
M Eigene Java Klasse für allgemeine Grafikelemente AWT, Swing, JavaFX & SWT 8
thor_norsk Java - Allgemeine - Frage AWT, Swing, JavaFX & SWT 14
W Kennt jemand Dear ImGui (und den Java-Wrapper dazu)? AWT, Swing, JavaFX & SWT 0
D JAVA Schieberegler AWT, Swing, JavaFX & SWT 6
N JavaFX Einfacher Taschenrechner mit Scene Builder und Java FX AWT, Swing, JavaFX & SWT 0
Jose05 Aus einer normalen Java Klasse eine FXML-Klasse laden AWT, Swing, JavaFX & SWT 12
S Welches Java Layout sollte ich verwenden? AWT, Swing, JavaFX & SWT 3
B Actionlistener mit Java Swing AWT, Swing, JavaFX & SWT 2
P Fehlermeldung: Error: Could not find or load main class set Caused by: java.lang.ClassNotFoundException: set AWT, Swing, JavaFX & SWT 5
Encera Java FX im Eclipse-Marketplace nichtmehr auffindbar AWT, Swing, JavaFX & SWT 6
_user_q Versionscode aus build.gradle in Java-Klasse ausgeben lassen AWT, Swing, JavaFX & SWT 14
M Java Dateien kopieren mit Fortschrittsbalken AWT, Swing, JavaFX & SWT 13
M Frage zu Java Bundesligaverwaltung AWT, Swing, JavaFX & SWT 7
_user_q Gibt es eine Möglichkeit, in Java alle möglichen Zeichen automatisch tippen zu lassen? AWT, Swing, JavaFX & SWT 13
E 3D-Grafik Java Fatal error bei LWJGL AWT, Swing, JavaFX & SWT 2
Heldderschatten Java Events und Interfaces AWT, Swing, JavaFX & SWT 18
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
sserio Java Fx - Problem AWT, Swing, JavaFX & SWT 3
U Warum wird zweimal die Affinetransformation estellt (2Dgraphics, Java)? AWT, Swing, JavaFX & SWT 31
U was bewirkt die methode fill und unterschied zu anderen fill Methoden in 2dgraphics? (Java)? AWT, Swing, JavaFX & SWT 6
DonBronson Java Graphics bewegbar machen (Drag&Drop) AWT, Swing, JavaFX & SWT 3
Yonnig Lokale HTML-Datei in Java GUI rendern AWT, Swing, JavaFX & SWT 4
E Java-TexturePaint sehr langsam AWT, Swing, JavaFX & SWT 9
N Java MySQL Datenbank durchsuchen? AWT, Swing, JavaFX & SWT 7
maximstein JavaFX WebView - java.lang.NoSuchMethodError: 'boolean com.sun.prism.ResourceFactory.isDisposed()' AWT, Swing, JavaFX & SWT 4
Splayfer Custom Font in AttributedString Java AWT, Swing, JavaFX & SWT 4
imawake Java Paket-Tracking Programm 📦 AWT, Swing, JavaFX & SWT 7
izoards *.doc Seitenränder per Java setzen... AWT, Swing, JavaFX & SWT 14
T FXML Datei in Java Code einbinden: javafx.fxml.LoadException AWT, Swing, JavaFX & SWT 2
J Key-Listener in Java AWT, Swing, JavaFX & SWT 37
J Java Datei durch CMD mit Parameter ausführen AWT, Swing, JavaFX & SWT 1
N Java Mouse Listiner macht alles zusammen AWT, Swing, JavaFX & SWT 4
J Java FX NullPointerException, ObservableList wird in View nicht angezeigt.. AWT, Swing, JavaFX & SWT 34
T Exception in thread "main" java.lang.NoClassDefFoundError AWT, Swing, JavaFX & SWT 4
M Error occurred during initialization of boot layer java.lang.module.FindException: Module javafx.controls not found AWT, Swing, JavaFX & SWT 14
AmsananKING Java Menü-Problem AWT, Swing, JavaFX & SWT 1
T Swing DPI-Skalierung und Java 2D unter Java 11 (und Windows 10) AWT, Swing, JavaFX & SWT 2
J Spiel mit Java AWT, Swing, JavaFX & SWT 9
I AWT java.awt.FileDialog - "coffee cup"-Icon lässt sich nicht ersetzen AWT, Swing, JavaFX & SWT 14
O Ein Java-Programm mit Swing steuern AWT, Swing, JavaFX & SWT 1
izoards Java FX Window Event SHOWING AWT, Swing, JavaFX & SWT 17
N FXMLLoader.load java.lang.RuntimeException: Gradle AWT, Swing, JavaFX & SWT 2
T Java GUI - Würfel Programm AWT, Swing, JavaFX & SWT 6
JojoSand Java Programm wird nicht gestartet - keinen Fehlerhinweis AWT, Swing, JavaFX & SWT 9
dtr84 JavaFX/OpenJFX mittels Apache Ivy einbinden (Java 11) AWT, Swing, JavaFX & SWT 18
M Jogl und Java 3d AWT, Swing, JavaFX & SWT 0
S0PEX JavaFX Java 8 auf 15 migrieren OpenJFX mit Gradle eingebunden, jedoch nicht gefunden !? AWT, Swing, JavaFX & SWT 4
I Gui in bestehendes Java-Programm AWT, Swing, JavaFX & SWT 11
V Java-Zeichenfeld mit AWT AWT, Swing, JavaFX & SWT 3
N java Gui friert scheinbar zufällig ein AWT, Swing, JavaFX & SWT 5
T Anderen Java Code durch Code kompilieren und Fehler in Label ausgeben AWT, Swing, JavaFX & SWT 5
P Java Fx einrichten AWT, Swing, JavaFX & SWT 2
pkm Frage wegen java.lang.IllegalStateException bei DocumentListener AWT, Swing, JavaFX & SWT 4
S JavaFX Java Custom Node Grafik zurückgeben AWT, Swing, JavaFX & SWT 2
MiMa Java und JavaFX 13 läuft endlich AWT, Swing, JavaFX & SWT 4
N eclipse Java, bilder benutzten Funktioniert nicht AWT, Swing, JavaFX & SWT 6
Trèfle Ausklappbare Diagramme in Java AWT, Swing, JavaFX & SWT 1
R Java, GUI, Hintergrundbild, Image, AWT, Swing, JavaFX & SWT 4
K JAVA FX Constraints AWT, Swing, JavaFX & SWT 2
F Java FX und webcam AWT, Swing, JavaFX & SWT 1
T Wie kann man in java aufwendige grafiken programmieren AWT, Swing, JavaFX & SWT 1
M Swing Java Swing/AWT Combobox Bug AWT, Swing, JavaFX & SWT 3
S Java GUI durch variable Größe einer Map anpassen AWT, Swing, JavaFX & SWT 3
J Java SWT Tabelleninhalt formattieren AWT, Swing, JavaFX & SWT 10
Blender3D Falsche Werte mit Java Toolkit Screensize AWT, Swing, JavaFX & SWT 4
K Swing AWT-EventQueue-1 java.lang.NoClassDefFoundError bei setVisible(true) AWT, Swing, JavaFX & SWT 3
A Java Programm gestalten AWT, Swing, JavaFX & SWT 4
B [Problem] Java öffnet Word-Datein nicht AWT, Swing, JavaFX & SWT 14
S Swing Java Swing AWT, Swing, JavaFX & SWT 6
I Java Bildfarbe ändern wie bei Photoshop AWT, Swing, JavaFX & SWT 9
R JavaFX Java FXML Vererbung in Klassen AWT, Swing, JavaFX & SWT 9
T Java: Zwei abhängige JSlider machen nicht das, was sie sollen AWT, Swing, JavaFX & SWT 4
J Parallele Aktionen in Java FX richtig durchführen. AWT, Swing, JavaFX & SWT 5
Neumi5694 java.awt.Window nach javafx.stage.Window AWT, Swing, JavaFX & SWT 1
M JavaFX java.lang.IllegalStateException: Location is not set. AWT, Swing, JavaFX & SWT 9
L Java- CardLayout AWT, Swing, JavaFX & SWT 10
M Java zeichnet nicht pixelgenau AWT, Swing, JavaFX & SWT 40
B Swing Eclipse is running under 0, but this Java project has a 1.6 Java compliance level, so WindowBuilder AWT, Swing, JavaFX & SWT 2
L Java- UI zweites Fenster aus einer anderen Klasse öffnen durch ButtonClick AWT, Swing, JavaFX & SWT 4
S Java Gui AWT, Swing, JavaFX & SWT 5
R Sierpinski Dreieck mit Java FX AWT, Swing, JavaFX & SWT 4
Flynn java.lang.UnsupportedOperationException: Not supported yet AWT, Swing, JavaFX & SWT 7
D Zwei getrennte Java Klassen verbinden. Wie ? AWT, Swing, JavaFX & SWT 2
D SQL Statements mit Java Swing benutzen AWT, Swing, JavaFX & SWT 4
D DatePicker für Java Swing AWT, Swing, JavaFX & SWT 2
S AWT Java print dialog Problem AWT, Swing, JavaFX & SWT 0
N Aktualisierung des Fensters AWT Java ohne Ruckeln AWT, Swing, JavaFX & SWT 3
MiMa Java, Maven Projekte nach JavaFX? AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben