Java 应用程序启动方法中出现异常。带Maven的OpenJFX13
我尝试使用带有Maven的OpenJFX模块启动一个新项目。我遵循以下步骤:(使用Maven转到JavaFX->Modular with Maven),但在应用程序启动方法中得到了一个例外 错误:Java 应用程序启动方法中出现异常。带Maven的OpenJFX13,java,maven,javafx,openjfx,Java,Maven,Javafx,Openjfx,我尝试使用带有Maven的OpenJFX模块启动一个新项目。我遵循以下步骤:(使用Maven转到JavaFX->Modular with Maven),但在应用程序启动方法中得到了一个例外 错误: Exception in Application start method java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke
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.IllegalStateException: Location is not set.
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2459)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at org.openjfx/org.openjfx.App.loadFXML(App.java:31)
at org.openjfx/org.openjfx.App.start(App.java:20)
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)
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:174)
... 1 more
Exception running application org.openjfx.App
pom.xml:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.openjfx</groupId>
<artifactId>Oblig1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.1</version>
<configuration>
<mainClass>org.openjfx.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
primary.fxml:
secondary.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox alignment="CENTER" spacing="20.0"
xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="org.openjfx.SecondaryController">
<children>
<Label text="Secondary View" />
<Button fx:id="secondaryButton" text="Switch to Primary View"
onAction="#switchToPrimary" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
董事:
src
main
java
org.openjfx
App.java
PrimaryController.java
SecondaryController.java
resources
org.openjfx
primary.fxml
secondary.fxml
我认为这可能与FXML加载程序中的链接有关,我见过其他人也有类似的问题(),但我的directorary的resources文件夹与他们的不同。感谢您的帮助。错误消息
java.lang.IllegalStateException:未设置位置。
表示您提供给fxmloader
构造函数的URL为null
。如果找不到指定的资源,则Class.getResource(…)
方法将以静默方式返回null
发生这种情况是因为您提供给loadFXML
方法以及最终提供给App.class.getResource(…)
的资源名称不正确。您提供给Class.getResource(…)
的值是一个资源名称,其详细信息已记录在案
资源名称由“类的包的完全限定名,但转换”构成
所有句点(.)到斜杠(/)(见下文)。如果不了解buid文件夹和/或jar文件的结构,就不可能准确地知道到底出了什么问题,但可能应该是这样的
scene = new Scene(loadFXML("/org/openjfx/primary"));
由于您的FXML文件和执行此代码的类位于同一个包中,因此您也可能只需要
scene = new Scene(loadFXML("primary"));
该文件的某些相关部分:
资源、名称和上下文
资源由一个字符串标识,该字符串由一系列
子字符串,由斜杠(/)分隔,后跟资源名称。
每个子字符串必须是有效的Java标识符。资源名称为
形式为shortName或shortName.extension。shortName和
扩展必须是Java标识符
资源的名称独立于Java实现;在里面
特别是,路径分隔符始终是斜杠(/)。但是,
Java实现控制了
资源映射到文件、数据库或其他包含
实际资源
资源名称的解释是相对于类加载器的
例子类加载器类实现的方法实现了这一点
口译
资源名称
类使用的资源名称的一个常见约定是
使用类的包的完全限定名,但转换
将所有句点(.)添加到斜杠(/),并添加表单的资源名称
name.extension。支持这一点,并简化细节处理
对于系统类(getClassLoader为其返回null),类
类提供了两个方便的方法,它们调用适当的
类加载器中的方法
给定给类方法的资源名称可能具有初始起始名称
“/”将其标识为“绝对”名称。资源名称可以
不以“/”开头是“相对的”
因此,“/org.openjfx/primary”
不是有效的资源名称,因为“org.openjfx”
不是有效的Java标识符
在您的结构中,请注意,org.openjfx
不是一个文件夹,而是一个包。IDE和构建工具将把它转换为文件系统上的文件夹层次结构,最终转换为jar文件中的文件夹层次结构,包的子包结构将被文件夹和子文件夹替换。因此,在源代码结构中,您将有一个带有“org”子文件夹、“openjfx”子文件夹的“java”文件夹,以及org.openjfx
包中类的java源文件。在“resources”文件夹中,您还将有一个“org”子文件夹、“openjfx”子文件夹,以及您创建的资源文件(包括FMXL文件)
构建工具(Maven或只是您的IDE)识别特定的源文件夹;在您的案例中,这些配置包括“java”和“resources”。构建应用程序时,在构建目标中重新创建源文件夹下结构的并集;在这里,这只会产生一个org
文件夹和openjfx
子文件夹。任何Java源文件都编译为类文件;任何其他文件都只是复制的。最后,整个过程被捆绑到一个jar文件中(本质上只是一个zip归档文件)
如果您在文件系统中找到jar文件(默认情况下,Maven会将其放在名为“target”的文件夹中,该文件夹位于“src”文件夹旁边),您可以使用
jar-tf Oblig1-1.0-SNAPSHOT.jar
(我认为,Oblig1-1.0-SNAPSHOT.jar
是生成的jar文件的名称,但如果需要,显然可以对其进行调整)。您应该看到我概述的文件夹结构,输出应该包括
/org/openjfx/App.class
/org/openjfx/PrimaryController.class
/org/openjfx/SecondaryController.class
/org/openjfx/primary.fxml
/org/openjfx/secondary.fxml
(同样的结构应该存在于target/classes
文件夹下,不过文件夹的命名和位置也取决于您的Maven设置。)
顺便说一句,您真的不应该将
org.openjfx
用于您自己的包名和Maven组ID;使用特定于您自己或您的组织的内容。是的,请先修复项目结构,如果错误仍然存在,您必须添加控制器代码。看起来您的控制器缺少@FXML URL位置代码>。是的,我忘了主菜。很抱歉。还将控制器类添加到问题中,如果使用正确的jar文件名运行jar-tf
(不管它是什么;它可能在某个地方的target
文件夹下)会得到什么
package org.openjfx;
import java.io.IOException;
import javafx.fxml.FXML;
public class SecondaryController {
@FXML
private void switchToPrimary() throws IOException {
App.setRoot("PrimaryController");
}
}
src
main
java
org.openjfx
App.java
PrimaryController.java
SecondaryController.java
resources
org.openjfx
primary.fxml
secondary.fxml
scene = new Scene(loadFXML("/org/openjfx/primary"));
scene = new Scene(loadFXML("primary"));