java jar - 如何指定应将资源保存在何处?
java jar - how do I specify where resources should be saved?
这是我当前的pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hu.elte.inf</groupId>
<artifactId>ThesisMVN</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>main/Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
我需要维护我的资源文件夹(及其子文件夹)的结构,因为目前将它们从资源文件夹中取出,所以我的游戏无法启动,因为它找不到所有纹理。
项目内的资源结构
jar-ed 资源结构(注意 jar 中只有一个 effects
文件夹,它将图像放在 class 文件旁边)
这是我当前加载图片的方式
public class ResourceLoader {
public static Image getResource(String path){
Image img=null;
try{
img = ImageIO.read(new File(path));
}
catch(IOException e) {
System.err.println("File not found("+path+')');
e.printStackTrace();
}
return img;
}
}
传递给 getResource 的 path
是从我设置所有图像路径的枚举中获取的,如下所示:
...
BULLET("src/main/resources/bullet.png"),
BULLET_GREY("src/main/resources/bullet_grey.png"),
...
AOE_SLOW("src/main/resources/effects/aoeSlow.png"),
AOE_DISARM("src/main/resources/effects/aoeDisarm.png"),
...
我想我应该删除 src/main/resources
前缀,但是一旦项目被破坏,我就只能访问图像。
这可能是我的设置中不可靠的部分,但我目前正在将每个加载的图像存储在名为 GameStateData
的 class 中。每当我需要创建一个新的 Sprite
时,我只是从那里获取已经加载的图像,所以我只需要在启动游戏时加载每个图像一次。
I need the structure of my resources folder (and its subfolders) maintained
它是维护的。资源文件夹中的每个文件 和目录 都已按照标准目录布局的要求直接复制到 jar 中。
问题出在您的设置上:在 'dev time' 时,您似乎试图从 resources/items/someItem.png
加载,但当您的应用程序出现问题时,这不起作用。有两种明显的方式可以发生这种情况;
你不明白原因
您正在尝试使用 new FileInputStream
、new File
,或者试图将这些 作为文件 加载。这行不通,也行不通,对目录结构进行再多的调整也无法使其发挥作用。在 java 中,file 表示 file - jarfile 中的 png 条目本身不是文件。
加载此类资源的方式始终是这种策略:
选择一个 class 即 'source location' - 例如,您正在寻找的资源将是 where-ever JVM 找到了这个 class 文件。通常,您可以在整个应用程序中选择任何 class;这仅在您使用模块化 class 加载系统时才有意义。如果您不知道那是什么意思,那么您就没有使用这些。
调用 MyContextClass.class.getResource(resourceKey)
获得一个 URL 对象,然后你可以将它传递给任何 API 允许你这样做的对象(还有很多 APIs 做,特别是包括 swing 自己的 ImageIcon
)。或者,使用 try (var in = MyContextClass.class.getResourceAsStream(resourceKey) { /* use resource here */ }
- 如果所讨论的 API 没有采用 URL 的重载但确实有采用 InputStream 的重载,则可以使用此方法。直接看内容也可以用这个
resourceKey
有两种口味。 "foo/bar.png"
解析相对于 package 上下文 class 所在的路径。如果你有 package com.foo; public class Bar {}
那么在部署的某个地方有 com/foo/Bar.class
。例如,在 jar 文件中,或在 bin
目录中。如果您随后写入 Bar.class.getResource("baz/quux.png")
,并且 Bar.class 位于该 jar 文件中,那么系统将在同一个 jar 文件中查找 com/foo/baz/quux.png
。或者,包括一个前导斜杠:"/foo/bar.png"
会在同一个 jar 中查找,但对于 foo/bar.png
.
这就是您要做的全部。构建系统和 IDEs 确保您将图像准确地放在现在的位置(在 resources
文件夹中),您 不 包含 resources
在您的部署密钥中(出于同样的原因,您在 src/main/java/com/foo/MyApp.class
中拥有 java 源文件,并且您不包括 src
、main
或 java
在您完全限定的 class 名称中。它只是 com.foo.MyApp
,而不是 main.java.com.foo.MyApp
。resources
不再是它的一部分,就像 java
是它的一部分一样您的 class 个名称。如果它不起作用,则说明它们配置错误。
您的设置不可靠
您可能一直在偷偷摸摸,例如使用插件系统,您可以自己直接在文件系统上检查某些文件,-或-通过 ContextClass.class.getResource
加载,或者您一直在搞乱 IDE 的 maven 插件识别资源目录的方式,或者您一直在手动设置 IDE 项目(而不是使用其 Maven 集成)并将 src/main
标记为源目录(而不是 src/main/java
和 src/main/resources
) .设置坏了;解决这个问题(不要 'fix' 它试图保持 resources
左右)。
这是我当前的pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>hu.elte.inf</groupId>
<artifactId>ThesisMVN</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>main/Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
我需要维护我的资源文件夹(及其子文件夹)的结构,因为目前将它们从资源文件夹中取出,所以我的游戏无法启动,因为它找不到所有纹理。
项目内的资源结构
jar-ed 资源结构(注意 jar 中只有一个 effects
文件夹,它将图像放在 class 文件旁边)
这是我当前加载图片的方式
public class ResourceLoader {
public static Image getResource(String path){
Image img=null;
try{
img = ImageIO.read(new File(path));
}
catch(IOException e) {
System.err.println("File not found("+path+')');
e.printStackTrace();
}
return img;
}
}
传递给 getResource 的 path
是从我设置所有图像路径的枚举中获取的,如下所示:
...
BULLET("src/main/resources/bullet.png"),
BULLET_GREY("src/main/resources/bullet_grey.png"),
...
AOE_SLOW("src/main/resources/effects/aoeSlow.png"),
AOE_DISARM("src/main/resources/effects/aoeDisarm.png"),
...
我想我应该删除 src/main/resources
前缀,但是一旦项目被破坏,我就只能访问图像。
这可能是我的设置中不可靠的部分,但我目前正在将每个加载的图像存储在名为 GameStateData
的 class 中。每当我需要创建一个新的 Sprite
时,我只是从那里获取已经加载的图像,所以我只需要在启动游戏时加载每个图像一次。
I need the structure of my resources folder (and its subfolders) maintained
它是维护的。资源文件夹中的每个文件 和目录 都已按照标准目录布局的要求直接复制到 jar 中。
问题出在您的设置上:在 'dev time' 时,您似乎试图从 resources/items/someItem.png
加载,但当您的应用程序出现问题时,这不起作用。有两种明显的方式可以发生这种情况;
你不明白原因
您正在尝试使用 new FileInputStream
、new File
,或者试图将这些 作为文件 加载。这行不通,也行不通,对目录结构进行再多的调整也无法使其发挥作用。在 java 中,file 表示 file - jarfile 中的 png 条目本身不是文件。
加载此类资源的方式始终是这种策略:
选择一个 class 即 'source location' - 例如,您正在寻找的资源将是 where-ever JVM 找到了这个 class 文件。通常,您可以在整个应用程序中选择任何 class;这仅在您使用模块化 class 加载系统时才有意义。如果您不知道那是什么意思,那么您就没有使用这些。
调用
MyContextClass.class.getResource(resourceKey)
获得一个 URL 对象,然后你可以将它传递给任何 API 允许你这样做的对象(还有很多 APIs 做,特别是包括 swing 自己的ImageIcon
)。或者,使用try (var in = MyContextClass.class.getResourceAsStream(resourceKey) { /* use resource here */ }
- 如果所讨论的 API 没有采用 URL 的重载但确实有采用 InputStream 的重载,则可以使用此方法。直接看内容也可以用这个resourceKey
有两种口味。"foo/bar.png"
解析相对于 package 上下文 class 所在的路径。如果你有package com.foo; public class Bar {}
那么在部署的某个地方有com/foo/Bar.class
。例如,在 jar 文件中,或在bin
目录中。如果您随后写入Bar.class.getResource("baz/quux.png")
,并且 Bar.class 位于该 jar 文件中,那么系统将在同一个 jar 文件中查找com/foo/baz/quux.png
。或者,包括一个前导斜杠:"/foo/bar.png"
会在同一个 jar 中查找,但对于foo/bar.png
.这就是您要做的全部。构建系统和 IDEs 确保您将图像准确地放在现在的位置(在
resources
文件夹中),您 不 包含resources
在您的部署密钥中(出于同样的原因,您在src/main/java/com/foo/MyApp.class
中拥有 java 源文件,并且您不包括src
、main
或java
在您完全限定的 class 名称中。它只是com.foo.MyApp
,而不是main.java.com.foo.MyApp
。resources
不再是它的一部分,就像java
是它的一部分一样您的 class 个名称。如果它不起作用,则说明它们配置错误。
您的设置不可靠
您可能一直在偷偷摸摸,例如使用插件系统,您可以自己直接在文件系统上检查某些文件,-或-通过 ContextClass.class.getResource
加载,或者您一直在搞乱 IDE 的 maven 插件识别资源目录的方式,或者您一直在手动设置 IDE 项目(而不是使用其 Maven 集成)并将 src/main
标记为源目录(而不是 src/main/java
和 src/main/resources
) .设置坏了;解决这个问题(不要 'fix' 它试图保持 resources
左右)。