Java:无法在JAR文件中将JPG图像作为资源加载

3
在以下代码片段中:
InputStream inputStream = 
            ClassLoader.getSystemClassLoader()
                       .getResource("pics/logo.jpg")
                       .openStream();

无论是getResource还是openStream都返回了null。我该如何解决这个问题?

5个回答

2

*.jar文件加载*.jpg图像(或任何其他图像)使用以下模式:

  1. Create a project, which then be compiled to the *.jar file

    project-with-resources
    │
    ├── src
    │   └── main
    │       ├── java
    │       │   ├── . . .
    │       │   └── Project.java
    │       └── resources
    │           ├── . . .
    │           └── image1.jpg
    └── pom.xml
    
  2. Configure maven-resources-plugin (there may be several resources folders)

    <build>
        <defaultGoal>package</defaultGoal>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <targetPath>resources</targetPath>
            </resource>
            . . .
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
            . . .
        </plugins>
    </build>
    
  3. In Java code use ImageIO class to read pictures to the BufferedImage objects

    public class Project {
        public static void main(String[] args) throws IOException {
            BufferedImage image =
                ImageIO.read(Project.class
                    .getResourceAsStream("/resources/image1.jpg"));
        }
    }
    
  4. Prepare getters, if necessary

    public class Project {
        private BufferedImage image;
        . . .
        public BufferedImage getImage() {
            return image;
        }
    }
    
  5. Build project to the *.jar file using Maven package goal in your IDE

    Maven Lifecycle


0

根据您的应用程序是否在运行安全管理器及其安全策略下,您可能没有足够的权限。

如果我正确地阅读了手册

它还提供了有关可用方法之间微妙差异的指导和解释。


0

java.lang.Class.getResource()java.lang.ClassLoader.getResource()之间在资源名称的解释上有所不同:对于前者,给定的名称相对于类的包,除非它以'/'开头,对于后者给定的名称始终是"绝对的"。

这意味着当您调用java.lang.String.class.getResource("resource/Doc.jpg")时,它将查找/java/lang/resource/Doc.jpg,而调用java.lang.String.class.getClassLoader().getResource("resource/Doc.jpg")则尝试查找/resource/Doc.jpg

两者都不是真正的“路径”(就文件系统上的位置而言),它们确定相对于CLASSPATH的位置。这个位置可以是文件系统上的位置(如果资源不在JAR文件中...),但它也可能是一个数据库记录的引用,提供为URI,这取决于所涉及的类加载器的实现。


0

我在Netbeans中使用Ant创建了一个Java应用程序,代码如下:

public class Main {
    public static void main(String[] args){
        System.out.println(ClassLoader.getSystemClassLoader().
                getResource(".").getPath());
    }
}

当我在Netbeans中运行时,我得到了:

/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication47/build/classes/

但是如果我用命令行运行它:

java -jar "/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication50/dist/JavaApplication50.jar"

我得到了:

Exception in thread "main" java.lang.NullPointerException at Main.main(Main.java:13)

奇怪;我没有深入研究它。然后我创建了一个使用Maven的Java应用程序,也是在Netbeans中,代码完全相同,当我运行它时,无论是在Netbeans内部还是外部,我都得到了正确的答案。从Netbeans内部:

------------------------------------------------------------------------
Building JavaApplication46 1.0-SNAPSHOT
------------------------------------------------------------------------

--- exec-maven-plugin:1.5.0:exec (default-cli) @ JavaApplication46 ---
/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication46/target/classes/
------------------------------------------------------------------------

从命令行: 在此输入图像描述 了解你所处的路径位置应该能帮助你将资源放置在正确的位置。

0

您需要将'logo.jpg'文件放置在'pics'目录中,相对于您的CLASSPATH根目录。否则,当您尝试基于此打开一个InputStream时,ClassLoader.getResource() 将返回null,并导致NPE。

因此,在使用此代码的Eclipse工作区时...

import java.io.InputStream;
import java.net.URL;

public class GetResource {
    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        URL resource = classLoader.getResource("pics/logo.jpg");
        System.out.println("resource is " + resource);
        InputStream inputStream = resource.openStream();
        System.out.println("The inputStream was not null");
    }
}

它将返回...

resource is null
Exception in thread "main" java.lang.NullPointerException
    at GetResource.main(GetResource.java:9)

如果在CLASSPATH根目录下找不到"pics/logo.jpg"文件,需要在正确的位置创建"logo.jpg"文件(在这种情况下是Eclipse项目中的"src/pics"文件夹),Eclipse会自动将其放入"bin/pics"文件夹中,输出结果为...
resource is file:/home/joe/workspace/Play/bin/pics/logo.jpg
The inputStream was not null

通常资源会被打包在你的jar文件中,所以"logo.jpg"应该在jar根目录下的"/pics"目录中。

不必像那样使用类加载器。只需使用 GetResource.class.getResource() 即可。使用 ClassName.class 的方式可能会有一些类加载器版本无法解决的问题。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接