Tengo problemas para que IntellJ reconozca los paquetes JavaFX. Con un nuevo proyecto JavaFX, con OpenJDK 11, al intentar compilar el proyecto, IntelliJ no puede reconocer los paquetes JavaFX.
Lo he importado openjfx:javafx-base-11
del repositorio de Maven.
He analizado otras preguntas y las soluciones parecen ir desde comprobar que el código de bytes está en el nivel correcto (el mío lo está) y que el lenguaje del proyecto es correcto (el mío lo está).
¿Alguien tiene alguna idea?
Editar:
Error:
module-info.java
module-info.java
archivo en la carpeta de origen y explícitamente requerir Cuantas módulos JavaFX que se está utilizando:requires javafx.controls;
,requires javafx.graphics;
, etc.Respuestas:
Como se menciona en los comentarios, la Guía de inicio es el lugar para comenzar con Java 11 y JavaFX 11.
La clave para trabajar como lo hacía antes de Java 11 es comprender que:
Proyecto JavaFX
Si crea un proyecto predeterminado de JavaFX regular en IntelliJ (sin Maven o Gradle), le sugiero que descargue el SDK desde aquí . Tenga en cuenta que también hay jmods, pero para un proyecto no modular, se prefiere el SDK.
Estos son los sencillos pasos para ejecutar el proyecto predeterminado:
/Users/<user>/Downloads/javafx-sdk-11/lib/
. Una vez que haga esto, notará que las clases JavaFX ahora se reconocen en el editor.Antes de ejecutar el proyecto predeterminado, solo necesita agregarlos a las opciones de VM:
--module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml
correr
Maven
Si usa Maven para construir su proyecto, siga estos pasos:
Agregue las dependencias de JavaFX 11.
<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>
Una vez que haga esto, notará que las clases JavaFX ahora se reconocen en el editor.
Notará que Maven administra las dependencias requeridas por usted: agregará javafx.base y javafx.graphics para javafx.controls, pero lo más importante es que agregará el clasificador requerido según su plataforma. En mi caso, Mac.
Es por eso que sus jarras
org.openjfx:javafx-controls:11
están vacías , porque hay tres clasificadores posibles (plataformas Windows, Linux y Mac), que contienen todas las clases y la implementación nativa.En caso de que aún desee ir a su repositorio .m2 y tomar las dependencias desde allí manualmente, asegúrese de elegir la correcta (por ejemplo
.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar
)Reemplace los complementos predeterminados de Maven con los de aquí .
Ejecutar
mvn compile javafx:run
y debería funcionar.Trabajos similares también para los proyectos de Gradle, como se explica en detalle aquí .
EDITAR
La guía de introducción mencionada contiene documentación actualizada y proyectos de muestra para IntelliJ:
JavaFX 11 sin Maven / Gradle, consulte ejemplos no modulares o proyectos de muestra modulares .
JavaFX 11 con Maven, consulte ejemplos no modulares o proyectos de muestra modulares .
JavaFX 11 con Gradle, ver la muestra no modular o de muestra modulares proyectos.
fuente
/Users/<user>/Downloads/javafx-sdk-11/lib/
, observe lalib
carpeta. Eso debería contener todos los archivos javafxEl problema de que JavaFX ya no es parte de JDK 11. La siguiente solución funciona con IntelliJ (no lo he probado con NetBeans):
Agregue la biblioteca global JavaFX como dependencia:
Configuración -> Estructura del proyecto -> Módulo. En el módulo, vaya a la pestaña Dependencias y haga clic en el signo "+" agregar -> Biblioteca -> Java-> elija JavaFX de la lista y haga clic en Agregar seleccionados, luego Aplicar configuración.
Haga clic con el botón derecho en el archivo de origen (src) en su proyecto JavaFX y cree un nuevo archivo module-info.java . Dentro del archivo escribe el siguiente código:
module YourProjectName { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
Estos 2 pasos resolverán todos tus problemas con JavaFX, te lo aseguro.
Referencia: Hay un tutorial de You Tube realizado por el canal The Learn Programming, que explicará todos los detalles anteriores en solo 5 minutos. También recomiendo verlo para resolver su problema: https://www.youtube.com/watch?v=WtOgoomDewo
fuente
Ninguno de los anteriores funcionó para mí. Pasé demasiado tiempo aclarando otros errores que surgieron. Encontré que esta es la mejor y más fácil forma.
¡Esto funciona para obtener JavaFx en Jdk 11, 12 y en OpenJdk12 también!
module thisIsTheNameOfYourProject { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample; }
¡¡¡Todo me tomó solo 5 minutos !!!
fuente
Resumen rápido, puede hacer lo siguiente:
Incluya los módulos JavaFX a través de
--module-path
y me--add-modules
gusta en la respuesta de José.O
Una vez que haya agregado las bibliotecas JavaFX a su proyecto (ya sea manualmente o mediante la importación de maven / gradle), agregue el
module-info.java
archivo similar al especificado en esta respuesta. (Tenga en cuenta que esta solución hace que su aplicación sea modular, por lo que si usa otras bibliotecas, también deberá agregar declaraciones para requerir sus módulos dentro delmodule-info.java
archivo).Esta respuesta es un complemento de la respuesta de José.
La situación es esta:
IllegalAccessError
participación de un "módulo sin nombre" al intentar iniciar la aplicación.Extracto de un seguimiento de pila que genera una
IllegalAccessError
cuando se intenta ejecutar una aplicación JavaFX desde Intellij Idea: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
Bien, ahora estás un poco atascado y no tienes idea de lo que está pasando.
Lo que realmente sucedió es esto:
Entonces parece que todo debería estar bien. PERO, cuando ejecuta su aplicación, el código en los módulos JavaFX falla cuando intenta usar la reflexión para crear instancias de su clase de aplicación (cuando invoca el lanzamiento) y sus clases de controlador FXML (cuando carga FXML). Sin alguna ayuda, este uso de la reflexión puede fallar en algunos casos, generando lo oscuro
IllegalAccessError
. Esto se debe a una característica de seguridad del sistema de módulos de Java que no permite que el código de otros módulos use la reflexión en sus clases a menos que usted lo permita explícitamente (y el lanzador de aplicaciones JavaFX y FXMLLoader requieren una reflexión en su implementación actual para que funcionen correctamente).Aquí es donde algunas de las otras respuestas a esta pregunta, cuya referencia
module-info.java
, entran en escena.Entonces, tomemos un curso intensivo en módulos de Java:
La parte clave es esta:
Entonces, tal vez no desee abrir su paquete a todo el mundo, entonces puede hacer:
Entonces, terminas creando una clase src / main / java / module-info.java que se ve así:
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; }
Donde,
org.jewelsea.demo.javafx.springboot
es el nombre del paquete que contiene la clase de aplicación JavaFX y las clases de controlador JavaFX (reemplácelo con el nombre de paquete apropiado para su aplicación). Esto le dice al tiempo de ejecución de Java que está bien para las clases enjavafx.graphics
yjavafx.fxml
para invocar la reflexión sobre las clases en suorg.jewelsea.demo.javafx.springboot
paquete. Una vez hecho esto, y la aplicación se compila y se vuelve a ejecutar, las cosas funcionarán bien y elIllegalAccessError
uso de reflexión generado por JavaFX ya no ocurrirá.Pero, ¿qué pasa si no desea crear un archivo module-info.java?
Si en lugar de usar el botón Ejecutar en la barra de herramientas superior de IDE para ejecutar su clase de aplicación directamente, usted en su lugar:
javafx.run
.Run Maven Build
oDebug...
.Entonces la aplicación se ejecutará sin el
module-info.java
archivo. Supongo que esto se debe a que el complemento maven es lo suficientemente inteligente como para incluir dinámicamente algún tipo de configuración que permite que las clases JavaFX reflejen la aplicación incluso sin unmodule-info.java
archivo, aunque no sé cómo se logra esto.Para transferir esa configuración al botón Ejecutar en la barra de herramientas superior, haga clic con el botón derecho en el
javafx.run
objetivo de Maven y elija la opciónCreate Run/Debug Configuration
para el objetivo. Luego, puede elegir Ejecutar en la barra de herramientas superior para ejecutar el objetivo de Maven.fuente