javaFX java version 11이상에서 실행하기

오류 내용

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:566)
	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:566)
	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:834)
Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.scene.control.ControlHelper (in unnamed module @0x5cfa1941) cannot access class com.sun.javafx.scene.layout.RegionHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.layout to unnamed module @0x5cfa1941
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
Error: JavaFX runtime components are missing, and are required to run this application

 

문제점 : Java 11버전 부터 기존 javaFX Package가 기본 번들에서 삭제 돼서 문제라고 한다.

그냥 java 8로 할껄... 이라고 후회 하고 있긴 한데 아무튼 상기와 같은 오류가 난다면 다음과 같이 수정을 함으로써 오류를 해결 할 수 있다.

Gradle 설정 변경

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.9'
}

플러그인을 추가 한다. 해당 플러그인 정보는 

https://github.com/openjfx/javafx-gradle-plugin

이 사이트를 참고하면 된다.

Dependency 추가

javafx {
    version = "16"
    modules = [ 'javafx.controls' ]
}

여기서 version은 

https://github.com/openjdk/jfx/tree/master/doc-files

여기서 릴리즈 노트를 보고 잘 선택하면 될 것 같다. 

16이 현시점 최신 버전이다.

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.9'
}

repositories {
    mavenCentral()
}

javafx {
    version = "16"
    modules = [ 'javafx.controls' ]
}

mainClassName = 'HelloFX'

주의 할 것은 mainClassName를 자기 프로젝트에 맞게 넣어줘야 한다는 것이다.

 

 

모듈

마지막으로 module-info.java 파일을 추가하면 된다.

module hellofx.main {
    requires javafx.controls;
    requires javafx.base;
    requires javafx.graphics;


    opens sample;
}

java에서 모듈을 본격적으로 지원하기 시작한 것은 jdk 9 버전부터 인데

javaFX이번에 쓰면서 처음으로 써봤다. 부끄럽지만...

모르는 것을 인정하고

https://www.oracle.com/corporate/features/understanding-java-9-modules.html

여기에서 내용을 참고 하면 된다.

간단히 말하자면 

  • 9버전 이전에 Application 개발 할 때는 안쓰는 Java Package도 몽땅 묶어서 build 해야했는데
  • 9버전 이후부터는 선택적인 Java Package Module를 선택해서 build 할 수 있다.

정도의 이야기로 보인다.

일단 모듈로 프로젝트를 설정하고 나면 다음과 같이 필요 Package에 대한 Module을 import해줘야 사용할 수 있다.

예를 들자면 Logger를 사용하고 싶다면

https://docs.oracle.com/javase/10/docs/api/java/util/logging/Logger.html

이 페이지에 보이듯이

java.logging module을 추가 해야한다.

 

JDK 8에서 비슷한 오류가 난다고 하시는 분이 있어서 내용 추가

어느 부분이 오류가 나실지 모르니까 jdk 8에서 javafx sample 만드는 방법 설명 합니다.

intellij 기준으로 java 프로젝트를 선택하세요. javaFX 프로젝트는 선택하시면 안됩니다. java 8 기준으로는 이제 더이상 기능 support 하지 않습니다.

위와같이 일반 프로젝트로 생성하신 후,

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

위의 코드를 붙여넣기 해주세요.

https://docs.oracle.com/javase/8/javafx/get-started-tutorial/hello_world.htm

javafx 기본 helloworld code 입니다.

상기 코드를 run해주세요.

이렇게 나오시면 정상적으로 javafx를 사용하실 준비가 되신겁니다.

쉽죠? 일반 java 실행 파일에 코드만 붙여넣으시면 됩니다. jdk 1.8쓰시는거 잊지 마시고요~

https://github.com/theyoung/javafx_sdk18_sample

근데 확실히 javafx는 java8로 개발하는게 편하긴 하네;;;; 옛날에는 swing쓴다고 그 고생을 했는데...ㅎㅎㅎ

728x90
반응형