3

I am trying to export my project as a runnable jar. I can do it using Eclipse feature or Maven, no matter.

My program is using some relatives path to load resources (images). I specify the path in eclipse from the project base directory. Everything works fine when executing my program with Eclipse, but when I generate a jar and try to run it, there is nothing and it imediatly quit. I think my program can't access my resources when executing from jar.

I have the following arborescence:

src/main/java/nantel/java/boulder/views/MainWindow.java
src/main/resources/logo.png

I was using the following to load my picture:

panel.add(new JLabel(new ImageIcon("./src/main/resources/logo.png")));

As I said, it's ok when I launch it from Eclipse but not from executable jar... I think it's a problem of classpath.

I have tried to use the following instead:

panel.add(new JLabel(new ImageIcon(getClass().getResource("logo.png"))));

I have tried different paths, but I always get a NullPointerException (the getResource method always return null).

Have you any idea about how I can get my resources using the getClass().getResource() method and if it will help me running an executable jar?

I also give you my maven build configuration..

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>nantel.java.boulder.Launcher</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

When I extract the JAR archive, I can see the arborescence is not the same as in my Eclipse project. There is not longer src/main/resources or src/main/java but every thing are directly put as:

./logo.png
./nantel/java/boulder/...

And it seems logic my application can not find the resource the given relative path ("./src/main/resources/logo.png"). Any idea?

----- EDIT

The NullPointerException has been solved in the Eclipse launch, but I still have an error when trying to execute the jar.

hiveship:Desktop Maelig$ java -jar test.jar 
@@@ default folder path -> file:/Users/Maelig/Desktop/test.jar!/levels/
Exception in thread "main" java.lang.NullPointerException

Why is the path like this ?? In my code:

    public static final String DEFAULT_FOLDER_PATH = SpriteRepository.class.getResource("/levels/").getPath();
hiveship
  • 308
  • 2
  • 7
  • 21
  • Have you tried remove the leading `.` from those classpaths? – Sam Estep Jun 28 '15 at 12:13
  • Yes and if I don't specify the './' my resource is not loaded in Eclipse (and not the in the executable jar). – hiveship Jun 28 '15 at 12:17
  • @MaëligNANTEL: Hopefully this thread regarding, how to [add images to java Project](http://stackoverflow.com/a/9866659/1057230), will serve some purpose, in your endeavour :-) – nIcE cOw Jun 28 '15 at 12:38

1 Answers1

3

Try adding a leading / before the path:

panel.add(new JLabel(new ImageIcon(getClass().getResource("/logo.png"))));

If you don't put a forward slash, the absolute name of the given resource would be:

modified_package_name/resource_name 

where the modified_package_name is the package name of the class object (i.e. getClass()) with '/' substituted for '.'.

You can also use Class#getResourceAsStream() which returns an InputStream, then convert to a byte array and pass it to the ImageIcon constructor:

InputStream input = getClass().getResourceAsStream("/logo.png");
byte[] bytes = IOUtils.toByteArray(input);  // using commons-io library
panel.add(new JLabel(new ImageIcon(bytes)));
M A
  • 71,713
  • 13
  • 134
  • 174
  • Thanks you, it solved my NullPointerException when executing my application from Eclipse ! But I still have a problem to start my app from an executable jar :( – hiveship Jun 28 '15 at 12:46
  • 1
    @MaëligNANTEL The path is the URL of the file in the Jar file. You can also use `getResourceAsStream` to return an `InputStream` instead of a `URL`. See my updated answer. – M A Jun 28 '15 at 13:27
  • @manouti Hi, I have a different scenario with regards to output. Both ClassLoader.getResource(subdir/readme.txt) and Class.getResource(/subdir/readme.txt) giving me SUCCESS when run in Eclipse. But both of them returning NULL when run from a executable jar on windows machine. Is there something I'm missing here? – Suresh Feb 08 '18 at 14:12