IntelliJ IDEA добавить ресурсы в JAR - PullRequest
0 голосов
/ 08 июня 2018

У меня есть приложение, которое работает с ресурсами (.wav .png-файлы).Я хочу включить эти ресурсы в мой .jar, когда создаю свой проект.

Запуск приложения из IDE работает хорошо.

Как описано здесь , я создалresources-folder на том же уровне моего src-folder

Моя структура проекта:

ProjectName --        
              |
              out
              |
              resources --
              |           |
              |           sounds
              |           |
              |           images
              src --
                    |
                    ...

Как описано здесь , я пометил папку resources as Resources root.

Как описано здесь , я создал свои собственные артефакты в Project structure.Вот как они выглядят: enter image description here

Кусок кода, который работает с аудиофайлом, например:

new Media(new File("resources/sounds/login_sound.wav").toURI().toString());

Когда я пытаюсь запуститьjar через терминал, Iam получает следующую ошибку:

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$launchApplication$154(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$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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$48(GtkApplication.java:139)
    ... 1 more
Exception running application main.TheFloorIsLavaGUI

Любые советы?Спасибо

1 Ответ

0 голосов
/ 12 июня 2018

TL; DR:

Загрузить файл из пути к классам вместо файловой системы:

new Media(
  Test.class.getResource(
    "resources/sounds/login_sound.wav"
   ).toURI().toString())`

Объяснение: есть параздесь происходит:

  • Вы пытаетесь загрузить файл по пути /your/home/.../project/out/artifacts/.../resources/....Отметив resources как папку ресурсов, вы указываете IntelliJ поместить все файлы туда в корень пути к классам, как показано на скриншоте.

enter image description here

  • Он не помещает этот файл в файловую систему, но включает его в 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 принимает URI jar: 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.

...