无法从 Heroku Java 应用中的类路径加载资源
Unable to load resource from classpath in Heroku Java app
我在运行时访问资源文件时遇到问题,该文件存储在我的 JAVA 项目的资源文件夹中。
该项目是 Spring 基于引导的,我在 src/main/resources 下存储了一些 ddl 和 json 配置文件。
项目得到正确部署(通过 Maven)。但是,当我的代码尝试访问这些资源文件之一时,出现以下异常:
java.nio.file.NoSuchFileException: 文件:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/app_data_schema.ddl
我可以从日志中看到,就在这个异常之前,Spring 从同一位置正确加载了另一个文件
(文件:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/schema.sql)。
我还使用 heroku CLI ("heroku run bash") 仔细检查文件确实已部署到我期望的位置:
/app/target/classes/setup_data
- test_app_data1.json
- test_app_data2.json
- app_data_schema.ddl
这让我相信问题出在我加载文件的方式上,它在我的机器上本地工作,但在部署到 Heroku 时却不行。
这是我用来计算文件完整路径的代码:
public static String getFullPathForResource(Class<?> resourceClass, String resourceName) {
URL resourceUrl = resourceClass.getResource(resourceName);
String fullPath = "";
if (resourceUrl != null) {
fullPath = resourceUrl.getPath();
}
return fullPath;
}
然后我加载文件如下:
String ddlResourceFullPath = getFullPathForResource(getClass(), ddlResource);
Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));
getFullPathForResource()方法的结果确实是:
"file:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/schema.sql"
根据我的理解应该匹配我的资源的正确路径!
能否指导我如何正确加载资源文件?
感谢您的帮助!
我被 Heroku 的支持指出了这个问题。
问题出在我加载文件的方式上,而不是我找到资源路径的方式上。
具体来说,这一行:
Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));
Files.lines 期望文件在文件系统上,并且无法打开 Jar 文件中的文件。
使用 java.lang.ClassLoader.getResourceAsStream()
解决了这个问题。 (例如:MyClass.class.getResourceAsStream()
)
我在运行时访问资源文件时遇到问题,该文件存储在我的 JAVA 项目的资源文件夹中。
该项目是 Spring 基于引导的,我在 src/main/resources 下存储了一些 ddl 和 json 配置文件。 项目得到正确部署(通过 Maven)。但是,当我的代码尝试访问这些资源文件之一时,出现以下异常:
java.nio.file.NoSuchFileException: 文件:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/app_data_schema.ddl
我可以从日志中看到,就在这个异常之前,Spring 从同一位置正确加载了另一个文件 (文件:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/setup_data/schema.sql)。
我还使用 heroku CLI ("heroku run bash") 仔细检查文件确实已部署到我期望的位置:
/app/target/classes/setup_data
- test_app_data1.json
- test_app_data2.json
- app_data_schema.ddl
这让我相信问题出在我加载文件的方式上,它在我的机器上本地工作,但在部署到 Heroku 时却不行。 这是我用来计算文件完整路径的代码:
public static String getFullPathForResource(Class<?> resourceClass, String resourceName) {
URL resourceUrl = resourceClass.getResource(resourceName);
String fullPath = "";
if (resourceUrl != null) {
fullPath = resourceUrl.getPath();
}
return fullPath;
}
然后我加载文件如下:
String ddlResourceFullPath = getFullPathForResource(getClass(), ddlResource);
Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));
getFullPathForResource()方法的结果确实是: "file:/app/target/app-backend-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/schema.sql"
根据我的理解应该匹配我的资源的正确路径!
能否指导我如何正确加载资源文件?
感谢您的帮助!
我被 Heroku 的支持指出了这个问题。
问题出在我加载文件的方式上,而不是我找到资源路径的方式上。 具体来说,这一行:
Stream<String> lines = Files.lines(Paths.get(ddlResourceFullPath));
Files.lines 期望文件在文件系统上,并且无法打开 Jar 文件中的文件。
使用 java.lang.ClassLoader.getResourceAsStream()
解决了这个问题。 (例如:MyClass.class.getResourceAsStream()
)