【问题标题】:Locating resources within a jar package在 jar 包中定位资源
【发布时间】:2011-04-24 08:43:25
【问题描述】:

我有一个静态类,在该类中,图像被加载到 BufferedImage 对象中,如下所示:

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

现在,当我使用 Maven2 从中创建一个可执行 jar 时,一切正常,除了找不到图像文件。我检查了jar,图片文件都放在了jar的根目录下,所以我尝试使用:

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

但没有成功。同样通过这种方式,我不能再在 Eclipse 中使用相同的代码了。有什么方法可以让这个在 jar 和 Eclipse 中都能工作吗?

这是我的 Pom.xml 文件:

<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">
  <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>

【问题讨论】:

    标签: java resources jar


    【解决方案1】:

    使用ImageIO.read(inputStream) 并使用ClassLoader.getResourceAsStream() 读取InputStream

    示例代码:

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

    注意:

    在我的代码示例中,my/picfolder 是相对文件夹层次结构下面 src/main/resources

    【讨论】:

      【解决方案2】:
      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;
      }
      

      【讨论】:

      • 不要使用 src/main/resources,它不会在 jar 中。
      • "resources" 也不会出现。在 maven 项目中,直接在 src/main/resources 中的任何内容都将被复制到 jar 的根级别。
      • 从问题看来,图像位于 JAR 的根目录(默认包)。您当前的代码将从当前包加载它,而不是从根/默认包。最好在图像名称中添加前导斜杠或使用 getClass().getClassloader().getResource(String) 加载不带前导斜杠的资源(类似于他的回答中提出的“seanizer”方式)。
      【解决方案3】:

      使用类加载器 getResourceAsStream() 方法。

      【讨论】:

        【解决方案4】:

        不要使用“/./resources/back_img.png”,而是在 ClassLoader 中使用“resources/back_img.png”。 这是示例:

            String path = "resources/back_img.png";
            ClassLoader cl = ImageHandler.class.getClassLoader();
            URL imgURL = cl.getResource(path);
            //URL imgURL = ImageHandler.class.getResource(path);
        
            if (imgURL != null) {
                ImageIcon icon = new ImageIcon(imgURL, description);
                Image img = icon.getImage();
                Image sizedImg = img.getScaledInstance(width, height, Image.SCALE_DEFAULT);
                return new ImageIcon(sizedImg);
            } else {
                System.err.println("Couldn't find file: " + path);
                return null;
            }
        

        【讨论】:

          【解决方案5】:

          你解决了我的问题,肖恩·帕特里克·弗洛伊德。谢谢 IDE 之间似乎有所不同,但是,查看 jar 文件的结构,我们知道什么是相对路径。 就我而言,我使用了 Netbean,我的文件放在 src/my/picfolder/mypic.jpg 中(Sean 是 src/main/resources/my/picfolder/mypic.jpg),但是构建完成后,提取 jar 文件,我们将在 my/picfolder/mypic.jpg 中看到图像。所以当我们调用getResourceAsStream

          时,相对路径一定是my/picfolder/mypic.jpg

          【讨论】:

            猜你喜欢
            • 2012-01-13
            • 2013-09-01
            • 2010-10-09
            • 2013-07-07
            • 2014-10-08
            • 1970-01-01
            • 2011-11-07
            • 2014-07-26
            相关资源
            最近更新 更多