Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load images from a jar file

Tags:

java

I have an application that works perfectly from the Netbeans IDE, but when run from the jar file in the dist directory does not load the necessary images.

I have spent 1 1/2 days reading this and other forums, trying to find an answer, but I can't get the jar images to work.

Here he is an extract from my code:

String str = t.getText() + "100.gif";
Image img = null;

if (t != HIDDEN)
{
    ClassLoader cldr = Terrain.class.getClassLoader();
    URL url = cldr.getResource("fantasyhexwar/Images/" + str);

    if (url == null)
        JOptionPane.showMessageDialog(null, "no good");

    img = ImageIO.read(url);
    t.setImage(img);
}

I have tried many combinations of relative path, including "images/", "/images/", etc. The images are in the jar file:

 fantasyhexwar/Images/plains100.gif
 fantasyhexwar/Images/quarry60.gif
 fantasyhexwar/Images/ram80.gif
 fantasyhexwar/Images/save map40.gif
 fantasyhexwar/Images/scout80.gif
 fantasyhexwar/Images/settler80.gif
 fantasyhexwar/Images/ship80.gif

etc...

I know I am missing something fundamental, but I'm not sure what. My suspicion is that it is something to do with the manifest file or possibly class path.

Hopefully someone can point me in the right direction...

EDIT: The problem seems to be that

URL url = Terrain.class.getResource("/fantasyhexwar/Images/" + str);

returns null. The images are definitely in the JAR, and in desperation I have also tried all possible relative paths, with code like this:

ClassLoader cldr = Terrain.class.getClassLoader();
URL url = Terrain.class.getResource("/fantasyhexwar/Images/" + str);
if (url == null)
    url = cldr.getResource("/fantasyhexwar/fantasyhexwar/Images/" + str);
if (url == null)
    url = cldr.getResource("fantasyhexwar/fantasyhexwar/Images/" + str);
if (url == null)
    url = cldr.getResource("/fantasyhexwar/Images/" + str);
if (url == null)
    url = cldr.getResource("/Images/" + str);
if (url == null)
    url = cldr.getResource("Images/" + str);
if (url == null)
    url = cldr.getResource("/" + str);
if (url == null)
    url = cldr.getResource(str);
if (url == null)
    JOptionPane.showMessageDialog(null, "no good");

But none of it works when executing directly from the JAR...

When I try to run from the command line, I get:

java -cp .;FantasyHexWar.jar FantasyHexWarApp

Exception in thread "main" java.lang.NoClassDefFoundError: FantasyHexWarApp
Caused by: java.lang.ClassNotFoundException: FantasyHexWarApp
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: FantasyHexWarApp.  Program will exit.
like image 509
Fysh Avatar asked Feb 11 '11 16:02

Fysh


2 Answers

I was a little careless with my filenames. For example one file was called "save map.png", but the application was looking for "Save Map.png".

This worked fine when loading files from the drive, but when turned into a URL and loaded directly from the jar, it made all the difference.

Therefore, it seems that resource file names in a jar are case-sensitive.

like image 176
Fysh Avatar answered Sep 28 '22 11:09

Fysh


If the images are in the jar file, under fantasyhexwar/Images/.*,

Image image = getToolkit().getImage(ClassLoader.getSystemResource("fantasyhexwar/Images/plains100.gif"));

will work.

like image 25
user2767882 Avatar answered Sep 28 '22 12:09

user2767882