在构建Java9模块的Gradle项目中,资源文件放在哪里?
从IDEA 2018.2.1开始,IDE开始错误突出显示包“非 在模块图中,“来自已模块化的依赖项”。我在我的项目中添加了一个在构建Java9模块的Gradle项目中,资源文件放在哪里?,java,gradle,embedded-resource,java-9,java-module,Java,Gradle,Embedded Resource,Java 9,Java Module,从IDEA 2018.2.1开始,IDE开始错误突出显示包“非 在模块图中,“来自已模块化的依赖项”。我在我的项目中添加了一个module info.java文件,并添加了 requisite需要语句,但我现在无法访问 我的src/main/resources目录中的资源文件 (有关完整示例,请参见。) 当我使用/gradlew run或/gradlew installDist+生成 包装器脚本,我能够读取资源文件,但当我运行 来自IDE的应用程序,我不是 我提交了一份 有了JetBrains,
module info.java
文件,并添加了
requisite需要
语句,但我现在无法访问
我的src/main/resources
目录中的资源文件
(有关完整示例,请参见。)
当我使用/gradlew run
或/gradlew installDist
+生成
包装器脚本,我能够读取资源文件,但当我运行
来自IDE的应用程序,我不是
我提交了一份
有了JetBrains,我学到的是这个想法就是使用这个模块
默认情况下,Gradle使用的是类路径。加入
在我的build.gradle
的下面一个模块中,我能够获得gradle
到也…无法读取任何资源文件
run {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--module', "$moduleName/$mainClassName"
]
classpath = files()
}
}
我试着导出我感兴趣的资源目录
“package”,编译时生成失败,原因是:
错误:包为空或不存在:mydir
使用打开
而不是导出
会出现相同的错误,尽管降级了
警告
我甚至试着移动src/main/java
下的mydir
资源目录,
但这会产生相同的错误/警告,并导致
未将资源复制到生成
目录
Java 9中的资源应该放在哪里?我如何访问它们
注意:在继续讨论之后,我对这个问题进行了大量编辑 研究这个问题。在最初的问题中,我也试图 了解如何在资源目录中列出文件,但在 在调查过程中,我确定这是一个骗局-- 首先,因为只有当 正在从
文件中读取资源://
URL(甚至可能不是这样),
第二,因为普通文件也不起作用,所以很明显
问题是一般的资源文件,而不是具体的资源文件
目录
解决方案: 根据,我在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的代码,使运行
任务对JAR执行,尝试现在读取运行任务中的资源目录InputStream
,而不是提供文件列表。(相对于JAR,它只得到一个空的InputStream
)更新(2020年3月25日):在适当的JPMS支持方面取得了重大进展。Gradle 6.4的夜间构建现在包括使用Java9模块进行本地开发的选项。看
更新(2020年9月29日):自Gradle 6.4(截至本次更新的当前版本为6.6.1)以来,您现在可以在Gradle项目中本机支持JPMS模块,但您必须明确激活此功能:
java{
模块化.inferModulePath.set(true)
}
有关更多信息,请参阅Gradle's,它还链接到其他各种相关文档
Gradle和java9模块支持 不幸的是,从6.0.1版开始,Gradle仍然没有对Java9模块的一流支持,正如指南所示 Java9最令人兴奋的特性之一是它支持开发和部署模块化Java软件。Gradle还没有对Java9模块的一流支持 一些,比如,试图增加支持。本指南将在开发时更新更多关于如何使用内置Gradle支持的信息 注意:本指南过去更为广泛,并提供了如何“手动”自定义现有任务的示例。但是,它后来改为上面的内容,建议使用至少提供一些Java9支持的第三方插件。其中一些社区插件似乎不仅仅提供模块支持,例如支持使用Gradle提供的
jlink
工具
Gradle项目有一个“epic”,据说它跟踪Java9模块支持:
问题 找不到资源文件的原因是,默认情况下,Gradle会在不同的目录中输出已编译的类和已处理的资源。它看起来像这样:
构建/
|--班级/
|--资源/
classes
目录是放置module info.class
文件的地方。这会导致模块系统出现问题,因为从技术上讲,资源
目录下的文件不包括在类
目录下的模块中。当使用类路径而不是modulepath时,这不是问题,因为模块系统将整个类路径视为一个巨大的模块(即所谓的未命名模块)
如果为仅限资源的包添加opens
指令,则在运行时会出现错误。错误的原因是由于前面提到的目录布局,模块中不存在包。您在编译时收到警告的原因基本相同;该模块存在于src/main/java
中,src/main/resources
下的资源文件在技术上不包括在该模块中
注意:我所说的“仅资源包”是指包含资源但没有任何资源具有.java
或.class
扩展名的包
当然,如果资源仅可供模块本身访问,则无需添加opens
指令。当其他模块需要访问资源时,您只需要为包含资源的包添加此类指令,因为模块中的资源受限制
资源
opens io.fouad.packageone to moduletwo.name;
A.class.getResource("/io/fouad/packageone/logging.properties");
public static URL getLoggingConfigFileAsResource()
{
return A.class.getResource("/io/fouad/packageone/logging.properties");
}