Intellij не может распознать javafx 11 с OpenJDK 11
Возникли проблемы при получении Intellj для распознавания пакетов javafx. В новом проекте javafx, в OpenJDK 11, при попытке построить проект Intellij не может распознать пакеты javafx.
Я импортировал openjfx:javafx-base-11
из репо мавена.
Я смотрел на другие вопросы, и решения, кажется, варьируются от проверки того, что байт-код находится на правильном уровне (у меня есть), язык проекта правильный (у меня есть).
У кого-нибудь есть идеи?
редактировать:
ошибка:
8 ответов
Как уже упоминалось в комментариях, руководство по началу работы - это то место, с которого нужно начинать с Java 11 и JavaFX 11.
Ключ к работе, как вы делали до Java 11, состоит в том, чтобы понять, что:
- JavaFX 11 больше не является частью JDK
- Вы можете получить его в разных вариантах, либо в виде SDK, либо в виде обычных зависимостей (maven/gradle).
- Вам нужно будет включить его в путь модуля вашего проекта, даже если ваш проект не является модульным.
Проект JavaFX
Если вы создадите обычный проект JavaFX по умолчанию в IntelliJ (без Maven или Gradle), я бы предложил вам скачать SDK отсюда. Обратите внимание, что также существуют jmod, но для немодульного проекта предпочтителен SDK.
Это простые шаги для запуска проекта по умолчанию:
- Создать проект JavaFX
- Установите JDK 11 (укажите вашу локальную версию Java 11 ea)
- Добавьте JavaFX 11 SDK в качестве библиотеки. URL может быть что-то вроде
/Users/<user>/Downloads/javafx-sdk-11/lib/
, Как только вы это сделаете, вы заметите, что классы JavaFX теперь распознаются в редакторе.
Перед запуском проекта по умолчанию вам просто нужно добавить их в опции VM:
--module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml
Бежать
специалист
Если вы создаете проект Maven, вы можете легко добавить необходимую зависимость:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
- Создайте проект Maven с архетипом JavaFX
- Установите JDK 11 (укажите вашу локальную версию Java 11 ea)
Добавьте зависимости 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>
Как только вы это сделаете, вы заметите, что классы JavaFX теперь распознаются в редакторе.
Вы заметите, что Maven управляет необходимыми зависимостями для вас: он добавит javafx.base и javafx.graphics для javafx.controls, но, что наиболее важно, добавит требуемый классификатор на основе вашей платформы. В моем случае Mac.
Вот почему ваши банки org.openjfx:javafx-controls:11
пусты, потому что есть три возможных классификатора (платформы Windows, Linux и Mac), которые содержат все классы и собственную реализацию.
Если вы все еще хотите пойти в репозиторий.m2 и взять оттуда зависимости вручную, убедитесь, что вы выбрали правильный (например, .m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar
)
Замените стандартные плагины maven на те, что здесь.
Бежать
mvn compile exec:java
и это должно работать.
Подобные работы также подходят для проектов Gradle, как подробно описано здесь.
Проблема в том, что Java FX больше не является частью JDK 11. Следующее решение работает с использованием IntelliJ (еще не пробовал с NetBeans):
Добавьте глобальную библиотеку JavaFX в качестве зависимости:
Настройки -> Структура проекта -> Модуль. В модуле перейдите на вкладку "Зависимости", нажмите знак "+" -> Библиотека -> Java-> выберите JavaFX из списка и нажмите "Добавить выбранное", затем "Применить настройки".
Щелкните правой кнопкой мыши исходный файл (src) в вашем проекте JavaFX и создайте новыйфайл module-info.java. Внутри файла напишите следующий код:
module YourProjectName { requires javafx.fxml; requires javafx.controls; requires javafx.graphics; opens sample;}
Эти 2 шага решат все ваши проблемы с JavaFX, уверяю вас.
Для справки: есть учебник You Tube, созданный каналом Learn Programming, который объяснит все детали выше всего за 5 минут. Я также рекомендую посмотреть его, чтобы решить вашу проблему: https://www.youtube.com/watch?v=WtOgoomDewo
Краткое резюме, вы можете сделать либо:
Включите модули JavaFX через
--module-path
а также--add-modules
как в ответе Хосе.ИЛИ
После добавления в проект библиотек JavaFX (вручную или через импорт maven/gradle) добавьте
module-info.java
файл, аналогичный указанному в этом ответе. (Обратите внимание, что это решение делает ваше приложение модульным, поэтому, если вы используете другие библиотеки, вам также нужно будет добавить операторы, чтобы требовать их модули внутриmodule-info.java
файл).
Этот ответ является дополнением к ответу Хосе.
Ситуация такая:
- Вы используете последнюю версию Java, например 13.
- У вас есть приложение JavaFX как проект Maven.
- В вашем проекте Maven у вас настроен плагин JavaFX и установлены зависимости JavaFX в соответствии с ответом Хосе.
- Вы переходите к исходному коду вашего основного класса, который расширяет Application, вы щелкаете его правой кнопкой мыши и пытаетесь запустить.
- Вы получаете
IllegalAccessError
с участием "неназванного модуля" при попытке запустить приложение.
Выдержка из трассировки стека, генерирующей IllegalAccessError
при попытке запустить приложение JavaFX из 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
Хорошо, теперь вы как бы застряли и не понимаете, что происходит.
На самом деле произошло следующее:
- Maven успешно загрузил зависимости JavaFX для вашего приложения, поэтому вам не нужно отдельно загружать зависимости, устанавливать JavaFX SDK, дистрибутив модуля или что-то подобное.
- Idea успешно импортировала модули в качестве зависимостей в ваш проект, поэтому все компилируется нормально, весь код завершается, и все работает нормально.
Так что вроде все должно быть ОК. НО, когда вы запускаете свое приложение, код в модулях JavaFX дает сбой при попытке использовать отражение для создания экземпляров вашего класса приложения (когда вы вызываете запуск) и ваших классов контроллера FXML (когда вы загружаете FXML). Без какой-либо помощи такое использование отражения в некоторых случаях может не сработать, что приведет кIllegalAccessError
. Это связано с функцией безопасности системы модуля Java, которая не позволяет коду из других модулей использовать отражение в ваших классах, если вы явно не разрешаете это (а средство запуска приложений JavaFX и FXMLLoader требуют отражения в своей текущей реализации, чтобы они функционировали правильно).
Здесь приведены некоторые другие ответы на этот вопрос, относящиеся к module-info.java
, войдите в картину.
Итак, давайте пройдем ускоренный курс по модулям Java:
Ключевая часть такова:
4.9. Открывается
Если нам нужно разрешить отражение частных типов, но мы не хотим, чтобы весь наш код был открыт, мы можем использовать директиву opens для предоставления определенных пакетов.
Но помните, что это откроет пакет для всего мира, поэтому убедитесь, что это то, что вы хотите:
module my.module { opens com.my.package; }
Итак, возможно, вы не хотите открывать свой пакет для всего мира, тогда вы можете сделать:
4.10. Открывается…
Хорошо, иногда отражение - это здорово, но мы все же хотим максимальной безопасности, которую мы можем получить от инкапсуляции. Мы можем выборочно открывать наши пакеты для предварительно утвержденного списка модулей, в этом случае с помощью директивы opens… to:
module my.module {открывает com.my.package в moduleOne, moduleTwo и т. д.; }
Итак, вы создаете класс src/main/java/module-info.java, который выглядит так:
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;
}
Где, org.jewelsea.demo.javafx.springboot
- это имя пакета, который содержит класс приложения JavaFX и классы контроллера JavaFX (замените его на соответствующее имя пакета для вашего приложения). Это сообщает среде выполнения Java, что это нормально для классов вjavafx.graphics
а также javafx.fxml
вызвать размышления о классах в вашем org.jewelsea.demo.javafx.springboot
пакет. Как только это будет сделано, приложение скомпилировано и перезапущено, все будет работать нормально, иIllegalAccessError
сгенерированный JavaFX, использование отражения больше не будет происходить.
Но что, если вы не хотите создавать файл module-info.java
Если вместо использования кнопки "Выполнить" на верхней панели инструментов IDE для непосредственного запуска класса приложения вы:
- Зашел в окно Maven в стороне IDE.
- Выберите цель плагина javafx maven
javafx.run
. - Щелкните правой кнопкой мыши и выберите либо
Run Maven Build
илиDebug...
.
Тогда приложение будет работать без module-info.java
файл. Я предполагаю, что это потому, что плагин maven достаточно умен, чтобы динамически включать какие-то настройки, которые позволяют отражать приложение в классах JavaFX даже безmodule-info.java
файл, хотя я не знаю, как это делается.
Чтобы передать этот параметр на кнопку "Выполнить" на верхней панели инструментов, щелкните правой кнопкой мыши значок javafx.run
Цель Maven и выберите вариант Create Run/DebugConfiguration
для цели. Затем вы можете просто выбрать "Выполнить" на верхней панели инструментов, чтобы выполнить цель Maven.
Ничто из вышеперечисленного не помогло мне. Я потратил слишком много времени на устранение других ошибок. Я обнаружил, что это самый простой и лучший способ.
Это работает для получения JavaFx на Jdk 11, 12 и на OpenJdk12 тоже!
- Видео показывает загрузку JavaFx Sdk
- Как установить его в качестве глобальной библиотеки
- Установите модуль-info.java (я предпочитаю нижний)
module thisIsTheNameOfYourProject {
requires javafx.fxml;
requires javafx.controls;
requires javafx.graphics;
opens sample;
}
Все это заняло у меня всего 5 минут!!!
На дворе 2021 год, и JetBrains обновила свою IDE. Другие вопросы об этом сообщении об ошибке закрыты и указывают здесь.
Error: JavaFX runtime components are missing, and are required to run this application
Если вы выполнили все остальные шаги в этих ответах (например, библиотеки, версии, соответствующие JDK и JavaFX), и вы все еще видите эту ошибку компиляции, убедитесь, что ваша конфигурация запуска/компиляции имеет
--module-path
а также
--add-modules
в качестве
VM Options
и не
Program Arguments
в IntelliJ.
- Открытым
Run/Debug Configurations
- Открытым
Modify Options
падать - Нажмите
Add VM Options
Очень хорошее объяснение можно найти на
https://edencoding.com/runtime-components-error/
в том числе
Предоставление отражающего доступа к вашему модулю
Предоставление другого доступа к вашему модулю
и всего, нам нужно, добавив к приведенным выше ответам, добавить экспорт в определение вашего модуля
module my.project {
requires javafx.fxml;
requires javafx.controls;
opens my.project to javafx.graphics;
exports my.project;
}
Azul предоставляет готовый OpenJDK 11 с JavaFX, очень удобно: https://www.azul.com/downloads/zulu/zulufx/
Примечание для модераторов: только то, что я добавил один и тот же ответ на несколько вопросов, не означает, что вопросы одинаковы
добавьте в параметры виртуальной машины (в конфигурации запуска) эту строку:
--module-path yourpathwheresdkislocated/lib --add-modules=javafx.controls,javafx.fxml
и если вы хотите запустить приложение jar с терминала, поместите это
java --module-path yourpathwheresdkislocated/lib --add-modules=javafx.controls,javafx.fxml -jar YourJar.jar