提问人:ZabbixJs 提问时间:11/3/2023 更新时间:11/3/2023 访问量:47
使用 JavaFX 依赖项运行 jar 文件时出错
Error when running jar file using JavaFX dependencies
问:
我需要创建一个带有依赖项的 jar 文件,以便我可以在没有源代码文件的情况下传输它。但是当您通过双击启动这样的 jar 时,没有任何效果,但是如果您通过命令行以 java -jar 文件.jar 格式运行它,则会出现以下错误:
Exception in thread "main" java.lang.ExceptionInInitializerError
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 org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: java.lang.NullPointerException
at uip.gui.JavaFxRun.<clinit>(JavaFxRun.java:16)
... 8 more
这是我的插件代码和启动代码:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
uip.gui.JavaFxRun
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
使用 JavaFX 的文件:
public class JavaFXClassFrame extends Application {
static Logger LOGGER;
static {
try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(JavaFXClassFrame.class.getName());
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Error ", e);
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
try {
FXMLLoader loader = new FXMLLoader();
URL xmlUrl = getClass().getResource("/fileFxml.fxml");
loader.setLocation(xmlUrl);
Parent root = loader.load();
stage.setScene(new Scene(root));
stage.show();
LOGGER.log(Level.INFO, "Success ");
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error", e);
}
}
}
public class JavaFxRun {
static Logger LOGGER;
static {
try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(JavaFxRun.class.getName());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error ", e);
}
}
public static void main(String[] args) {
JavaFXClassFrame.main(args);
}
}
JavaFX 启动文件:
public class JavaFxRun {
static Logger LOGGER;
static {
try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(JavaFxRun.class.getName());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error ", e);
}
}
public static void main(String[] args) {
JavaFXClassFrame.main(args);
}
}
答:
正如堆栈跟踪所建议的那样,该问题是由 的第 16 行引起的,但该行中还有一个先前的问题:JavaFxRun
try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
从文件系统读取文件,而不是从 JAR 读取文件;此外,如果解压缩 JAR,您会看到 的路径不是您指定的路径。FileInputStream
log.config
尝试将该行替换为
try (InputStream ins = JavaFxRun.class.getResourceAsStream("/log.config")) {
此行使用表示类的对象的 getResourceAsStream()
方法。Class
JavaFxRun
评论
LOGGER.log
log.config
似乎您在此代码的某个地方未捕获:NullPointerException
static Logger LOGGER;
static {
try (FileInputStream ins = new FileInputStream("src/main/resources/log.config")) {
LogManager.getLogManager().readConfiguration(ins);
LOGGER = Logger.getLogger(JavaFxRun.class.getName());
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error ", e);
}
}
要弄清楚这是在哪一行上发生的(即哪一行是 JavaFxRun.java 的第 16 行),但认为问题出在这条线上有点棘手:
LOGGER.log(Level.WARNING, "Error ", e);
据我所知,这是唯一可以抛出 NPE 的线。事情是这样的:
- 您尝试打开“src/main/resources/log.config”。
- 这引发了一个原因是(可能)当应用程序在 IDE 外部运行时,该文件不在预期的文件系统位置。
FileNotFoundException
- FNFE 被您的
catch (Exception e) {...}
- 您尝试通过变量调用方法...和 NPE。
LOGGER
NPE 的发生是因为没有初始化。发生这种情况是因为 FNFE 在执行 try
语句的正文之前就被抛出并捕获了。LOGGER
基本上,您不能使用日志记录系统来记录无法配置日志记录系统的情况。你能做的最好的事情就是将错误消息直接写入标准错误,并希望它能到达有用的地方。
注意:在这种情况下,替换为可以实际找到文件(或资源)的内容将修复触发 NPE 的 FNFE。但这还不是结束。如果(比如说)资源丢失了怎么办?找到的文件或资源是什么,但它包含乱码日志记录配置。您仍将获得 NPE!new FileInputStream("src/main/resources/log.config")
基本上,这种说法是错误的。它永远不会像你预期的那样工作。如果你到达那条线并尝试使用 ,NPE 是不可避免的。LOGGER.log(Level.WARNING, "Error ", e);
LOGGER
评论
LOGGER.log
getResourceAsStream()
null
评论