JavaFX и maven: NullPointerException: требуется место
Я пытаюсь настроить Maven на JavaFX. Несмотря на то, что я не был ознакомлен с Maven и JavaFX, я не ожидал, что это будет проблемой. Мои знания Java довольно прочные (включая Swing), и не ожидали, что у них возникнут трудности с настройкой.
Я начал с проекта JavaFX, предоставленного IntelliJ 13.0 Community Edition. Код в моем основном классе относительно невелик:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
//getClass().getResource("../../resources/sample.fxml");
Parent root = FXMLLoader.load(getClass().getResource("../sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
и мой pom.xml
тоже не слишком большой:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>JavaFXDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<organization>
<name>RubberDucky</name>
</organization>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>2.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<mainClass>sample.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>javafx</artifactId>
<version>2.2</version>
<systemPath>${java.home}/lib/jfxrt.jar</systemPath>
<scope>system</scope>
</dependency>
</dependencies>
</project>
Я использую JavaFX Maven Plugin для создания приложения. После запуска mvn clean jfx:jar
все кажется прекрасным, все сборки успешны. Но когда я пытаюсь запустить приложение, я получаю следующую ошибку:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.javafx.main.Main.launchApp(Main.java:698)
at com.javafx.main.Main.main(Main.java:871)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown So
urce)
at com.sun.javafx.application.LauncherImpl.access$000(Unknown Source)
at com.sun.javafx.application.LauncherImpl$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.load(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at javafx.fxml.FXMLLoader.load(Unknown Source)
at sample.Main.start(Main.java:15)
at com.sun.javafx.application.LauncherImpl$5.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$5.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
... 1 more
После некоторой грубой отладки проблема кажется на пути, с которого я загружаю свои файлы. После жесткого кодирования sample.fxml
на место на моем жестком диске приложение запускается без каких-либо проблем. То же самое касается текущей настройки (см. Выше) при запуске приложения из IntelliJ.
Я чувствую, что исчерпал каждый ресурс (включая StackOverflow, некоторые очень похожие ошибки), но я просто не могу понять, что именно не так.
Ответы
Ответ 1
Убедитесь, что ваш sample.fxml
находится в каталоге src/main/resources/
(или в подкаталоге). Затем вы можете получить доступ к файлу следующим образом:
Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("sample.fxml"));
Объяснение:
На этапе компиляции все ресурсы и классы копируются в target/classes/
. Таким образом, ваш файл fxml находится в этом каталоге и ваш класс в подкаталоге относительно его имени пакета. Если вы вызываете getClass().getResource("sample.fxml");
, файл будет искать по отношению к файлу класса, который будет в этом каталоге: target/classes/sample/
.
Вызов .getResource()
в classloader устанавливает относительный путь поиска к target/classes/
, и поэтому ваш файл будет найден.
P.S. Вы также можете написать:
Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
Ответ 2
Как уже объяснил @Absurd-Mind, maven не будет копировать файлы ресурсов (например, fxml), которые находятся в каталоге src
.
Если вы хотите сохранить файлы fxml
помимо исходных файлов java, вы можете использовать плагин ресурсов maven для их копирования:
<build>
...
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/java</directory>
<includes>
<include>**/*.fxml</include>
</includes>
</resource>
</resources>
...
</build>
Ответ 3
У меня была такая же проблема с Intelij и Gradle.
Шаги, чтобы исправить:
1. Переместить файл
sample.fxml
к пути
\SRC\основные\ресурсы\FXML
- Задайте путь к этому файлу:
Родительский корень = FXMLLoader.load(getClass(). GetResource ("/fxml/sample.fxml"));
Ответ 4
Для тех, кто использует gradle, поскольку их система сборки добавляет это в ваш файл build.gradle
:
sourceSets.main.resources {
srcDirs = ["src/main/java"]; //assume that your java classes are inside this path
exclude "**/*.java"
}
Затем очистите и перестройте проект.
И что он будет делать? Если у вас есть view.fxml
внутри вашего пакета com.example.myfxapp
, после создания проекта он будет экспортироваться в <build dir>/resources/com/example/myfxapp/view.fxml
Ответ 5
Для меня я позаботился о следующих вещах -
-
Убедитесь, что файл fxml размещен там, где находится основной класс. И затем загрузите его с помощью этого - (В моем случае, TechJFX.fxml - это файл)
FXMLLoader loader = new FXMLLoader(getClass().getResource("TechJFX.fxml"));
-
Добавить opencv - *. jar в папку проекта (в моем случае opencv-300.jar)
-
Добавьте банку в путь сборки, используя
Щелкните правой кнопкой мыши папку проекта → Путь сборки → Настроить путь сборки → вкладка "Библиотеки" → Добавить внешние JARS и найти банку
Кроме того, в разделе Order and Export → Tick opencv-300.jar и JRE System Library (если еще не отмечено)
-
Скопируйте opencv_java *.dll(в моем случае opencv_java300.dll) в то место, где вы находитесь в папке проекта.
-
Добавьте следующий класс в ваш основной класс
static{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
-
Готово.
Надеюсь, это поможет кому-то столкнуться с подобной проблемой.