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();
getResource
或 openStream
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
图像(或任何其他图像),请使用此架构:
创建一个项目,然后将其编译到*.jar
文件
project-with-resources
│
├── src
│ └── main
│ ├── java
│ │ ├── . . .
│ │ └── Project.java
│ └── resources
│ ├── . . .
│ └── image1.jpg
└── pom.xml
配置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>
在Java
代码中使用ImageIO
class读取图片到BufferedImage
对象
public class Project {
public static void main(String[] args) throws IOException {
BufferedImage image =
ImageIO.read(Project.class
.getResourceAsStream("/resources/image1.jpg"));
}
}
必要时准备吸气剂
public class Project {
private BufferedImage image;
. . .
public BufferedImage getImage() {
return image;
}
}
在 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/
------------------------------------------------------------------------
从命令行:
了解您在路径方面的位置应该有助于您将资源放在正确的位置。
在以下代码片段中:
InputStream inputStream =
ClassLoader.getSystemClassLoader()
.getResource("pics/logo.jpg")
.openStream();
getResource
或 openStream
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
图像(或任何其他图像),请使用此架构:
创建一个项目,然后将其编译到
*.jar
文件project-with-resources │ ├── src │ └── main │ ├── java │ │ ├── . . . │ │ └── Project.java │ └── resources │ ├── . . . │ └── image1.jpg └── pom.xml
配置
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>
在
Java
代码中使用ImageIO
class读取图片到BufferedImage
对象public class Project { public static void main(String[] args) throws IOException { BufferedImage image = ImageIO.read(Project.class .getResourceAsStream("/resources/image1.jpg")); } }
必要时准备吸气剂
public class Project { private BufferedImage image; . . . public BufferedImage getImage() { return image; } }
在 IDE
中使用 Mavenpackage
目标将项目构建到*.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/
------------------------------------------------------------------------
从命令行:
了解您在路径方面的位置应该有助于您将资源放在正确的位置。