运行可执行JAR时JavaFX应用无法加载图片的问题
问题现象
开发JavaFX应用时,在IntelliJ中运行完全正常,但打包成可执行JAR后,加载英雄图片时抛出空指针异常。奇怪的是应用图标能正常加载,仅英雄图片加载失败。
相关代码
创建英雄ImageView的方法
private ImageView createChampionImageView(Champion champion) { ImageView imageView = new ImageView("/images/champions/" + champion.getName().toLowerCase().replaceAll("[. ]", "") + ".png"); imageView.setFitHeight(60); imageView.setFitWidth(60); RoundCorners.setRoundedCornerImageView(imageView); return imageView; }
调用ImageView创建方法的fillChampionsPane()
public void fillChampionsPane() { if (championsPageParser.champions() == null) return; ArrayList<Champion> champions = championsPageParser.champions(); for (Champion champion : champions) { // 此方法内部会调用createChampionImageView addToTilePane(champion); } }
触发fillChampionsPane()的setChampionsParserUGG()
@FXML private void setChampionsParserUGG() { JavaLeagueBuilds.chosenPage = U_GG; JavaLeagueBuilds.getInstance().switchToLoading(); CompletableFuture.runAsync(() -> ChampionsScene.getInstance().setChampionsPageParser(new HtmlChampionsUGGParser())) .thenRun(() -> Platform.runLater(() -> { ChampionsScene.getInstance().fillChampionsPane(); JavaLeagueBuilds.getInstance().switchToChampions(); })); }
报错信息
首次运行可执行JAR时的报错:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot invoke "java.net.URL.toString()" because the return value of "java.lang.Class.getResource(String)" is null
at me.trup10ka.jlb.controllers.ChampionsScene.createChampionImageView(ChampionsScene.java:138)
at me.trup10ka.jlb.controllers.ChampionsScene.addToTilePane(ChampionsScene.java:91)
at me.trup10ka.jlb.controllers.ChampionsScene.fillChampionsPane(ChampionsScene.java:75)
at me.trup10ka.jlb.controllers.MainScene.lambda$setChampionsParserUGG$3(MainScene.java:48)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
at java.base/java.lang.Thread.run(Thread.java:833)
尝试使用getClass().getResource()后的报错:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because the return value of "java.lang.Class.getResource(String)" is null
at me.trup10ka.jlb.controllers.ChampionsScene.createChampionImageView(ChampionsScene.java:141)
at me.trup10ka.jlb.controllers.ChampionsScene.addToTilePane(ChampionsScene.java:94)
at me.trup10ka.jlb.controllers.ChampionsScene.fillChampionsPane(ChampionsScene.java:78)
at me.trup10ka.jlb.controllers.MainScene.lambda$setChampionsParserUGG$3(MainScene.java:48)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:185)
at java.base/java.lang.Thread.run(Thread.java:833)Process finished with exit code 0
已尝试的解决方法
- 使用
getClass().getResource()加载图片资源 - 使用
getResourceAsStream()加载图片资源
以上方法均未解决问题。
内容的提问来源于stack exchange,提问作者Trupka

