我的问题:如何为gradle build
设置模块路径?
我已经很习惯从命令行使用Java模块。我经常在Powershell中进行练习,生成这些源文件。
└───src
├───appMod
│ │ module-info.java
│ │
│ └───appPack
│ Entry.java
│
└───greetMod
│ module-info.java
│
└───greetPack
Hello.java
module appMod {
requires greetMod;
}
package appPack;
import greetPack.Hello;
public class Entry {
public static void main(String[] args) {
System.out.println(new Hello().sayHello());
}
}
module greetMod {
exports greetPack;
}
package greetPack;
public class Hello {
public String sayHello() {
return "Greetings from Hello class!";
}
}
由于appMod模块需要greetMod,因此我先编译并打包greetMod。
javac -d out/greetMod src/greetMod/module-info.java src/greetMod/greetPack/Hello.java;
jar cf lib/greetJar.jar -C out/greetMod .;
然后我编译并打包appMod,但是我这样做时指定了模块路径(-p),可在其中找到新的greetMod jar(greetJar)(在lib中)。
javac -d out/appMod -p lib src/appMod/module-info.java src/appMod/appPack/Entry.java;
jar cfe lib/appJar.jar appPack.Entry -C out/appMod .;
然后我可以通过添加模块路径来部分运行或链接它。
java -p lib -m appMod;
jlink -p lib --add-modules appMod --launcher launch=appMod --output dist;
dist/bin/launch
我现在想在Gradle中做同样的练习,但是我不知道该怎么做等同于设置模块路径,例如-p lib
。我见过sourceSets的代码和dependencies的无数变种,但到目前为止,我还无法将所有有用的东西放在一起。我还阅读了相互矛盾的声明,它们都说Gradle doesn't fully support Java modules和那个Gradle does support them。
答案 0 :(得分:2)
自Gradle 6.4起,您可以使用在项目Java插件上设置inferModulePath
属性来自动设置模块路径:
subprojects {
plugins.withType(JavaPlugin).configureEach {
java {
modularity.inferModulePath = true
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
}
答案 1 :(得分:1)
我知道这可能会造成混淆,但是绝对可以通过gradle完成。您将需要使用多项目构建来完成这项工作。在最顶部的build.gradle
中,执行以下操作:
subprojects {
apply plugin: 'java'
sourceCompatibility = 1.9
compileJava {
doFirst {
options.compilerArgs += [
'--module-path', classpath.asPath
]
classpath = files()
}
}
}
在您的settings.gradle
中:
rootProject.name = 'module-testing'
include 'src:greetMod'
include 'src:appMod'
appMod
中的所有内容都应移到名为appModSrc
的文件夹中。对greetMod
执行相同操作,因此请使用greetModSrc
。
目录结构:
├── build.gradle
└── greetModSrc
├── greetPack
│ └── Hello.java
└── module-info.java
sourceSets {
main {
java {
srcDirs 'greetModSrc'
}
}
}
目录结构:
├── appModSrc
│ ├── appPack
│ │ └── Entry.java
│ └── module-info.java
└── build.gradle
plugins {
id 'application'
}
sourceSets {
main {
java {
srcDirs 'appModSrc'
}
}
}
application {
mainClassName 'appPack.Entry'
}
jar {
doFirst {
manifest {
attributes('ModuleMainClass': mainClassName)
}
}
}
dependencies {
implementation project(':src:greetMod')
}
使用此设置,您只需运行 ./gradlew :src:appMod:run
:
> Task :src:appMod:run
Greetings from Hello class!
您可以在此处下载想法项目:https://github.com/smac89/multi-java9-gradle
答案 2 :(得分:1)
首先请注意:我使用Java 15的Gradle 6.6.1。
这是我观察到的:
为了使编译工作正常进行,每个项目都需要:
java {
modularity.inferModulePath = true
}
这可以通过{p>在根build.gradle
上打开
subprojects {
apply plugin: "java"
java {
modularity.inferModulePath = true
}
}
为了将模块路径与gradle run
一起使用(ServiceLoader在没有META-INF的情况下工作,反射限制...),您必须使用以下应用程序部分:
application {
mainModule = 'org.gradle.sample.app' // name defined in module-info.java
mainClass = 'org.gradle.sample.Main'
// DO NOT USE mainClassName = 'org.gradle.sample.Main'
}
花了我很多时间将所有Gradle页面中的所有内容放在一起- 但这全是here。
注意:
这将不是模块路径的非模块化jar。