Ich habe Probleme, IntellJ dazu zu bringen, JavaFX-Pakete zu erkennen. Bei einem neuen JavaFX-Projekt mit OpenJDK 11 kann IntelliJ beim Versuch, das Projekt zu erstellen, die JavaFX-Pakete nicht erkennen.
Ich habe openjfx:javafx-base-11
aus dem Maven Repo importiert .
Ich habe mir andere Fragen angesehen und die Lösungen scheinen von der Überprüfung zu reichen, ob der Bytecode auf der richtigen Ebene ist (meiner ist) und ob die Projektsprache korrekt ist (meiner ist).
Hat jemand irgendwelche Ideen?
Bearbeiten:
Error:
module-info.java
module-info.java
Datei in Ihrem Quellordner und explizit erfordern je nachdem , was JavaFX - Module , die Sie verwenden:requires javafx.controls;
,requires javafx.graphics;
etc.Antworten:
Wie in den Kommentaren erwähnt, ist das Starthandbuch der Ausgangspunkt für Java 11 und JavaFX 11.
Der Schlüssel, um wie vor Java 11 zu arbeiten, besteht darin, Folgendes zu verstehen:
JavaFX-Projekt
Wenn Sie in IntelliJ ein reguläres JavaFX-Standardprojekt erstellen (ohne Maven oder Gradle), empfehlen wir Ihnen, das SDK hier herunterzuladen . Beachten Sie, dass es auch jmods gibt, aber für ein nicht modulares Projekt wird das SDK bevorzugt.
Dies sind die einfachen Schritte zum Ausführen des Standardprojekts:
/Users/<user>/Downloads/javafx-sdk-11/lib/
. Sobald Sie dies tun, werden Sie feststellen, dass die JavaFX-Klassen jetzt im Editor erkannt werden.Bevor Sie das Standardprojekt ausführen, müssen Sie diese nur zu den VM-Optionen hinzufügen:
--module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml
Lauf
Maven
Wenn Sie Ihr Projekt mit Maven erstellen, gehen Sie folgendermaßen vor:
Fügen Sie die JavaFX 11-Abhängigkeiten hinzu.
<dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>11</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>11</version> </dependency> </dependencies>
Sobald Sie dies tun, werden Sie feststellen, dass die JavaFX-Klassen jetzt im Editor erkannt werden.
Sie werden feststellen, dass Maven die erforderlichen Abhängigkeiten für Sie verwaltet: Es werden javafx.base und javafx.graphics für javafx.controls hinzugefügt. Am wichtigsten ist jedoch, dass der erforderliche Klassifizierer basierend auf Ihrer Plattform hinzugefügt wird . In meinem Fall Mac.
Deshalb ist Ihre Gläser
org.openjfx:javafx-controls:11
sind leer , denn es gibt drei mögliche Klassifizierer (Windows, Linux und Mac - Plattformen), die alle die Klassen und die native Implementierung enthalten.Wenn Sie dennoch zu Ihrem .m2-Repo gehen und die Abhängigkeiten von dort manuell übernehmen möchten, stellen Sie sicher, dass Sie die richtige auswählen (zum Beispiel
.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar
).Ersetzen Sie die Standard-Maven-Plugins durch die von hier .
Führen Sie
mvn compile javafx:run
, und es sollte funktionieren.Ähnliche Arbeiten auch für Gradle-Projekte, wie hier ausführlich erläutert .
BEARBEITEN
Das erwähnte Handbuch Erste Schritte enthält aktualisierte Dokumentation und Beispielprojekte für IntelliJ:
JavaFX 11 ohne Maven / Gradle, siehe nicht modulares Beispiel oder modulare Beispielprojekte .
JavaFX 11 mit Maven, siehe nicht modulares Beispiel oder modulare Beispielprojekte .
JavaFX 11 mit Gradle, siehe nicht modulares Beispiel oder modulare Beispielprojekte .
quelle
/Users/<user>/Downloads/javafx-sdk-11/lib/
, beachten Sie denlib
Ordner. Das sollte alle Javafx-Gläser enthaltenDas Problem, dass JavaFX nicht mehr Teil von JDK 11 ist. Die folgende Lösung funktioniert mit IntelliJ (habe es nicht mit NetBeans versucht):
Fügen Sie die JavaFX Global Library als Abhängigkeit hinzu:
Einstellungen -> Projektstruktur -> Modul. Gehen Sie im Modul zur Registerkarte Abhängigkeiten und klicken Sie auf das Zeichen "+" hinzufügen -> Bibliothek -> Java-> wählen Sie JavaFX aus der Liste aus und klicken Sie auf Ausgewählte hinzufügen und dann auf Einstellungen anwenden.
Klicken Sie in Ihrem JavaFX-Projekt mit der rechten Maustaste auf die Quelldatei (src) und erstellen Sie eine neue Datei module-info.java . Schreiben Sie in die Datei den folgenden Code:
module YourProjectName { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
Diese beiden Schritte lösen alle Ihre Probleme mit JavaFX, das versichere ich Ihnen.
Referenz: Es gibt ein You Tube-Tutorial von The Learn Programming Channel, das alle oben genannten Details in nur 5 Minuten erklärt. Ich empfehle außerdem, es anzusehen, um Ihr Problem zu lösen: https://www.youtube.com/watch?v=WtOgoomDewo
quelle
Keines der oben genannten hat bei mir funktioniert. Ich habe zu viel Zeit damit verbracht, andere aufgetretene Fehler zu beseitigen. Ich fand das der einfachste und beste Weg.
Dies funktioniert auch für JavaFx auf Jdk 11, 12 und OpenJdk12!
module thisIsTheNameOfYourProject { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
Das Ganze hat mich nur 5 Minuten gekostet !!!
quelle
Kurze Zusammenfassung, Sie können entweder:
Fügen Sie die JavaFX-Module über
--module-path
und--add-modules
wie in Josés Antwort ein.ODER
Wenn Sie Ihrem Projekt JavaFX-Bibliotheken hinzugefügt haben (entweder manuell oder über den Maven / Gradle-Import), fügen Sie die
module-info.java
Datei hinzu, die der in dieser Antwort angegebenen ähnelt. (Beachten Sie, dass diese Lösung Ihre App modular macht. Wenn Sie also andere Bibliotheken verwenden, müssen Sie auch Anweisungen hinzufügen, damit deren Module in dermodule-info.java
Datei enthalten sind.)Diese Antwort ist eine Ergänzung zu Joses Antwort.
Die Situation ist folgende:
IllegalAccessError
ein „unnamed Modul“ beteiligt , wenn sie versuchen , die App zu starten.Auszug aus einem Stack-Trace, der
IllegalAccessError
beim Versuch, eine JavaFX-App über Intellij Idea auszuführen, eine generiert:Exception in Application start method java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051) Caused by: java.lang.RuntimeException: Exception in Application start method at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195) at java.base/java.lang.Thread.run(Thread.java:830) Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x45069d0e at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38) at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056) at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13) at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) at java.base/java.security.AccessController.doPrivileged(AccessController.java:391) at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) Exception running application org.jewelsea.demo.javafx.springboot.Main
OK, jetzt steckst du irgendwie fest und hast keine Ahnung, was los ist.
Was tatsächlich passiert ist, ist Folgendes:
Es scheint also, dass alles in Ordnung sein sollte. ABER, wenn Sie Ihre Anwendung ausführen, schlägt der Code in den JavaFX-Modulen fehl, wenn Sie versuchen, mithilfe von Reflection Instanzen Ihrer Anwendungsklasse (beim Aufrufen des Starts) und Ihrer FXML-Controller-Klassen (beim Laden von FXML) zu instanziieren. Ohne Hilfe kann diese Verwendung der Reflexion in einigen Fällen fehlschlagen und die Dunkelheit erzeugen
IllegalAccessError
. Dies liegt an einer Sicherheitsfunktion des Java-Modulsystems, die es Code von anderen Modulen nicht erlaubt, Reflektion für Ihre Klassen zu verwenden, es sei denn, Sie erlauben dies ausdrücklich (und der JavaFX-Anwendungsstarter und FXMLLoader erfordern beide eine Reflektion in ihrer aktuellen Implementierung, damit sie funktionieren korrekt).Hier kommen einige der anderen Antworten auf diese Frage
module-info.java
ins Spiel.Nehmen wir also an einem Crashkurs in Java-Modulen teil:
Der Schlüsselteil ist folgender:
Vielleicht möchten Sie Ihr Paket nicht für die ganze Welt öffnen, dann können Sie Folgendes tun:
Am Ende erstellen Sie also eine src / main / java / module-info.java-Klasse, die folgendermaßen aussieht:
module org.jewelsea.demo.javafx.springboot { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml; }
Wobei
org.jewelsea.demo.javafx.springboot
der Name des Pakets ist, das die Klassen JavaFX Application und JavaFX Controller enthält (ersetzen Sie diesen durch den entsprechenden Paketnamen für Ihre Anwendung). Dies teilt der Java-Laufzeit mit, dass es für Klassen injavafx.graphics
undjavafx.fxml
in Ordnung ist, die Klassen in Ihremorg.jewelsea.demo.javafx.springboot
Paket zu reflektieren . Sobald dies erledigt ist und die Anwendung kompiliert und erneut ausgeführt wurde, funktionieren die Dinge einwandfrei und dieIllegalAccessError
durch JavaFX generierte Verwendung von Reflection tritt nicht mehr auf.Was aber, wenn Sie keine Datei module-info.java erstellen möchten?
Wenn Sie anstelle der Schaltfläche Ausführen in der oberen Symbolleiste der IDE Ihre Anwendungsklasse direkt ausführen möchten, gehen Sie stattdessen wie folgt vor:
javafx.run
.Run Maven Build
oderDebug...
.Dann wird die App ohne die
module-info.java
Datei ausgeführt. Ich denke, das liegt daran, dass das Maven-Plugin intelligent genug ist, um dynamisch einige Einstellungen aufzunehmen, mit denen die App auch ohnemodule-info.java
Datei von den JavaFX-Klassen reflektiert werden kann, obwohl ich nicht weiß, wie dies erreicht wird.Um diese Einstellung auf die Schaltfläche Ausführen in der oberen Symbolleiste zu übertragen, klicken Sie mit der rechten Maustaste auf das
javafx.run
Maven-Ziel und wählen Sie die OptionCreate Run/Debug Configuration
für das Ziel. Dann können Sie einfach in der oberen Symbolleiste Ausführen auswählen, um das Maven-Ziel auszuführen.quelle