Gradle: 如何创建多个jar?
Gradle: How to create multiple jar?
我是 Gradle 和 Groovy 的新手,我希望有人能解决我的问题。
我有几个包,每个包都需要编译成一个jar。
我发现的一种解决方案是创建多个 Jar
类型的任务,但我想避免 copy/paste 并在每次添加新任务时得到一个巨大的 gradle 文件打包到我的项目中。
我目前的实现是有多个 jar 任务,比如这个:
task jarFoo(type: Jar) {
baseName = "foo"
version = "1.0.0"
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
它就像一个魅力,但我经常添加包,我最终会得到很多包,因此有很多任务和很多 copied/pasted 代码。
在摆弄 build.gradle
文件后,我发现我需要从 Jar
扩展才能创建一个 jar。
到目前为止,这是 class 的代码:
class JarTask extends Jar {
String jarName = "default"
String jarVersion = "1.0.0"
@TaskAction
def jar() {
baseName = jarName
version = jarVersion
String className = baseName.capitalize()
// Thanks Opal for reminding that sourceSets
// is defined in project.
from(project.sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
task jarFoo(type: JarTask) {
jarName = "foo"
}
task jarBar(type: JarTask) {
jarName = "bar"
jarVersion = "1.2.42"
}
问题是创建的 jar 基本上忽略了方法中的所有内容:它只包含一个 MANIFEST.MF
包含清单版本的一行,并给出了项目名称,而不是给定的名称在任务中。没有别的。
如果需要,您可以在我的GitHub repo(主要是法语)中在线找到代码。
如有任何想法,我们将不胜感激!
编辑后问题很简单。给定任务没有 属性 sourceSets
(在本例中为 Jar
)。 sourceSets
在 Project
上定义,每个扩展 DefaultTask
的任务都从其父级继承 project
字段。所以你只需要:
from(project.sourceSets.main.output) {
include "$baseName/**"
}
回答
希望您了解任务配置和执行阶段的区别。这是这里发生的问题。基本上,您扩展了 Jar
任务,因为所有 Copy
类型的任务都不是为扩展而设计的 - 请参阅 here. In task action you configure the artifacts to be copied but.. there's too late for configuration - it's execution phase. To solve the problem task rules 可能会被使用。我修改了脚本,它是:
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
tasks.addRule('Pattern: build<ID>') { String taskName ->
if (taskName.startsWith('build')) {
task(taskName, type: Jar) {
baseName = taskName - 'build'
version = '1.0.0'
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
}
artifacts {
archives project.tasks['buildqcm'], project.tasks['buildlistage'] //etc
}
并且应该使用 gradle buildlistage buildqcm
简单地调用。您可以进行额外的验证以检查 <ID>
passed 是否在包列表中,例如希望对您有所帮助,抱歉让您等了这么久:/
这是另一个允许传递参数的更简单的选项。我找到了关于这个主题的灵感:https://discuss.gradle.org/t/passing-arguments-to-a-task/8427/20,这听起来和我想做的一模一样。
这里我们基本上定义了一个方法,returns 一个任务,给定一些参数。剩下的只是测试是否给出了版本,或者已经给出的代码有问题并在@Opal 的帮助下进行了改编。
将新构建包含在 artifacts
块中足以使任务可用。然后,只需 运行 gradle jarqcm
构建单个包或 gradle assemble
编译所有内容。
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
def jarPackage(artifactName, artifactVersion) {
if (artifactVersion == "" || artifactVersion == null) {
artifactVersion = "1.0.0"
}
return tasks.create("jar${artifactName}", Jar) {
baseName = artifactName
version = artifactVersion
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
artifacts {
archives jarPackage("aleatoire", ""), jarPackage("calculatrice", "1.2.3"), jarPackage("copier", ""),
jarPackage("qcm", "1.0.0")
}
我是 Gradle 和 Groovy 的新手,我希望有人能解决我的问题。
我有几个包,每个包都需要编译成一个jar。
我发现的一种解决方案是创建多个 Jar
类型的任务,但我想避免 copy/paste 并在每次添加新任务时得到一个巨大的 gradle 文件打包到我的项目中。
我目前的实现是有多个 jar 任务,比如这个:
task jarFoo(type: Jar) {
baseName = "foo"
version = "1.0.0"
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
它就像一个魅力,但我经常添加包,我最终会得到很多包,因此有很多任务和很多 copied/pasted 代码。
在摆弄 build.gradle
文件后,我发现我需要从 Jar
扩展才能创建一个 jar。
到目前为止,这是 class 的代码:
class JarTask extends Jar {
String jarName = "default"
String jarVersion = "1.0.0"
@TaskAction
def jar() {
baseName = jarName
version = jarVersion
String className = baseName.capitalize()
// Thanks Opal for reminding that sourceSets
// is defined in project.
from(project.sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
task jarFoo(type: JarTask) {
jarName = "foo"
}
task jarBar(type: JarTask) {
jarName = "bar"
jarVersion = "1.2.42"
}
问题是创建的 jar 基本上忽略了方法中的所有内容:它只包含一个 MANIFEST.MF
包含清单版本的一行,并给出了项目名称,而不是给定的名称在任务中。没有别的。
如果需要,您可以在我的GitHub repo(主要是法语)中在线找到代码。
如有任何想法,我们将不胜感激!
编辑后问题很简单。给定任务没有 属性 sourceSets
(在本例中为 Jar
)。 sourceSets
在 Project
上定义,每个扩展 DefaultTask
的任务都从其父级继承 project
字段。所以你只需要:
from(project.sourceSets.main.output) {
include "$baseName/**"
}
回答
希望您了解任务配置和执行阶段的区别。这是这里发生的问题。基本上,您扩展了 Jar
任务,因为所有 Copy
类型的任务都不是为扩展而设计的 - 请参阅 here. In task action you configure the artifacts to be copied but.. there's too late for configuration - it's execution phase. To solve the problem task rules 可能会被使用。我修改了脚本,它是:
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
tasks.addRule('Pattern: build<ID>') { String taskName ->
if (taskName.startsWith('build')) {
task(taskName, type: Jar) {
baseName = taskName - 'build'
version = '1.0.0'
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
}
artifacts {
archives project.tasks['buildqcm'], project.tasks['buildlistage'] //etc
}
并且应该使用 gradle buildlistage buildqcm
简单地调用。您可以进行额外的验证以检查 <ID>
passed 是否在包列表中,例如希望对您有所帮助,抱歉让您等了这么久:/
这是另一个允许传递参数的更简单的选项。我找到了关于这个主题的灵感:https://discuss.gradle.org/t/passing-arguments-to-a-task/8427/20,这听起来和我想做的一模一样。
这里我们基本上定义了一个方法,returns 一个任务,给定一些参数。剩下的只是测试是否给出了版本,或者已经给出的代码有问题并在@Opal 的帮助下进行了改编。
将新构建包含在 artifacts
块中足以使任务可用。然后,只需 运行 gradle jarqcm
构建单个包或 gradle assemble
编译所有内容。
apply plugin: "idea"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
compile "com.intellij:forms_rt:7.0.3"
runtime "com.intellij:forms_rt:7.0.3"
}
def jarPackage(artifactName, artifactVersion) {
if (artifactVersion == "" || artifactVersion == null) {
artifactVersion = "1.0.0"
}
return tasks.create("jar${artifactName}", Jar) {
baseName = artifactName
version = artifactVersion
String className = baseName.capitalize()
from(sourceSets.main.output) {
include "$baseName/**"
}
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes "Implementation-Title": "$className",
"Implementation-Version": "$version",
"Main-Class": "$baseName.$className"
}
}
}
artifacts {
archives jarPackage("aleatoire", ""), jarPackage("calculatrice", "1.2.3"), jarPackage("copier", ""),
jarPackage("qcm", "1.0.0")
}