Home > Software engineering >  Exception in Application constructor in JavaFX project
Exception in Application constructor in JavaFX project

Time:03-21

I migrate my old JavaFX project to JavaFX-maven. I use openjdk-17 for this. When I starts this code, I catch exception in Application constructor. Maybe I uses incorrect libriries? But then why compiler says okay when build my project?

My stack trace

Exception in Application constructor
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class classes.Main
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:891)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class classes.Main (in module com.example.javacoursework) because module com.example.javacoursework does not export classes to module javafx.graphics
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
    at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:489)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:803)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    ... 1 more

My code

package classes;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.Objects;

public class Main extends Application //Error occured in constructor!?
{
    @Override
    public void start(Stage primaryStage) throws IOException
    {
        Button button = new Button("Hello");
        Scene scene = new Scene(button);
        primaryStage.setScene(scene);
        primaryStage.show();
//        Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("../../resources/123.fxml")));
//        primaryStage.setTitle("Vote app");
//        primaryStage.setScene(new Scene(root));
//        primaryStage.setResizable(false);
//        primaryStage.show();
    }

    public static void main(String[] args)
    {
        //launch(args);
        System.out.println("Hello World!");
    }
}

If need more info, I will add to this post.

CodePudding user response:

The problem is not in your code. It's your project/launch setup. Go here and have a look at how to configure Maven correctly. https://openjfx.io/openjfx-docs/

CodePudding user response:

The JavaFX framework instantiates your Application implementation class using reflection. Code can only reflectively access code in a separate module if the necessary "permissions" are given by said module. An IllegalAccessException will be thrown if those "permissions" are not given.

Here is your root exception:

Caused by: java.lang.IllegalAccessException: class com.sun.javafx.application.LauncherImpl (in module javafx.graphics) cannot access class classes.Main (in module com.example.javacoursework) because module com.example.javacoursework does not export classes to module javafx.graphics

The fix is simple. Just add the following directive to your module-info descriptor (module-info.java):

exports classes to javafx.graphics;

Which package needs to be exported, and to which module it needs to be exported, can be determined by reading the exception message. Note you only need to use exports, instead of opens, because the JavaFX application class and its constructor are required to be public.


It may help to read: What is a stack trace, and how can I use it to debug my application errors?

  • Related