Runnable Jar cannot find Resources and Other Libraries

unixhead picture unixhead · Dec 21, 2012 · Viewed 17.3k times · Source

I created a desktop app and I have run into a problem with my generated runnable jar. Everything works fine in the Eclipse environment, but when I generate the jar it only shows theswtcomponents (menu, tabs, etc..). The other libraries location is a blank area (library to generate gallery). The same does not appearset ToolBar(containing buttons with images),GoogleMap.htmldoes not appear.

How can I correctly generate an executable jar that will include these external sources?

ToolBar image loading code :

folderSearchIcon = new Image(display, this.getClass().getResourceAsStream("images/search_folder.png"));

GoogleMap.html loading code :

File mapFile = new File("resources/GoogleMap.html");        
if(!mapFile.exists()) {
    System.out.println("File doesn't exist! " + mapFile.getAbsolutePath()); 
    return;
}

Generating runnable jar:

enter image description here

My app structure in Eclipse and generated jar structure:

enter image description here

Generated manifest :

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

Answer

Ian Roberts picture Ian Roberts · Dec 21, 2012

For the toolbar image you need to add a slash, i.e. instead of

this.getClass().getResourceAsStream("images/search_folder.png")

you need

this.getClass().getResourceAsStream("/images/search_folder.png")

This is because, as explained in the JavaDocs, Class.getResourceAsStream resolves relative paths against the package of the class in question, so if this is a com.example.Foo then getResourceAsStream("images/search_folder.png") would look for com/example/images/search_folder.png inside your JAR. Prepending the slash would make it look for images/search_folder.png instead, which is what your screenshot suggests you need.

You will need to use a similar trick for the GoogleMap.html - you can't load items from inside a JAR using java.io.File, but you could use this.getClass().getResource("/GoogleMap.html") to get a java.net.URL pointing to the HTML file inside your JAR.