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

Java: Cannot load a JPG image as a resource in a JAR file

在以下代码片段中:

InputStream inputStream = 
            ClassLoader.getSystemClassLoader()
                       .getResource("pics/logo.jpg")
                       .openStream();

getResourceopenStream returns null。我该如何缓解这个问题?

您需要将 'logo.jpg' 放在 'pics' 目录中,相对于您的 CLASSPATH 的根目录,否则,ClassLoader.getResource() 将 return null,导致当您尝试打开基于它的 InputStream 时出现 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");
    }
}

它将return...

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"文件夹,会自动放入"bin/pics"文件夹),输出为...

resource is file:/home/joe/workspace/Play/bin/pics/logo.jpg
The inputStream was not null

通常资源会捆绑在您的 jar 中,因此 "logo.jpg" 应该位于 jar 根目录的“/pics”目录中。

您可能没有足够的权限,具体取决于您的应用程序是否 运行 SecurityManager 及其安全策略。

如果我没看错的话Manual

它还针对可供您使用的不同方法之间的细微差别提供了指导和解释。

java.lang.Class.getResource()java.lang.ClassLoader.getResource()对资源名称的解释不同:首先,给定名称是相对于class包的,除非它启动带有“/”的第二个名称始终为 "absolute".

这意味着当您调用 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.

两者都不是真正的 'pathes'(在文件系统上的位置意义上),它们确定相对于 CLASSPATH 的位置。 可以 是文件系统上的一个位置(如果资源不在 JAR 文件中......),但它也可以是对数据库记录的引用,作为 URI 提供,具体取决于关于所涉及的 class 个加载器的实现。

要从 *.jar 文件加载 *.jpg 图像(或任何其他图像),请使用此架构:

  1. 创建一个项目,然后将其编译到*.jar文件

    project-with-resources
    │
    ├── src
    │   └── main
    │       ├── java
    │       │   ├── . . .
    │       │   └── Project.java
    │       └── resources
    │           ├── . . .
    │           └── image1.jpg
    └── pom.xml
    
  2. 配置maven-resources-plugin(可能有几个资源文件夹)

    <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. Java代码中使用ImageIOclass读取图片到BufferedImage对象

    public class Project {
        public static void main(String[] args) throws IOException {
            BufferedImage image =
                ImageIO.read(Project.class
                    .getResourceAsStream("/resources/image1.jpg"));
        }
    }
    
  4. 必要时准备吸气剂

    public class Project {
        private BufferedImage image;
        . . .
        public BufferedImage getImage() {
            return image;
        }
    }
    
  5. 在 IDE

    中使用 Maven package 目标将项目构建到 *.jar 文件

我在 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)

St运行ge;我没有追根究底。然后我使用 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/
------------------------------------------------------------------------

从命令行:

了解您在路径方面的位置应该有助于您将资源放在正确的位置。