0

I know this question was asked many times before, but I still can't manage it to work. What I want to achieve is to create jar which will load resource (packed in jar) in runtime, without broking resource loading while executing application from Eclipse.

My project structure is standard:

src/main/java
src/main/resources
src/test/java
src/test/resources

Code for load image resource:

        ClassLoader classLoader = getClass().getClassLoader();
        splashImage = ImageIO.read(new File(classLoader.getResource("img/splash.png").getFile()));

It is working fine when starting the App from the Eclipse. However, when I export the runnable jar from the Eclipse, it doesn't works.

Exported jar have /resources/img folder in it's root directory. But when the app starts, an exception is thrown:

Caused by: javax.imageio.IIOException: Can't read input file!

How it is possible to make it work from runnable jar file and when running the App from the Eclipse?

I was also trying to build jar with maven plugins, but with no luck.

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.8</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>foo.bar.App</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
MGorgon
  • 2,547
  • 23
  • 41
  • I thought generally the files in the resources directory should be placed at the root of the classpath, not in a folder called resources. How are you currently making the jar file? – thatidiotguy Jan 20 '15 at 19:05
  • In two ways: export runnable jar from eclipse and mvn install. None of them is working – MGorgon Jan 20 '15 at 19:06
  • Well the problem is that your `img` folder is under the resources folder. It should be at the top of the classpath given the code you provided. – thatidiotguy Jan 20 '15 at 19:08
  • But when I change to getResource("resources/img/splash.png") it is not working when starting the App from the Eclipse... – MGorgon Jan 20 '15 at 19:10
  • Exactly, you need to fix that. You need to make your build consistent with your development environment. – thatidiotguy Jan 20 '15 at 19:10

1 Answers1

3

You should go the following way for loading your resource:

classLoader.getResourceAsStream("/img/splash.png")

The point is that src/main/resources will automatically being copied to target/class which is the root of your classpath. This will work in Eclipse as well from the packaged jar.

An runnable jar will be created by maven via maven-assembly-plugin like this:

<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.5.3</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        [...]
</project>

After you have added this you can create the full runnable jar via:

mvn clean package

This will produce a jar file in target folder which looks like: ´whatever-1.0-SNAPSHOT-jar-with-dependencies.jar´.

What i don't understand is the usage of maven-dependency-plugin in your build?

khmarbaise
  • 92,914
  • 28
  • 189
  • 235
  • It worked with classLoader.getResourceAsStream("img/splash.png") and with few aditional configuration in maven-assembly-plugin. maven-dependency-plugin was copying libraries to external folder but it's no use now with maven-assembly-plugin. Thanks for help – MGorgon Jan 20 '15 at 19:51