Проблема с Runnable JAR-файлом в Eclipse: невозможно создать экземпляр приложения - PullRequest
0 голосов
/ 17 апреля 2020

Я получаю ошибки при попытке создать исполняемый файл jar для моего java проекта из Eclipse. После генерации файла я запускаю

java -jar RunnableAct.jar

, который выдает мне много ошибок, таких как:

Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class application.Main$Main2
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$160(LauncherImpl.java:819)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.IllegalStateException: Location is not set.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2434)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
    at application.AppController.RedirectTo(AppController.java:142)
    at application.AppController.<init>(AppController.java:131)
    at application.Main$Main2.<init>(Main.java:46)
    ... 10 more

Мой основной класс выглядит так :

public class Main {

    public static void main(String[] args) {
        Application.launch(Main2.class, args);
    }

    public static class Main2 extends Application {

        AppController controller = new AppController();

        @Override
        public void start(Stage stage) throws Exception{

            // redirection to main controller class's main method where intro page is called
            Scene scene = new Scene(controller);
            stage.setScene(scene);
            stage.setOnCloseRequest(close -> System.exit(0));
            stage.show();

        }
    }
}

Я создал вышеупомянутый основной метод после нахождения некоторых предложений здесь, в противном случае первая версия была:

public class Main extends Application {


    public AppController controller = new AppController();


    public static void main(String[] args) {
        Application.launch(args);
    }


    @Override
    public void start(Stage stage) throws Exception{

        // redirection to main controller class's main method where intro page is called
        Scene scene = new Scene(controller);
        stage.setScene(scene);
        stage.setOnCloseRequest(close -> System.exit(0));
        stage.show();

    }
}

Когда вызывается класс AppController, он вызывает следующее Метод:

public AppController() {    
        RedirectTo("/fxml/Intro.fxml");
    }

    public void RedirectTo(String url) {        
        FXMLLoader loader = new FXMLLoader(getClass().getResource(url));        
        loader.setController(this);
        loader.setRoot(this);
        try {
            loader.load();
        } catch (IOException ex) {
        }   

    }

оба печати:

java .lang.RuntimeException: Невозможно создать приложение класса экземпляра приложения. Основной $ Main2

или с другим основным Метод:

java .lang.RuntimeException: Невозможно создать приложение класса экземпляра приложения. Основной

Я бы действительно оценил вашу помощь, спасибо!

1 Ответ

0 голосов
/ 17 апреля 2020

Предложение «Вызвано» в трассировке стека:

Caused by: java.lang.IllegalStateException: Location is not set.

указывает, что FXMLLoader не может найти файл F XML.

(По сути, здесь происходит следующее: если ресурс находится не в правильном месте, getClass().getResource(url) вернет ноль. Аргумент URL, который вы передаете конструктору FXMLLoader, устанавливается как location; при попытке загрузить F XML, если location равно нулю, выдается исключение, указывающее, что местоположение не было задано.)

Если код работает правильно в IDE , но выдает это исключение при запуске из файла JAR, то есть две распространенные возможные причины:

  1. (Не применимо здесь, но включает его для других пользователей.) Вы используете спецификацию ресурса, которая работает в обычной файловой системе, но не работает в jar-файле. Спецификации ресурсов для файла JAR должны строго соответствовать спецификации именования ресурсов Java; в частности, . и .. не допускаются в именах ресурсов. В случае с текущим вопросом "/fxml/Intro.fxml" является допустимым именем ресурса.
  2. Файл F XML не был развернут (или был развернут по неправильному пути) в файле JAR).

Хороший способ устранить эту проблему - перечислить содержимое файла JAR. Вы можете сделать это из командной строки с помощью jar -tf path/to/jar/file.jar (заменив путь на фактическое местоположение вашего jar-файла). В вашем случае /fxml/Intro.fxml ищет запись jar с именем Intro.fxml в «папке» fxml, которая должна быть в root файла jar.

Если запись отсутствует, необходимо убедиться, что сборка настроена правильно. Это зависит от вашей среды сборки, и большинство людей в наши дни будут рекомендовать такой инструмент сборки, как Maven или Gradle. Для ванильной сборки Eclipse вы должны убедиться, что папка, содержащая файл F XML, настроена как исходная папка: вы можете сделать это, щелкнув правой кнопкой мыши по проекту, выбрав «Свойства», выбрав «Java Путь сборки». "и выбрав" Источник "на вкладках в диалоговом окне.

...