JavaFX/OpenJFX mittels Apache Ivy einbinden (Java 11)

dtr84

dtr84

Mitglied
Hallo.

Ich arbeite an einem relativ komplexen Projekt, dass eine GUI mittels JavaFX darstellt. Darüber hinaus verwendet das Projekt noch diverse weitere Bibliotheken, wie z.B. Apache Commons, Bouncy Castle und SQLite. Der Build-Prozess wird mittels Apache Ant gesteuert, wobei die Abhängigkeiten (Bibliotheken) mit Apache Ivy verwalten werden. Bisher läuft das Projekt unter Java 8 (LTS).

Das Projekt soll nun aber von Java 8 auf Java 11 (LTS) portiert werden.

Das Problem: Während bei Java 8 das JavaFX noch fester bestandteil des JRE bzw. JDK war, ist es bei Java 11 nicht mehr enthalten. Soweit ich verstehe, müssen unter Java 11 deshalb jetzt die JavaFX-Bibliotheken von "OpenJFX" eingebunden werden, um JavaFX nutzen zu können.

Ich habe es auch soweit geschafft, die OpenJFX Bibliotheken in die ivy.xml einzutragen:
XML:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="com.example" module="jfx11"/>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-base -->
        <dependency org="org.openjfx" name="javafx-base" rev="11.0.2"/>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
        <dependency org="org.openjfx" name="javafx" rev="11.0.2">
            <artifact name="javafx" type="pom" ext="pom"/>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-base -->
        <dependency org="org.openjfx" name="javafx-base" rev="11.0.2">
            <artifact name="javafx-base" e:classifier="win"/>
            <!--<artifact name="javafx-base" e:classifier="linux"/>-->
            <!--<artifact name="javafx-base" e:classifier="mac"/>-->
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-controls -->
        <dependency org="org.openjfx" name="javafx-controls" rev="11.0.2">
            <artifact name="javafx-controls" e:classifier="win"/>
            <!--<artifact name="javafx-controls" e:classifier="linux"/>-->
            <!--<artifact name="javafx-controls" e:classifier="mac"/>-->
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
        <dependency org="org.openjfx" name="javafx-graphics" rev="11.0.2">
            <artifact name="javafx-graphics" e:classifier="win"/>
            <!--<artifact name="javafx-graphics" e:classifier="linux"/>-->
            <!--<artifact name="javafx-graphics" e:classifier="mac"/>-->
        </dependency>
    </dependencies>
</ivy-module>

Der Build-Prozess läuft jetzt soweit durch. Jedoch zur Laufzeit bekomme ich beim Programmstart sofort folgenden Fehler:
Error: JavaFX runtime components are missing, and are required to run this application

Meine Vermutung: JavaFX besteht ja nicht bloß aus Java-Code (JAR Dateien), sondern eben auch aus "nativen" DLL-Dateien. Bei Java 8 waren diese im JRE bzw. JDK enthalten. Man findet bei Java 8 im "bin" Ordner des JDK/JRE die Dateien glass.dll, javafx_font.dll und so weiter, die offensichtlich den "platform-spezifischen" Teil von JavaFX enthalten. Diese Dateien fehlen natürlich bei einem Java 11 im JDK/JRE! Und über Apache Ivy werden zwar die JAR-Dateien für JavaFX in den Class-Path eingebunden, aber die zugehörigen DLL-Dateien fehlen dann immer noch zur Laufzeit im "bin" Verzeichnis!

(Jedenfalls sieht es mir so aus, als ob dass das Problem ist)

Kann mir jemand sagen, was der vorgesehen Weg ist, um JavaFX (OpenJFX) mit Java 11 zum Laufen bekommt, mit Apache Ant+Ivy? ;)

Danke und viele Grüße!
 
Zuletzt bearbeitet:
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Die nativen Libs sind in den Jars mit System-spezifischem Classifier enthalten, üblicherweise reicht es, diese einzubinden.

Keine Ahnung was man mit Ant/Ivy machen muss, damit es korrekt läuft, deshalb einfach nur der generelle Hinweis, der immer kommt wenn irgendwer Ant benutzt: benutz Maven oder Gradle :)

Das Problem: Während bei Java 8 das JavaFX noch fester bestandteil des JRE bzw. JDK war, ist es bei Java 11 nicht mehr enthalten. Soweit ich verstehe, müssen unter Java 11 deshalb jetzt die JavaFX-Bibliotheken von "OpenJFX" eingebunden werden, um JavaFX nutzen zu können.
Das ist nur so halbrichtig: JavaFX war in manchen JDKs/JREs enthalten, aber keineswegs in allen.
Und entfernt wurde es nur aus dem Oracle JDK. Man bekommt aber weiterhin JDKs von zB Azul oder Bellsoft, die es weiterhin mitbringen. Wenn du eins von denen nutzt, ist auch weiterhin JavaFX verfügbar.
 
dtr84

dtr84

Mitglied
Die nativen Libs sind in den Jars mit System-spezifischem Classifier enthalten, üblicherweise reicht es, diese einzubinden.
Danke für die Antwort!

Ich verstehe nicht genau was Du meinst. Aber dass "nativer" Code (DLL-Dateien unter Windows, SO-Dateien unter Linux) direkt aus einem JAR geladen werden, ist meines Wissens nach nicht möglich. Das Laden von DLL-Dateien passiert ja quasi über den Loader des Betriebssystems - also unter der Haube wird (bei Windows) letzlich irgendwo LoadLibrary() aus der Win32 API aufgerufen - und die "kennt" keine JAR-Dateien.

Wenn man sich mal das offizielle JavaFX JDK von der OpenJFX-Seite ansieht, dann gibt es da in der Windows-Variante ebenfalls einen "lib" Ordner mit JAR-Files plus einen "bin" Ordner mit den zugehörigen DLL-Dateien. Die Farge ist allerdings, wie ich diese DLL-Dateien so in meine Anwendung integrieren kann, dass JavaFX sie zur Laufzeit auch findet. Bei Java 8 waren diese, wie gesagt, noch direkt im "bin" Ordner des JRE/JDK enthalten. Es kann aber ja kaum zur Nutzung unserer Anwendung vorrausgesetzt werden, dass der Benutzer erst irgendwelche DLL-Dateien aus dem JavaFX JDK in seine jeweilige JRE/JDK rein kopiert - klingt nach Gefrickel. Außerdem hat das bei meinem Test auf dem Weg auch gar nicht funktioniert.

Keine Ahnung was man mit Ant/Ivy machen muss, damit es korrekt läuft, deshalb einfach nur der generelle Hinweis, der immer kommt wenn irgendwer Ant benutzt: benutz Maven oder Gradle :)

Leider, wie schon gesagt, geht es hier um ein bestehendes und ziemlich komplexes Projekt. Das zugehörige Ant-File (build.xml) ist ziemlich komplex. Es werden im Rahmen des Build-Prozess nicht einfach nur die kompilierten class-Files zusammen mit den benötigten Bibliotheken zu einem JAR zusammen gepackt, sondern auch Config-Dateien und einiges mehr erzeugt. Einfach mal das Build-System über den Haufen zu schmeißen ist daher kaum möglich. Außerdem verwendet Ivy, soweit ich das sehe, ohnehin das Maven-Repo, um die JavaFX-Bibliotheken aufzulösen.

So oder so: Es dürfte letzendlich keinen großen Unterschied machen, welches Build-System man verwendet. Letzten Endes fällt am Ende das "finale" JAR raus, das meine Anwendung plus die dazu gelinkten Bibliotheken enthält. Unter Windows wird daraus per Launch4j noch eine selbstlaufendes EXE gemacht. Aber die Frage bleibt: Wo bzw. wie müssen die DLL-Dateien für JavaFX bereit gestellt werden, damit JavaFX sie zur Laufzeit findet. Ich denke kaum, dass Maven oder Gradle diese Abhängkeit zu den nativen DLLs einfach weg zaubern kann... oder was machen die anders?

Das ist nur so halbrichtig: JavaFX war in manchen JDKs/JREs enthalten, aber keineswegs in allen.
Und entfernt wurde es nur aus dem Oracle JDK. Man bekommt aber weiterhin JDKs von zB Azul oder Bellsoft, die es weiterhin mitbringen. Wenn du eins von denen nutzt, ist auch weiterhin JavaFX verfügbar.

Okay. Allerdings ist die Vorraussetzung, dass unsere Anwendung mit dem offiziellen Orace JDK bzw. JRE laufen muss. Die wohl am weitesten verbreitete Alternative zur Oracle JDK ist (AFAIK) das AdoptOpenJDK von der Eclipse Foundation, welches ja ebenfalls kein JavaFX mehr mitbringt.

Dem Benutzer zu sagen, unsere Anwendung läuft nur mit "exotischen" nicht-standard JREs/JDKs wird "von oben" sicher kein Zustimmung finden ;)

(wenn irgendwie möglich, sollte die Anwendung so ausgeliefert werden, dass sie direkt mit dem offiziellen Orace JDK läuft)

Viele Grüße!
 
Zuletzt bearbeitet:
kneitzel

kneitzel

Top Contributor
Ich verstehe nicht genau was Du meinst. Aber dass "nativer" Code (DLL-Dateien unter Windows, SO-Dateien unter Linux) direkt aus einem JAR geladen werden, ist meines Wissens nach nicht möglich. Das Laden von DLL-Dateien passiert ja quasi über den Loader des Betriebssystems - also unter der Haube wird (bei Windows) letzlich irgendwo LoadLibrary() aus der Win32 API aufgerufen - und die "kennt" keine JAR-Dateien.
Ich denke, dass Du dies falsch siehst. Zumindest wenn man die Abhängigkeiten per Maven lädt, dann kommen da keine DLL oder so zum tragen. Es gibt eine Plattformspezifische jar (z.B. bei javafx-base-11.0.1.jar gehört dann - je nach Plattform eine Datei wie javafx-base-11.0.1-win.jar dazu.
Und die scheint ohne DLLs auszukommen, zumindest habe ich da erst einmal nichts an DLLs gefunden ...

Und sowas sollte auch per ivy eingebunden funktionieren.

Dem Benutzer zu sagen, unsere Anwendung läuft nur mit "exotischen" nicht-standard JREs/JDKs wird "von oben" sicher kein Zustimmung finden ;)
Das ist seit Java 9 eh kein Thema mehr. Es wird ein ggf. abgespecktes JRE in Form eines Image mitgegeben. Dazu wurde ja eben JLink eingeführt.
Und woher nehmen eure Kunden das JRE von Oracle? Oder arbeitet Ihr noch auf Java 8 Basis?
Es kann aber ja kaum zur Nutzung unserer Anwendung vorrausgesetzt werden, dass der Benutzer erst irgendwelche DLL-Dateien aus dem JavaFX JDK in seine jeweilige JRE/JDK rein kopiert - klingt nach Gefrickel.
Das klingt alle srecht nach Gefrickel muss ich sagen. Und nein - da wird nichts in ein JRE / JDK Verzeichnis kopiert! Alleine schon die Idee lässt mich grausen! Das sind dann auch die, die meinen, dass man das lib Verzeichnis schön füllen kann ...

JavaFX hat eine tolle Dokumentation! Warum schaust Du nicht einmal auf openjfx.io das Getting Started an? Da wird dann auch beschrieben, wie das ohne Gradle / Maven funktionieren wird ... Da sind dann auch die Abhängigkeiten klar erläutert, die notwendig sind. Somit können Kunden einfach:
- JDK installieren
- JavaFX installieren
- Die Applikation entsprechend starten (also mit module-path setzen und so - siehe Getting Started)

Aber mit aktuellem Java baue ich lieber ein App-Image - dann hat der Kunde einfach meine App und startet die Applikation (Also Windows-exe, Mac hat die .app und Linux hat auch ein tolles Binary) ... So geht es halt auch :)
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Ich verstehe nicht genau was Du meinst. Aber dass "nativer" Code (DLL-Dateien unter Windows, SO-Dateien unter Linux) direkt aus einem JAR geladen werden, ist meines Wissens nach nicht möglich. Das Laden von DLL-Dateien passiert ja quasi über den Loader des Betriebssystems - also unter der Haube wird (bei Windows) letzlich irgendwo LoadLibrary() aus der Win32 API aufgerufen - und die "kennt" keine JAR-Dateien.

Wenn man sich mal das offizielle JavaFX JDK von der OpenJFX-Seite ansieht, dann gibt es da in der Windows-Variante ebenfalls einen "lib" Ordner mit JAR-Files plus einen "bin" Ordner mit den zugehörigen DLL-Dateien. Die Farge ist allerdings, wie ich diese DLL-Dateien so in meine Anwendung integrieren kann, dass JavaFX sie zur Laufzeit auch findet. Bei Java 8 waren diese, wie gesagt, noch direkt im "bin" Ordner des JRE/JDK enthalten. Es kann aber ja kaum zur Nutzung unserer Anwendung vorrausgesetzt werden, dass der Benutzer erst irgendwelche DLL-Dateien aus dem JavaFX JDK in seine jeweilige JRE/JDK rein kopiert - klingt nach Gefrickel. Außerdem hat das bei meinem Test auf dem Weg auch gar nicht funktioniert.

Doch, das ist natürlich möglich. Die nativen libs sind wie gesagt in den jeweiligen System-spezifischen Jars enthalten, und es reicht diese im Class- oder Module-Path zu haben, damit diese geladen werden.
zB enthält javafx-graphics-15.0.1-win.jar die für Windows nötigen dlls und javafx-graphics-15.0.1-linux.jar die für Linux nötigen so-Dateien.

So oder so: Es dürfte letzendlich keinen großen Unterschied machen, welches Build-System man verwendet.
Naja, der Unterschied ist: Mit Maven und Gradle gibt man die JavaFX-Dependency an und es läuft – mit Ant ist das offensichtlich nicht so :)

Zu Ant kann man kaum mehr sagen als "Es sollte funktionieren", vor allem wenn man den konkreten Build-Prozess nicht kennt und auch nicht reproduzieren kann.

Bekommst du ein minimales ausfühbares Beispiel hin, was einfach nur JavaFX einbindet und ein Fenster mit Hello-World anzeigt? So, dass es unter einem JDK mit JavaFX läuft, aber nicht, wenn man JavaFX als Dependency nutzt? Dann könnte man sich genauer angucken, an welcher Stelle es schief geht.

Unter Windows wird daraus per Launch4j noch eine selbstlaufendes EXE gemacht.

Ich würde in dem Fall auch nicht ausschließen, dass es an Launch4j liegt, hab aber keine Erfahrung damit. Tritt der Fehler auch ohne das Verpacken als exe auf?

Und wenn ihr sowieso nicht die Jar als Jar ausliefert: Warum nicht mit Launch4J das JRE bundeln – oder noch besser: den Umstieg ganz durchziehen und jlink und jpackage nutzen
 
dtr84

dtr84

Mitglied
Ich denke, dass Du dies falsch siehst. Zumindest wenn man die Abhängigkeiten per Maven lädt, dann kommen da keine DLL oder so zum tragen. Es gibt eine Plattformspezifische jar (z.B. bei javafx-base-11.0.1.jar gehört dann - je nach Plattform eine Datei wie javafx-base-11.0.1-win.jar dazu.
Und die scheint ohne DLLs auszukommen, zumindest habe ich da erst einmal nichts an DLLs gefunden ...

Und sowas sollte auch per ivy eingebunden funktionieren.

Danke für die Antwort. Aber ich denke, doch, die gibt es schon ;)

Wenn Du mal mit einem Tool wie dem Process Explorer schaust, welche DLL-Dateien Dein Java-Prozess tatsächlich lädt, dann sieht man, dass bei einer JavaFX-Anwendung, die unter Java 8 läuft, solche Dateien wie "glass.dll" und "javafx_font.dll" geladen werden - und zwar aus dem "bin" Ordner des JRE/JDK. Diese Fehlen bei Java 11 im JRE/JDK, jedenfalls bei Oracle oder AdoptOpenJDK. Und es sind auch genau die DLL-Dateien, die das JavaFX SDK von OpenJFX (in der Windows-Variante) in seinem "bin" Ordner mitliefert - zusätzlich zu den JARs im "lib" Ordner.

Dass Problem scheint nun genau darin zu bestehen, dass man per Apache Ivy zwar die für JavaFX erforderlichen JAR-Dateien einbinden kann, womit die Anwendung dann baut. Aber zur Laufzeit die zugehörigen DLL-Dateien nicht gefunden werden...

Ich weiß aber nicht, wie man das löst. Weil diese DLL-Dateien ja "normalerweise" (bisher, bei Java 8) ein Bestandteil des JRE/JDK sind.

Das ist seit Java 9 eh kein Thema mehr. Es wird ein ggf. abgespecktes JRE in Form eines Image mitgegeben. Dazu wurde ja eben JLink eingeführt.
Und woher nehmen eure Kunden das JRE von Oracle? Oder arbeitet Ihr noch auf Java 8 Basis?

Die Anwendung läuft aktuell unter Java 8, aber jetzt soll nach Java 11 protiert werden.

Welches JDK/JRE der Kunde benutzt hat man ja nicht so wirklich in der Hand. Benutzer in Unternehmen haben in der Regel das Oracle JDK von Ihrer IT zentral aufgespielt, weil das Unternehmen das lizenziert hat. Und dass soll dann bitte schön auch benutzt werden.

Der Standard-User gibt vermutlich "Java" in Google ein und landet dann auf der Oracle-Seite, wo er sich ebenfalls ein Oracle JDK zieht.

Das klingt alle srecht nach Gefrickel muss ich sagen. Und nein - da wird nichts in ein JRE / JDK Verzeichnis kopiert! Alleine schon die Idee lässt mich grausen! Das sind dann auch die, die meinen, dass man das lib Verzeichnis schön füllen kann ...

Das sehe ich ganz genau so!

Deshlab beschäftigt mich ja auch die Frage: Wie sorge ich bei einem standard JDK/JRE, das ab Java 11 nun einmal kein JavaFX mehr enthält, dass die Anwendung zur Laufzeit die erforderlichen DLL-Dateien findet?

Nur die JARs in meine Anwendung rein zu linken reicht ja offensichtlich nicht. Wie schon gesagt, Windows kann keine DLL-Dateien direkt aus einem JAR (ZIP-File) laden. Irgendwo müssen diese als einzelne Dateien liegen. Aber das muss eben in einem der Verzeichnisse sein, wo Windows auch nach DLL-Dateien sucht. Und das ist standardmäßig eben "The directory from which the application loaded", also da wo das EXE liegt.

(in Falle von Java-Anwendungen wäre das die "java.exe")

Standard Search Order for Desktop Applications:
* The directory from which the application loaded.
* The system directory. Use the GetSystemDirectory function to get the path of this directory.
* The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
* The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.

JavaFX hat eine tolle Dokumentation! Warum schaust Du nicht einmal auf openjfx.io das Getting Started an? Da wird dann auch beschrieben, wie das ohne Gradle / Maven funktionieren wird ... Da sind dann auch die Abhängigkeiten klar erläutert, die notwendig sind. Somit können Kunden einfach:
- JDK installieren
- JavaFX installieren
- Die Applikation entsprechend starten (also mit module-path setzen und so - siehe Getting Started)

Leider keine Dokumentation zu Apache Ant + Apache Ivy.

Würde ich mit einem neuen Projekt starten und hätte frei Wahl ein Build-System auszuwählen, dann wäre die Situation sicherlich eine andere. Aber im Moment geht es um ein komplexes bestehendes Projekt. Das Build-System über den Haufen zu werfen ist aktuell nicht drin.

Viele Grüße
 
dtr84

dtr84

Mitglied
Doch, das ist natürlich möglich. Die nativen libs sind wie gesagt in den jeweiligen System-spezifischen Jars enthalten, und es reicht diese im Class- oder Module-Path zu haben, damit diese geladen werden.
zB enthält javafx-graphics-15.0.1-win.jar die für Windows nötigen dlls und javafx-graphics-15.0.1-linux.jar die für Linux nötigen so-Dateien.

Wenn Du mal Deine JavaFX-Anwendung unter Windows startest und mit dem Process Explorer (oder einem ähnlichen Tool) schaust, welche DLL-Dateien in dem Java-Prozess tatsächlich geladen sind, wirst Du sicher sehen, dass da auch "glass.dll" und weitere JavaFX-spezifische DLLs dabei sind.

Die Frage ist, wo genau sie liegen. Und, vor allem, wie ein standard JRE/JDK (ohne eingebautes JavaFX) dazu gebracht wurde, sie zu laden.

Tatsächlich, wenn ich nicht Ant+Ivy benutze, sondern die JARs "von Hand" direkt aus dem manuell heruntergeladenen JavaFX JDK in das Eclipse-Projekt einbinden, und wenn ich dann noch zusätzlich zur Laufzeit "--module-path" angebe (auf das JavaFX SDK), lädt er die DLLs aus dem JavaFX JDK:

Siehe bitte:

Aber, so kann man das natürlich nicht deployen... :confused:

(und einen Build-Prozess, bei dem man erst JARs manuell über das JavaFX JDK herunterladen, und dann noch manuell Aufruparameter zur Laufzeit setzen muss, mit dem Pfad zum loken JavaFX JDK Pfad - das ist so natürlich alles auf Dauer kein gangbarer Weg)

Ich würde in dem Fall auch nicht ausschließen, dass es an Launch4j liegt, hab aber keine Erfahrung damit. Tritt der Fehler auch ohne das Verpacken als exe auf?

Ja, es tritt auch auf, wenn ich das JAR direkt über die Kommando-Zeile starte. Oder wenn ich die Anwendung in Eclipse laufe lassen.

Viele Grüße.
 
Zuletzt bearbeitet:
kneitzel

kneitzel

Top Contributor
zB enthält javafx-graphics-15.0.1-win.jar die für Windows nötigen dlls
Ich hatte in diversen javafx Elementen nachgesehen und keine dlls gefunden ... aber graphics hatte ich irgendwie nicht geschaut ...
Das erklärt das dann ... im Image selbst sind nur DLLs, die vom JDK7JRE kommen ...


Ansonsten ist das ein interessanter Punkt - ich schaue mir das auch gerade an, ob und wie ich da ein kleines Beispiel zusammen bekomme ...
Erst einmal muss man ja auch die ganzen classifier win JARs bekommen ... das war der erste Punkt und einfach zu haben:

Code:
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="org.apache" module="hello-ivy"/>
    <dependencies>
        <dependency org="org.openjfx" name="javafx-fxml" rev="11.0.2">
            <artifact name="javafx-fxml"/>
            <artifact name="javafx-fxml" e:classifier="win"/>   
        </dependency>
        
        <dependency org="org.openjfx" name="javafx-controls" rev="11.0.2">
            <artifact name="javafx-controls"/>
            <artifact name="javafx-controls" e:classifier="win"/>   
        </dependency>

        <dependency org="org.openjfx" name="javafx-graphics" rev="11.0.2">
            <artifact name="javafx-graphics"/>
            <artifact name="javafx-graphics" e:classifier="win"/>   
        </dependency>
        
        <dependency org="org.openjfx" name="javafx-base" rev="11.0.2">
            <artifact name="javafx-base"/>
            <artifact name="javafx-base" e:classifier="win"/>   
        </dependency>
    </dependencies>
</ivy-module>

Damit hat man schon einmal die Abhängigkeiten zusammen.

Aber weiter bin ich noch nicht - das bauen eines ant files ist doch etwas, das mir nicht ganz so gut von der Hand geht ... man vergisst halt doch zu viel und dann muss man vieles nachlesen...
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Wenn Du mal Deine JavaFX-Anwendung unter Windows startest und mit dem Process Explorer (oder einem ähnlichen Tool) schaust, welche DLL-Dateien in dem Java-Prozess tatsächlich geladen sind, wirst Du sicher sehen, dass da auch "glass.dll" und weitere JavaFX-spezifische DLLs dabei sind.

Die Frage ist, wo genau sie liegen.
Die liegen, wie schon gesagt, in den System-spezifischen Jars, zB in javafx-graphics-15.0.1-win.jar (und zT auch in anderen, base könnte welche enthalten, hab grad keine Zeit die Jars durchzugucken).

Und, vor allem, wie ein standard JRE/JDK (ohne eingebautes JavaFX) dazu gebracht wurde, sie zu laden.
Sie müssen im Class- oder Module-Path liegen, das ist alles.

Tatsächlich, wenn ich nicht Ant+Ivy benutze, sondern die JARs "von Hand" direkt aus dem manuell heruntergeladenen JavaFX JDK in das Eclipse-Projekt einbinden, und wenn ich dann noch zusätzlich zur Laufzeit "--module-path" angebe (auf das JavaFX SDK), lädt er die DLLs aus dem JavaFX JDK Pfad:

Siehe bitte:
https://i.ibb.co/JKrVsh3/grafik.png
Aber, so kann man das natürlich nicht deployen... :confused:

(und einen Build-Prozess, bei dem man erst JARs manuell über das JavaFX JDK herunterladen, und dann noch manuell Aufruparameter zur Laufzeit setzen muss, mit dem Pfad zum loken JavaFX JDK Pfad - das ist so natürlich alles auf Dauer kein gangbarer Weg)
Das ist auch beides nicht nötig.

Das JavaFX JDK braucht man nicht (und sollte man nicht nutzen, wenn man die Dependencys nutzt, das macht nur Probleme).
Den Module-Path muss man auch nicht nutzen, es reicht wenn die Klassen im Classpath liegen.

Ja, es tritt auch auf, wenn ich das JAR direkt über die Kommando-Zeile starte. Oder wenn ich die Anwendung in Eclipse laufe lassen.
Wenn das auch in Eclipse auftritt, würde ich auf ein Problem beim Auflösen der Dependencies tippen.

Wie gesagt: kannst du mal ein minimales Beispiel zeigen? Dann kann man versuchen, dass zu reproduzieren :)
 
dtr84

dtr84

Mitglied
Wie gesagt: kannst du mal ein minimales Beispiel zeigen? Dann kann man versuchen, dass zu reproduzieren :)

Ja, klar. Hier ist ein minimal Beispiel, Eclipse-Projekt plus ivy.xml:

Ich verwende hier zum Test das aktuelle Java 11 von AdoptOpenJDK, das selbst kein JavaFX mit bringt.

Wie man sieht erkennt Eclipse, mittles Ivy-Plugin, die JavaFX Abhängigkeiten. Es baut alles erfolgreich:

...jedoch zur Laufzeit:
Fehler: Zum Ausführen dieser Anwendung benötigte JavaFX-Runtime-Komponenten fehlen

Viele Grüße
 
Zuletzt bearbeitet:
kneitzel

kneitzel

Top Contributor
Also bei JavaFX gibt es eine Besonderheit bei dem ClassLoader. Ich habe mich da für die Details nicht interessiert, aber dieser Fehler kann durch einen kleinen Workaround umgangen werden:
Statt einfach nur eine Klasse zu haben wie:
Java:
package helloworld;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        StackPane root = new StackPane();
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

Nimmt man noch eine zweite Klasse dazu:
Java:
package helloworld;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main {
    public static void main(String[] args) {
        HelloWorld.main(args);
    }
}

Das sollte dieses Problem beheben. Bei meinem HelloWorld Tests kann man das sehr schön sehen:
Code:
C:\Temp\JavaFX Test>java -classpath .\* helloworld.Main     

C:\Temp\JavaFX Test>java -classpath .\* helloworld.HelloWorld
Fehler: Zum Ausführen dieser Anwendung benötigte JavaFX-Runtime-Komponenten fehlen

C:\Temp\JavaFX Test>


Ansonsten habe ich hier auch ein paar Tests gemacht aber habe auch noch ein paar Probleme mit dem classpath wenn ich es über das Manifest starte ... aber wenn ihr eine EXE baut, dann dürfte das eher egal sein und der Aufruf oben sollten gehen, oder?
 
kneitzel

kneitzel

Top Contributor
Der schönere Weg ist, auf die main in der Application-Klasse zu verzichten und das in anderen main mit Application.launch(HelloWorld.class, args) zu starten
Das ist ein guter Hinweis, die Möglichkeit habe ich gar nicht bedacht / übersehen.

Ich bin hier auch gerade nur mit Notepad++ unterwegs... Und wenn das als Ausrede nicht zählt, dann halt: Aber die main in Application braucht es, wenn man es vorführen will. :)
 
dtr84

dtr84

Mitglied
kneitzel hat gesagt.:
Also bei JavaFX gibt es eine Besonderheit bei dem ClassLoader. Ich habe mich da für die Details nicht interessiert, aber dieser Fehler kann durch einen kleinen Workaround umgangen werden:
Der schönere Weg ist, auf die main in der Application-Klasse zu verzichten und das in anderen main mit Application.launch(HelloWorld.class, args) zu starten

Ich werd bekloppt! Das ganze Wochenende schwarzer Bildschirm, und jetzt klappt das auf einmal! :D

Unglaublich, dass es die ganze Zeit daran lag 🤯

Übrigens, jetzt wo es mit den JAR Files von Ivy läuft, kann man auch sehen, woher JavaFX die benötigten DLL-Dateien lädt, wenn sie nicht im JRE/JDK integriert sind. Die Dateien werden nämlich nach "%USERPROFILE%\.openjfx\cache" extrahiert und anschließend von dort geladen:

(Dass er die DLL-Dateien einfach mal selbst zur Laufzeit aus dem JAR frech irgendwo hin extrahiert, darauf wäre ich jetzt auch nicht gekommen)

Vielen Dank für den Hinweis !!!
🍻
 
Zuletzt bearbeitet:
dzim

dzim

Top Contributor
Das ist übrigens kein wirklicher Fehler. Ich hab letztens mal eine Korrespondenz im Java-Bugtracker (glaub ich mich zu erinnern) gelesen.
Das der Workaround klappt ist der eigentliche Bug, den sie auch fixen wollen.
Eigentlich soll JavaFX ab JavaFX 11+ nur noch "ordentlich" modularisiert und nicht mehr via ClassPath verwendet werden. Der Code (in der Application) macht intern ein java.base-Modul-Check (oder so) und der schlägt im ClassPath-Umfeld fehl. Verwendet man nun den Woraround, kommt ein Bug zu tragen, dass dort in der Applikation diese Modul-Erkennung nicht mehr korrekt (also wie sie angedacht war) durchgeführt werden kann.
Übrigens *kann* man, wenn man will, oder es bei deployen (jlink, jpackage) später einfacher haben will, auch einfach das Full JDK von Bell-Soft, oder ZuluFX von Azul Systems verwenden. Da ist dann - ganz so wie früher beim Oracle JDK - JavaFX (oder besser OpenJFX) mit rein gebundlet.

Nur so mein Beitrag am Schluss, obwohl ihr das Problem ja schon gelöst habt...
 
dzim

dzim

Top Contributor
Ja, ich erinner mich daran, das Michael Paus, der Autor der Mail, damals schon recht früh in einem Repository von Dirk Lemmermann diesen Workaround verwendet hat. Aber auch hier schwirrte der schon umher.
Aber wie gesagt gibt es wohl eher Bestrebungen den Workaround, der auf einem Bug beruht, kaputt zu machen, als das JPMS-Enforcement zu beseitigen. Leider.

Und danke, dass du den Link rausgesucht hast @mrBrown ! 👍
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S JavaFX - mit Listener Veränderungen in einer TableView abhören AWT, Swing, JavaFX & SWT 3
R Können Animationen in JavaFX "verschluckt" werden? AWT, Swing, JavaFX & SWT 8
D runnable Jar mit Javafx erstellen(Eclipse) AWT, Swing, JavaFX & SWT 10
Monokuma Blöcke erzeugen (JavaFX) AWT, Swing, JavaFX & SWT 1
P JavaFx - Progressbar - Füllen mittels mehreren Tasks AWT, Swing, JavaFX & SWT 0
Rafael.Cupari JavaFx Installer AWT, Swing, JavaFX & SWT 16
Monokuma Swing zu JavaFX AWT, Swing, JavaFX & SWT 3
C JavaFx sound abspielen AWT, Swing, JavaFX & SWT 3
C JavaFX mit CSS in Eclipse AWT, Swing, JavaFX & SWT 2
parrot JavaFX Fehler AWT, Swing, JavaFX & SWT 4
B JavaFX JavaFX Anwendung deployen (entw als runnableJAR oder exe-Datei) AWT, Swing, JavaFX & SWT 15
N JavaFX applikation auf anderen Systemen zum laufen bringen AWT, Swing, JavaFX & SWT 7
W JavaFX JavaFX - TreeView will nicht AWT, Swing, JavaFX & SWT 8
H JavaFX JavaFX - Scene Builder - BorderPane AWT, Swing, JavaFX & SWT 23
D Columns unabhängig voneinander mit Daten füllen JavaFx AWT, Swing, JavaFX & SWT 1
C JavaFX Installation unter IntelliJ IDEA AWT, Swing, JavaFX & SWT 5
J JavaFX Label aktualisieren AWT, Swing, JavaFX & SWT 18
H JavaFX JavaFX Import Fehler AWT, Swing, JavaFX & SWT 4
M JavaFX javaFX Label-Text wird nicht gesetzt AWT, Swing, JavaFX & SWT 3
T Szene wechselen JavaFX mit If in Main Class AWT, Swing, JavaFX & SWT 2
S JavaFx Zufallsfarbe beim Button-Klick AWT, Swing, JavaFX & SWT 22
M JavaFX JavaFX in mehrere Controller AWT, Swing, JavaFX & SWT 21
R javafx erste application AWT, Swing, JavaFX & SWT 12
kneitzel JavaFX - Binding & Co AWT, Swing, JavaFX & SWT 42
S Alternative JavaFX TableView AWT, Swing, JavaFX & SWT 1
B Game of Life in JavaFX AWT, Swing, JavaFX & SWT 5
B eclipse für JavaFx setuppen AWT, Swing, JavaFX & SWT 4
N JavaFX Chioceboxen verküpfen AWT, Swing, JavaFX & SWT 0
J JavaFX Controls AWT, Swing, JavaFX & SWT 4
S JavaFx AWT, Swing, JavaFX & SWT 2
Tashtego JavaFX + Mobile AWT, Swing, JavaFX & SWT 9
JavaTalksToMe JavaFx ExekutorService Problem AWT, Swing, JavaFX & SWT 2
L JavaFX Javafx Dependency-Inversion AWT, Swing, JavaFX & SWT 19
OSchriever JavaFX JavaFX auf Raspberry Pi 4 AWT, Swing, JavaFX & SWT 6
M JavaFX Tab auswählen mit JavaFX AWT, Swing, JavaFX & SWT 9
J JavaFX JavaFX Splitpane - Zugriff auf die Controller der Elemente AWT, Swing, JavaFX & SWT 8
M Java und JavaFX 13 läuft endlich AWT, Swing, JavaFX & SWT 4
N JavaFX Logging des JavaFX Application Threads mit Log4J AWT, Swing, JavaFX & SWT 3
L Java FX JavaFX Effect Attribute ausdrucken AWT, Swing, JavaFX & SWT 1
Hatsi09 JavaFx Mediaplayer seltsames Verhalten AWT, Swing, JavaFX & SWT 0
Tashtego JavaFX - Datenübergabe zwischen Scenes AWT, Swing, JavaFX & SWT 8
Zrebna JavaFX-Projekt mit Bildern funktioniert nicht - um Hilfe wird gebeten AWT, Swing, JavaFX & SWT 14
S Kann javafx.scene.layout.VBoxBuilder nicht importieren AWT, Swing, JavaFX & SWT 3
Bluedaishi JavaFX Programm start mit zwei scenen bzw Fenster AWT, Swing, JavaFX & SWT 1
S Jogl und JavaFX AWT, Swing, JavaFX & SWT 6
Bluedaishi JavaFX ProgressBar AWT, Swing, JavaFX & SWT 10
S JavaFX JavaFX TableView scrollen färbt falsche Zeilen AWT, Swing, JavaFX & SWT 1
F JavaFX JavaFX Builden: JavaFX Runtime components are missing AWT, Swing, JavaFX & SWT 0
F JavaFX wirft zufällig Exceptions AWT, Swing, JavaFX & SWT 5
M JavaFX JAVAFX TreeItem mit Tooltip versehen AWT, Swing, JavaFX & SWT 4
techM JavaFX -> CSS AWT, Swing, JavaFX & SWT 5
J JavaFx TableView mit CheckBox AWT, Swing, JavaFX & SWT 4
J JavaFX Stoppuhr mit javafx.timeline AWT, Swing, JavaFX & SWT 2
B Problem mit JavaFX AWT, Swing, JavaFX & SWT 5
O Zukunft von Swing und JavaFX ? AWT, Swing, JavaFX & SWT 3
L JavaFX auf dem PI 4 installieren AWT, Swing, JavaFX & SWT 2
L JavaFX JavaFX Forms mit Groovy starten AWT, Swing, JavaFX & SWT 1
K JavaFX CSS Border (Verschiebung verhindern) AWT, Swing, JavaFX & SWT 4
K JavaFX Element in HBOX nach rechts verschieben AWT, Swing, JavaFX & SWT 2
M error: package javafx.scene.web is not visible import javafx.scene.web.*; AWT, Swing, JavaFX & SWT 16
J import javafx.fxml* bei JavaFX 13 geht nicht mehr AWT, Swing, JavaFX & SWT 7
F Kein JavaFX mehr im Eclipse Wizard AWT, Swing, JavaFX & SWT 1
N Ausführbare Datei aus JavaFX Projekt erstellen AWT, Swing, JavaFX & SWT 22
N Array mit JavaFX Elementen AWT, Swing, JavaFX & SWT 9
S JavaFX Exception in thread "JavaFX Application Thread" AWT, Swing, JavaFX & SWT 3
W JavaFX JavaFX - Spalten auf ganze SpreadsheetView verteilen AWT, Swing, JavaFX & SWT 16
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
S Erwaege JavaFX Einstieg AWT, Swing, JavaFX & SWT 27
O JavaFX mini Taschenrechner! AWT, Swing, JavaFX & SWT 35
L JavaFX JavaFX, FXML und Guice? AWT, Swing, JavaFX & SWT 0
B JavaFX habe mein Problem fett markiert AWT, Swing, JavaFX & SWT 2
L Javafx Controller Klasse in Maven AWT, Swing, JavaFX & SWT 7
L JavaFX JavaFX stürtzt durch einen Server#connect Exception AWT, Swing, JavaFX & SWT 3
Shallty JavaFX MenuItem (Info) Icon ändern AWT, Swing, JavaFX & SWT 7
E Aktuelle Uhrzeit auf jeder Stage anzeigen lassen (JavaFX) AWT, Swing, JavaFX & SWT 2
temi JavaFX Problem mit IntelliJ und JavaFx 11 unter XUbuntu AWT, Swing, JavaFX & SWT 3
L Java FX Problem mit Ubuntu 18 und JavaFx AWT, Swing, JavaFX & SWT 27
L JavaFX JavaScript im Javafx Webview AWT, Swing, JavaFX & SWT 4
pkm Ich kann JavaFX nicht installieren AWT, Swing, JavaFX & SWT 4
A JavaFX Daten in eine HTML-Table mit JS schreiben AWT, Swing, JavaFX & SWT 3
L JavaFX JavaFX Diagram Editor AWT, Swing, JavaFX & SWT 3
L JavaFX JavaFX Application mit Preloader sauber runterfahren AWT, Swing, JavaFX & SWT 10
K JavaFX funktioniert nicht AWT, Swing, JavaFX & SWT 2
G JavaFX Slider in JavaFX beide Seiten beschriften AWT, Swing, JavaFX & SWT 2
D JavaFX JavaFX Tutorial AWT, Swing, JavaFX & SWT 8
Bluedaishi JavaFX JFoenix TextField KeyEvent AWT, Swing, JavaFX & SWT 2
B JavaFx TreeView mit file system AWT, Swing, JavaFX & SWT 1
Bluedaishi JavaFX Button Image aus Datenbank AWT, Swing, JavaFX & SWT 13
B JavaFx Scene Builder Problem AWT, Swing, JavaFX & SWT 2
H Feste Positionen und Größen in JavaFX AWT, Swing, JavaFX & SWT 1
B JavaFX JavaFX TableView PropertyValueFactory für Werte aus HashMap AWT, Swing, JavaFX & SWT 2
B JavaFX JavaFX Table gespeichertes Wert auswählen/anvisieren AWT, Swing, JavaFX & SWT 3
FRI3ND JavaFX: Wie kann ich einer Scene Argumente übergeben? AWT, Swing, JavaFX & SWT 14
J Javafx mediaplayer mit sftp AWT, Swing, JavaFX & SWT 0
platofan23 JAVAFX zweites Fenster öffnen AWT, Swing, JavaFX & SWT 2
MoxxiManagarm JavaFX Auch ich versuche mit JavaFX warm zu werden AWT, Swing, JavaFX & SWT 9
G JavaFX JavaFX-Dialog aus einer Nicht-JavaFX-Anwendung heraus AWT, Swing, JavaFX & SWT 1
J JavaFX Wie verhindere ich das gleichzeitige Spielen von Dateien bei Mediaplayer JavaFX? AWT, Swing, JavaFX & SWT 3
H JavaFX - Label aktualisieren AWT, Swing, JavaFX & SWT 1
J Swing oder JavaFX AWT, Swing, JavaFX & SWT 21

Ähnliche Java Themen

Anzeige


Oben