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 для фактического использования ресурса в других местах. Надеюсь, это поможет.