【发布时间】:2019-01-22 16:07:00
【问题描述】:
从 IDEA 2018.2.1 开始,IDE 启动错误突出显示包“not
在模块图中”来自已模块化的依赖项。我在我的项目中添加了一个module-info.java 文件并添加了
必要的requires 语句,但我现在无法访问
我的src/main/resources 目录中的资源文件。
(有关完整示例,请参阅this GitHub project。)
当我使用 ./gradlew run 或 ./gradlew installDist + 时
包装脚本,我能够读取资源文件,但是当我运行我的
IDE 中的应用程序,我不是。
我提交了issue
使用 JetBrains,我了解到 IDEA 正在使用该模块
路径,而 Gradle 默认使用类路径。通过增加
我的build.gradle 的以下块,我能够得到 Gradle
也 ...无法读取任何资源文件。
run {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--module', "$moduleName/$mainClassName"
]
classpath = files()
}
}
我尝试export-ing 我感兴趣的资源目录作为
“包”,并在编译时构建失败:
错误:包为空或不存在:mydir
使用opens 而不是exports 得到了同样的错误,但降级了
警告。
我什至尝试移动src/main/java下的mydir资源目录,
但这产生了相同的错误/警告,并且还导致
资源未复制到build 目录。
Java 9 中的资源应该放在哪里,如何访问它们?
注意:在继续阅读后,我对这个问题进行了大量编辑
研究问题。在最初的问题中,我也试图
弄清楚如何列出资源目录中的文件,但在
在调查过程中,我确定这是一条红鲱鱼——
首先,因为读取资源目录仅在
正在从file:/// URL 读取资源(甚至可能不是这样),
其次,因为普通文件也不起作用,所以很明显
问题一般出在资源文件上,而不是专门与
目录。
解决方法:
根据Slaw's answer,我将以下内容添加到build.gradle:
// at compile time, put resources in same directories as classes
sourceSets {
main.output.resourcesDir = main.java.outputDir
}
// at compile time, include resources in module
compileJava {
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--patch-module', "$moduleName="
+ files(sourceSets.main.resources.srcDirs).asPath,
'--module-version', "$moduleVersion"
]
classpath = files()
}
}
// at run time, make Gradle use the module path
run {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--module', "$moduleName/$mainClassName"
]
classpath = files()
}
}
旁注:有趣的是,如果我不继续添加 Slaw 的代码,使 run 任务针对 JAR 执行,尝试读取资源运行任务中的目录InputStream 现在throws an IOException,而不是提供文件列表。 (针对 JAR,它只是得到一个空的 InputStream。)
【问题讨论】:
-
如果您正在使用命名模块,您是否也尝试过
--add-opens <source-module>/<package>=<target-module>,其中包名称是根据Module#getResourceAsStream的文档中所述派生的?顺便问一下,--show-module-resolution在启动时列出了什么? -
@nullpointer 这只是获取
package fonts not in <module-name>的另一种方式,尽管至少应用程序不会崩溃。同样,这是访问在同一模块中的资源目录的代码。如果这需要特殊的命令行处理,那么模块系统就会损坏。 -
@nullpointer
--show-module-resolution似乎没有显示任何非常有趣的东西。它确实给出了root <module-name> file:///<project-dir>/out/production/classes,是的,不包括out/production/resources。 -
有趣。我不知道您能够读取带有
ClassLoader.getResourceAsStream()的文件夹。直到。不确定这是否曾经是受支持的功能。 -
@DavidMoles 好的,如果您可以分享一个 MCVE 来理解和重现您所指出的内容,那就太好了。似乎您只有一个命名(您的)模块,并且您正在尝试访问其中的资源。但不是很清楚你想用代码
ClassLoader.getSystemClassLoader().getResourceAsStream("fonts")实现什么...只是补充一下,到 github 的链接对我也很有效。
标签: java gradle embedded-resource java-9 java-module