views:

49

answers:

4

I have a static class and inside that class images are loaded into BufferedImage objects like so:

File groundTopImageFile = new File("src/main/resources/ground - grass top.png");

Now when I create an executable jar out of this using Maven2 everything works, except it doesn't find the image files. I checked the jar, and the image files have all been put in the root of the jar, so I tried using:

File groundTopImageFile = new File("ground - grass top.png");

but no success. Also in this way I can't use the same code within Eclipse anymore. Is there some way to make this work both in the jar and in Eclipse?

This is my Pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.WetWindmill</groupId>
  <artifactId>Sheepness</artifactId>
  <name>Sheepness</name>
  <version>0.0.1-SNAPSHOT</version>
  <description>Equilibrium reaction visualized with sheep :)</description>

  <dependencies>
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.4</version>
    <scope>test</scope>
  </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.5.8</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>unpack-dependencies</id>
            <phase>generate-resources</phase>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>controller.Sheepness</mainClass>
              <packageName>com.WetWindmill.Sheepness</packageName>
            </manifest>
            <manifestEntries>
              <mode>under development</mode>
              <url>www.WetWindmill.com/Projects/Sheepness/</url>
            </manifestEntries>
          </archive>
        </configuration>
      </plugin>
    </plugins>

    <resources>
      <resource>
        <directory>${basedir}/target/dependency</directory>
      </resource>
      <resource>
        <directory>${basedir}/src/main/resources</directory>
      </resource>
    </resources>
  </build>
</project>
A: 

Use the class loader getResourceAsStream() method.

duffymo
+1  A: 
URL imgURL = getClass().getResource("/ground - grass top.png");
if (imgURL != null)
{
  return new ImageIcon(imgURL, "Ground Grass Top");
}
else
{
  logger.error("Couldn't find file: " + "ground - grass top.png");
  return null;
}
Boris Pavlović
don't use src/main/resources, it won't be in the jar.
seanizer
@seanizer thanks for the remark
Boris Pavlović
@Boris "resources" won't be there either. In a maven project, anything directly inside src/main/resources will be copied to the root level of the jar.
seanizer
@Boris From the question it seems that the image is at the root of the JAR (default package). Your current code will load it from current package, not from the root/default package. Better add a leading slash to the image name or use getClass().getClassloader().getResource(String) to load the resource without leading slash (similar to the way "seanizer" proposed in his answer).
Neeme Praks
+2  A: 

Use ImageIO.read(inputStream) and read the InputStream using ClassLoader.getResourceAsStream().

Sample Code:

String resourceName = "my/picfolder/mypic.jpg";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream stream = classLoader.getResourceAsStream(resourceName);
BufferedImage bi = ImageIO.read(stream);

Note:

In my code example, my/picfolder is the relative folder hierarchy below src/main/resources.

seanizer
+2  A: 

Check out this question and its excellent answer from Jon Skeet.

Chris Knight