IntelliJ는 OpenJDK 11에서 JavaFX 11을 인식 할 수 없습니다.


82

IntellJ에서 JavaFX 패키지를 인식하는 데 문제가 있습니다. OpenJDK 11을 사용하는 새 JavaFX 프로젝트에서 프로젝트를 빌드하려고 할 때 IntelliJ는 JavaFX 패키지를 인식 할 수 없습니다.

openjfx:javafx-base-11Maven 저장소에서 가져 왔습니다 .

나는 다른 질문을 살펴 보았고 해결책은 바이트 코드가 올바른 수준인지 (내가)인지, 프로젝트 언어가 올바른지 (내가)인지 확인하는 것에서부터 다양합니다.

누구나 아이디어가 있습니까?

그림 1

그림 2

그림 3

편집하다:

오류:

여기에 이미지 설명 입력


터미널에서 컴파일하고 실행할 수 있습니까?
drowny

당신은 그것의 모듈을 필요로해야합니다module-info.java
야곱 G.

나는 당신이이 유물을 필요가 있다고 생각 : mvnrepository.com/artifact/org.openjfx/javafx/11 기본 한 것 같아요 모두 포함되어 있지 않습니다.
Jorn Vernee

@JornVernee 시도하면 오류가 발생합니다. 나는 그것으로 OP를 편집했다.
AlwaysNeedingHelp

1
누가 그 말을 잘못했을 가능성이 있습니다. 당신은 만들 필요가 module-info.java: 소스 폴더에 파일을 명시 적으로 사용하고있는 것을 둘 중 자바 FX 모듈이 필요 requires javafx.controls;, requires javafx.graphics;
야곱 G.을

답변:


128

주석에서 언급했듯이 시작 안내서 는 Java 11 및 JavaFX 11로 시작하는 곳입니다.

Java 11 이전과 같이 작동하는 핵심은 다음을 이해하는 것입니다.

  • JavaFX 11은 더 이상 JDK의 일부가 아닙니다.
  • SDK 또는 일반 종속성 (maven / gradle)으로 다른 맛으로 가져올 수 있습니다.
  • 프로젝트가 모듈식이 아니더라도 프로젝트의 모듈 경로에 포함시켜야합니다.

JavaFX 프로젝트

IntelliJ에서 (Maven 또는 Gradle없이) 일반 JavaFX 기본 프로젝트를 만드는 경우 여기 에서 SDK를 다운로드하는 것이 좋습니다 . jmod도 있지만 모듈이 아닌 프로젝트의 경우 SDK가 선호됩니다.

다음은 기본 프로젝트를 실행하는 쉬운 단계입니다.

  1. JavaFX 프로젝트 만들기
  2. JDK 11 설정 (로컬 Java 11 버전을 가리킴)
  3. JavaFX 11 SDK를 라이브러리로 추가합니다. URL은 다음과 같을 수 있습니다 /Users/<user>/Downloads/javafx-sdk-11/lib/. 이렇게하면 JavaFX 클래스가 이제 편집기에서 인식된다는 것을 알 수 있습니다.

JavaFX 11 프로젝트

  1. 기본 프로젝트를 실행하기 전에 다음을 VM 옵션에 추가하기 만하면됩니다.

    --module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml

  2. 운영

메이븐

Maven을 사용하여 프로젝트를 빌드하는 경우 다음 단계를 따르세요.

  1. JavaFX 아키 타입으로 Maven 프로젝트 만들기
  2. JDK 11 설정 (로컬 Java 11 버전을 가리킴)
  3. 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 클래스가 이제 편집기에서 인식된다는 것을 알 수 있습니다.

JavaFX 11 Maven 프로젝트

Maven이 필요한 종속성을 관리한다는 것을 알 수 있습니다. javafx.controls에 대한 javafx.base 및 javafx.graphics를 추가하지만 가장 중요한 것은 플랫폼에 따라 필수 분류 자를 추가한다는 것 입니다. 제 경우에는 Mac입니다.

이것이 모든 클래스와 기본 구현을 포함하는 세 가지 가능한 분류 자 ​​(windows, linux 및 mac 플랫폼)가 있기 때문에 jar org.openjfx:javafx-controls:11비어있는 이유 입니다.

.m2 리포지토리로 이동하여 수동으로 종속성을 가져 오려면 올바른 것을 선택했는지 확인하십시오 (예 .m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar:)

  1. 기본 maven 플러그인을 여기의 플러그인으로 바꿉니다 .

  2. 실행 mvn compile javafx:run하면 작동합니다.

여기 에 자세히 설명 된대로 Gradle 프로젝트에서도 유사한 작업이 수행 됩니다 .

편집하다

언급 된 시작 안내서에는 IntelliJ에 대한 업데이트 된 문서 및 샘플 프로젝트 가 포함되어 있습니다 .


1
경로는 같은 것입니다 /Users/<user>/Downloads/javafx-sdk-11/lib/, 통지 lib폴더에 있습니다. 즉 모든 자바 FX의 항아리를 포함해야합니다
호세 페레에게

5
모듈 경로에 문제가있는 사람은 Windows에서 다음과 같이 표시되어야합니다. --module-path = "C : \ Path \ To \ Your \ JavaFX \ lib"--add-modules = javafx.controls, javafx .fxml, javafx.base, javafx.media, javafx.graphics, javafx.swing, javafx.web "="와 그 주위의 따옴표에 주목하십시오. 다른 접근 방식은 그렇지 않았지만 이것은 나를 위해 일했습니다. 또한 -jar YourJar.jar 매개 변수는 모듈 경로 및 모듈 추가 옵션 뒤에 와야합니다.
Jalau

4
안녕하세요 @ JoséPereda. 나는 오랫동안이 가이드로 고생 해 왔지만, 당신이 작성한 것을 정확히 했더라도 IntelliJ가 내 코드를 실행하도록 만들 수는 없습니다. 여전히 "Error : java : module not found : javafx.fxml"등이 표시됩니다. 이 문제를 해결하는 데 도움이되는 비공개 채팅을 할 기회가 있습니까? 감사합니다.
Davide3i

1
@jalau 감사합니다! 따옴표가 실제로 해냈으니 답으로 써야합니다.
derfect

2
Gradle 용 샘플 프로젝트의 배포를 빌드 한 다음 실행하면 "오류 : JavaFX 런타임 구성 요소가 누락
되어이

9

JavaFX가 더 이상 JDK 11의 일부가 아닌 문제입니다. 다음 솔루션은 IntelliJ를 사용하여 작동합니다 (NetBeans에서 시도하지 않음).

  1. JavaFX Global Library를 종속성으로 추가합니다.

    설정-> 프로젝트 구조-> 모듈. 모듈에서 종속성 탭으로 이동하여 "+"기호 추가-> 라이브러리-> Java-> 목록에서 JavaFX를 선택하고 선택한 항목 추가를 클릭 한 다음 설정 적용을 클릭합니다.

  2. JavaFX 프로젝트에서 소스 파일 (src)을 마우스 오른쪽 버튼으로 클릭하고 새 module-info.java 파일을 만듭니다 . 파일 내부에 다음 코드를 작성하십시오.

    module YourProjectName { 
        requires javafx.fxml;
        requires javafx.controls;
        requires javafx.graphics;
        opens sample;
    }
    

    이 두 단계는 JavaFX와 관련된 모든 문제를 해결할 것입니다.

참고 : 프로그래밍 학습 채널에서 만든 You Tube 튜토리얼이 있으며 위의 모든 세부 사항을 단 5 분만에 설명합니다. 또한 문제 해결을 위해 시청하는 것이 좋습니다. https://www.youtube.com/watch?v=WtOgoomDewo


8

위의 어느 것도 나를 위해 일하지 않았습니다. 발생한 다른 오류를 해결하는 데 너무 많은 시간을 보냈습니다. 나는 이것이 가장 쉽고 가장 좋은 방법이라는 것을 알았습니다.

이것은 Jdk 11, 12 및 OpenJdk12에서도 JavaFx를 얻는 데 효과적입니다!

  • 비디오는 JavaFx Sdk 다운로드를 보여줍니다.
  • 글로벌 라이브러리로 설정하는 방법
  • module-info.java를 설정하십시오 (하단을 선호합니다)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}

전체가 5 분 밖에 걸리지 않았습니다!


2019.3에서 이동 한 글로벌 도서관으로 설정합니다. 이것이 지금 어디에 있는지 지적 할 수 있습니까?
Michael S.

감사합니다! 나를 위해 일했습니다 !!! 찬성!
Daniel Boehm

4

요약, 다음 중 하나를 수행 할 수 있습니다.

  1. José의 답변에 --module-pathand --add-moduleslike를 통해 JavaFX 모듈을 포함하십시오 .

    또는

  2. 프로젝트에 JavaFX 라이브러리를 추가했으면 (수동으로 또는 maven / gradle 가져 오기를 통해) module-info.java이 답변에 지정된 것과 유사한 파일을 추가하십시오 . (이 솔루션은 앱을 모듈화하므로 다른 라이브러리를 사용하는 경우 module-info.java파일 내에 모듈을 요구하는 명령문도 추가해야 합니다).


이 답변은 Jose의 답변에 대한 보충 자료입니다.

상황은 다음과 같습니다.

  1. 최신 Java 버전 (예 : 13)을 사용하고 있습니다.
  2. Maven 프로젝트로 JavaFX 애플리케이션이 있습니다.
  3. Maven 프로젝트에는 Jose의 답변에 따라 JavaFX 플러그인이 구성되고 JavaFX 종속성이 설정되어 있습니다.
  4. Application을 확장하는 메인 클래스의 소스 코드로 이동하여 마우스 오른쪽 버튼을 클릭하고 실행 해보십시오.
  5. 당신은 내려면 IllegalAccessError응용 프로그램을 실행하려고하면 "이름이 모듈을"포함.

IllegalAccessErrorIntellij Idea에서 JavaFX 앱을 실행하려고 할 때 생성되는 스택 추적에 대한 발췌 :

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

좋아, 이제 당신은 약간 갇혀 있고 무슨 일이 일어나고 있는지 전혀 모릅니다.

실제로 일어난 일은 다음과 같습니다.

  1. Maven은 애플리케이션에 대한 JavaFX 종속성을 성공적으로 다운로드 했으므로 종속성을 별도로 다운로드하거나 JavaFX SDK 또는 모듈 배포 등을 설치할 필요가 없습니다.
  2. Idea는 모듈을 프로젝트에 대한 종속성으로 성공적으로 가져 왔으므로 모든 것이 정상적으로 컴파일되고 모든 코드 완성 및 모든 것이 잘 작동합니다.

그래서 모든 것이 괜찮을 것 같습니다. 그러나 애플리케이션을 실행할 때 리플렉션을 사용하여 애플리케이션 클래스 (시작을 호출 할 때) 및 FXML 컨트롤러 클래스 (FXML을로드 할 때)의 인스턴스를 인스턴스화하려고 할 때 JavaFX 모듈의 코드가 실패합니다. 도움이 없으면 이러한 리플렉션 사용이 실패하여 모호한 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.springbootJavaFX 응용 프로그램 클래스 및 JavaFX 컨트롤러 클래스를 포함하는 패키지의 이름입니다 (이를 응용 프로그램에 적합한 패키지 이름으로 대체). 이것은 클래스에 대한 확인이에 있는지 자바 런타임 이야기 javafx.graphicsjavafx.fxml당신의 클래스에 호출 반사에 org.jewelsea.demo.javafx.springboot패키지를. 이 작업이 완료되고 응용 프로그램이 컴파일되고 다시 실행되면 제대로 작동 IllegalAccessError하고 JavaFX의 리플렉션 사용에 의해 생성 된 작업 이 더 이상 발생하지 않습니다.

하지만 module-info.java 파일을 만들고 싶지 않다면

IDE의 상단 도구 모음에있는 실행 버튼을 사용하여 애플리케이션 클래스를 직접 실행하는 대신 다음을 수행합니다.

  1. IDE 측면의 Maven 창으로 이동했습니다.
  2. javafx maven 플러그인 대상을 선택했습니다 javafx.run.
  3. 그것을 마우스 오른쪽 버튼으로 클릭하고 Run Maven Build또는을 선택하십시오 Debug....

그러면 앱이 module-info.java파일 없이 실행 됩니다. 나는 이것이 module-info.java어떻게 수행되는지 모르겠지만 maven 플러그인이 파일 없이도 JavaFX 클래스에 의해 앱이 반영되도록하는 일종의 설정을 동적으로 포함 할 수있을만큼 똑똑하기 때문이라고 생각합니다 .

해당 설정을 상단 도구 모음의 실행 버튼으로 전송하려면 javafx.runMaven 대상을 마우스 오른쪽 버튼으로 클릭 Create Run/Debug Configuration하고 대상 에 대한 옵션을 선택합니다 . 그런 다음 상단 툴바에서 Run을 선택하여 Maven 타겟을 실행할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.