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 theswt
components (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.html
does 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:
My app structure in Eclipse and generated jar structure:
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
As you can see here:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)
getResourceAsStream() looks for the file in the same package as the class from which it is called. Thus it will look for a file named "com/whatever/more/images/search_folder.png" inside the JAR, which of course won't exist, because the contents of the "resources" directory are directly put in the root of the JAR file by the JAR exporter.
Use http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream(java.lang.String) instead.
The second part: when you load the HTML will never work. You try to find a File named "resources/GoogleMap.html", but that will look outside of the JAR, in the working directory of your java program process. You should again use the previous function to load the HTML:
http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream(java.lang.String)
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.
I lost many hours on this same issue. If you created your runnable jar using the options in the "Export" functionality in Eclipse, it just won't work. At least it didn't for me. No matter what number of options I tried, nothing worked. When trying to read the resources, the resourceUrl would return null. Finally, I decided to create the runnable jar using Maven, and leave the Eclipse kind help aside. I needed to have the dependent jars in a separate lib folder. I created the runnable jar as explained in http://www.mkyong.com/maven/how-to-create-a-manifest-file-with-maven/ and the solution worked for me. Somehow, when Eclipse creates the runnable jar package, the resources cannot be read, even though they are present in the jar file. Hope this will help others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With