intelliJ IDEA 添加资源到JAR
intelliJ IDEA add resources to JAR
我有一个正在使用资源(.wav .png- 文件)的应用程序。
我想在构建项目时将这些资源包含在我的 .jar 中。
运行 来自 IDE 的应用程序运行良好。
如 here 所述,我在 src-folder
的同一级别创建了 resources-folder
我的项目结构:
ProjectName --
|
out
|
resources --
| |
| sounds
| |
| images
src --
|
...
如所述,我已将文件夹 resources
标记为 Resources root
。
正如 here 所述,我在 Project structure
中创建了自己的工件。
这就是它们的样子:
例如处理音频文件的代码片段:
new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
当我尝试通过终端 运行 jar 时,出现以下错误:
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (File or directory not found)
完整的堆栈跟踪:
moritz@Momix:~/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar$ java -jar TheFloorIsLavaGUI.jar
Gtk-Message: 12:33:12.649: Failed to load module "canberra-gtk-module"
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (Datei oder Verzeichnis nicht gefunden)
at javafx.scene.media.Media.<init>(Media.java:407)
at managers.SoundManager.playSong(SoundManager.java:71)
at main.TheFloorIsLavaGUI.start(TheFloorIsLavaGUI.java:39)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:139)
... 1 more
Exception running application main.TheFloorIsLavaGUI
有什么建议吗?
谢谢
TL;DR:
从类路径而不是文件系统加载文件:
new Media(
Test.class.getResource(
"resources/sounds/login_sound.wav"
).toURI().toString())`
说明:这里发生了几件事:
- 您正在尝试从路径
/your/home/.../project/out/artifacts/.../resources/...
加载文件。通过将 resources
标记为资源文件夹,您告诉 IntelliJ 将所有文件放在类路径的根目录中,如屏幕截图所示。
它不会将该文件放入文件系统,而是将其包含在 jar 中
当 IDE 中的 运行 时,new File("resources/sounds/login_sound.wav").toURI()
的计算结果为 /home/moritz/IdeaProjects/TheFloorIsLavaGUI/resources/sounds/login_sound.wav
,这是项目中文件的位置。当来自 jar 的 运行 时,它计算出输出文件夹中的路径 /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav
,这不是构建放置它的位置。
现在,处理这个问题的正确方法不是从文件系统加载资源,而是从类路径加载资源。尝试 运行 IDE 和 jar 中的以下内容以查看差异
System.out.println(new File("foo.wav").toURI().toString());
System.out.println( Test.class.getResource("foo.wav").toURI().toString());
// From IDE
file:/Users/.../untitled/foo.wav
file:/ Users/.../untitled/out/production/untitled/foo.wav
// From Jar
file:/Users/.../untitled/out/artifacts/foo.wav
jar:file: /Users/.../untitled/out/artifacts/untitled_jar/untitled.jar!/foo.wav
请注意 Media
接受 jar URI:https://docs.oracle.com/javafx/2/api/javafx/scene/media/Media.html#Media%28java.lang.String%29
所以你需要做的其实很简单。
将加载 wav 从 new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
更改为 new Media(Test.class.getResource("resources/sounds/login_sound.wav").toURI().toString())
除此之外:您可能想查看 gradle 或 maven 等构建工具,而不是从 IDE.
构建
我有一个正在使用资源(.wav .png- 文件)的应用程序。 我想在构建项目时将这些资源包含在我的 .jar 中。
运行 来自 IDE 的应用程序运行良好。
如 here 所述,我在 src-folder
resources-folder
我的项目结构:
ProjectName --
|
out
|
resources --
| |
| sounds
| |
| images
src --
|
...
如resources
标记为 Resources root
。
正如 here 所述,我在 Project structure
中创建了自己的工件。
这就是它们的样子:
例如处理音频文件的代码片段:
new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
当我尝试通过终端 运行 jar 时,出现以下错误:
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (File or directory not found)
完整的堆栈跟踪:
moritz@Momix:~/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar$ java -jar TheFloorIsLavaGUI.jar
Gtk-Message: 12:33:12.649: Failed to load module "canberra-gtk-module"
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: MediaException: MEDIA_UNAVAILABLE : /home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav (Datei oder Verzeichnis nicht gefunden)
at javafx.scene.media.Media.<init>(Media.java:407)
at managers.SoundManager.playSong(SoundManager.java:71)
at main.TheFloorIsLavaGUI.start(TheFloorIsLavaGUI.java:39)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:139)
... 1 more
Exception running application main.TheFloorIsLavaGUI
有什么建议吗? 谢谢
TL;DR:
从类路径而不是文件系统加载文件:
new Media(
Test.class.getResource(
"resources/sounds/login_sound.wav"
).toURI().toString())`
说明:这里发生了几件事:
- 您正在尝试从路径
/your/home/.../project/out/artifacts/.../resources/...
加载文件。通过将resources
标记为资源文件夹,您告诉 IntelliJ 将所有文件放在类路径的根目录中,如屏幕截图所示。
它不会将该文件放入文件系统,而是将其包含在 jar 中
当 IDE 中的 运行 时,
new File("resources/sounds/login_sound.wav").toURI()
的计算结果为/home/moritz/IdeaProjects/TheFloorIsLavaGUI/resources/sounds/login_sound.wav
,这是项目中文件的位置。当来自 jar 的 运行 时,它计算出输出文件夹中的路径/home/moritz/IdeaProjects/TheFloorIsLavaGUI/out/artifacts/TheFloorIsLavaGUI_jar/resources/sounds/login_sound.wav
,这不是构建放置它的位置。
现在,处理这个问题的正确方法不是从文件系统加载资源,而是从类路径加载资源。尝试 运行 IDE 和 jar 中的以下内容以查看差异
System.out.println(new File("foo.wav").toURI().toString());
System.out.println( Test.class.getResource("foo.wav").toURI().toString());
// From IDE
file:/Users/.../untitled/foo.wav
file:/ Users/.../untitled/out/production/untitled/foo.wav
// From Jar
file:/Users/.../untitled/out/artifacts/foo.wav
jar:file: /Users/.../untitled/out/artifacts/untitled_jar/untitled.jar!/foo.wav
请注意 Media
接受 jar URI:https://docs.oracle.com/javafx/2/api/javafx/scene/media/Media.html#Media%28java.lang.String%29
所以你需要做的其实很简单。
将加载 wav 从 new Media(new File("resources/sounds/login_sound.wav").toURI().toString());
更改为 new Media(Test.class.getResource("resources/sounds/login_sound.wav").toURI().toString())
除此之外:您可能想查看 gradle 或 maven 等构建工具,而不是从 IDE.
构建