Runnable Jar не может найти ресурсы и другие библиотеки
Я создал настольное приложение, и у меня возникла проблема с моей сгенерированной runnable jar. Все отлично работает в среде Eclipse, но когда я создаю банку, он показывает только компоненты swt
(меню, вкладки и т.д.).
Месторасположение других библиотек - пустая область (библиотека для создания галереи). То же самое не отображается set ToolBar
(содержит кнопки с изображениями), GoogleMap.html
не отображается.
Как я могу правильно создать исполняемую банку, которая будет включать эти внешние источники?
Код загрузки изображения ToolBar:
folderSearchIcon = new Image(display, this.getClass().getResourceAsStream("images/search_folder.png"));
Код загрузки GoogleMap.html:
File mapFile = new File("resources/GoogleMap.html");
if(!mapFile.exists()) {
System.out.println("File doesn't exist! " + mapFile.getAbsolutePath());
return;
}
Создание исполняемой банки:
![enter image description here]()
Моя структура приложения в Eclipse и созданная структура jar:
![enter image description here]()
Сгенерированный манифест:
Manifest-Version: 1.0
Rsrc-Class-Path: ./ swt.jar commons-imaging-1.0-SNAPSHOT.jar org.eclip
se.nebula.widgets.gallery_0.5.3.201210262156.jar xmpcore.jar metadata
-extractor-2.6.3.jar
Class-Path: .
Rsrc-Main-Class: geotagger.AppInit
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Ответы
Ответ 1
Для изображения панели инструментов вам нужно добавить косую черту, т.е. вместо
this.getClass().getResourceAsStream("images/search_folder.png")
вам нужно
this.getClass().getResourceAsStream("/images/search_folder.png")
Это связано с тем, что как описано в JavaDocs, Class.getResourceAsStream
разрешает относительные пути к пакету рассматриваемого класса, поэтому, если this
является com.example.Foo
тогда getResourceAsStream("images/search_folder.png")
будет искать com/example/images/search_folder.png
внутри вашего JAR. Превращение косой черты заставит его искать images/search_folder.png
вместо этого, что вам подсказывает ваш скриншот.
Вам нужно будет использовать подобный трюк для GoogleMap.html
- вы не можете загружать элементы из JAR с помощью java.io.File
, но вы можете использовать this.getClass().getResource("/GoogleMap.html")
, чтобы получить java.net.URL
, указывающий на файл HTML внутри вашего JAR.
Ответ 2
Как вы можете видеть здесь:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getResourceAsStream (java. lang.String)
getResourceAsStream() ищет файл в том же пакете, что и класс, из которого он вызывается. Таким образом, он будет искать файл с именем "com/whatever/more/images/search_folder.png" внутри JAR, который, конечно, не будет существовать, потому что содержимое каталога "resources" напрямую помещается в корень JAR файл экспортером JAR.
Используйте http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream (java.lang.String).
Вторая часть: при загрузке HTML никогда не будет работать. Вы пытаетесь найти файл с именем "resources/GoogleMap.html", но это будет выглядеть вне JAR, в рабочем каталоге вашего Java-процесса. Вы должны снова использовать предыдущую функцию для загрузки HTML:
http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream (java.lang. String)
Ответ 3
Я потерял много часов по этой же проблеме. Если вы создали свою исполняемую банку с помощью опций в функции "Экспорт" в Eclipse, она просто не сработает. По крайней мере, это не для меня. Независимо от того, сколько вариантов я пытался, ничего не сработало. При попытке прочитать ресурсы ресурсUrl вернет значение null. Наконец, я решил создать runnable jar, используя Maven, и оставил Eclipse вид в стороне. Мне нужно было иметь зависимые баночки в отдельной папке lib. Я создал runnable jar, как описано в http://www.mkyong.com/maven/how-to-create-a-manifest-file-with-maven/, и решение сработало для меня. Так или иначе, когда Eclipse создает пакет runnable jar, ресурсы не могут быть прочитаны, даже если они присутствуют в файле jar. Надеюсь, это поможет другим.
Ответ 4
Поскольку при экспорте в исполняемую банку по существу создается один файл, файл/образ/ресурс в вашей папке ресурсов больше не может быть найден с помощью FileReader, поскольку местоположение файла в настоящее время не существует.
Переход от использования FileReader fr = new FileReader(resource_file_path)
к загрузке с помощью InputStream, InputStream is = getClass().getResourceAsStream(resource_file_path)
, а затем с помощью InputStreamReader
для фактического использования ресурса в других местах. Надеюсь, это поможет.