35

我正在使用 Gradle 创建一个构建过程,并且我想提供一个使用 Java 代码的插件。Gradle插件文档 这是可能的:

您可以使用您喜欢的任何语言实现自定义插件,前提是实现最终编译为字节码。对于此处的示例,我们将使用 Groovy 作为实现语言。如果需要,您可以改用 Java 或 Scala。

然而,经过几个小时的谷歌搜索和阅读,我还没有找到任何关于如何使用 Java 创建 Gradle 自定义插件的解释。似乎您可以在如下目录中为其创建代码:

<rootProjectDir>/buildSrc/src/main/java/
  MyGradlePlugin.java
  MyGradleTasks.java 

但是问题就变成了:

  1. 如何在 Java 中实现插件类和任务以兼容 Gradle?
  2. 如何让 Gradle 识别 Java 类和任务,以便您可以在构建中使用它们?

    你能像对 Groovy 等价物那样引用插件类吗?

    src/main/resources/META-INF/gradle-plugins/myjavaplugin.properties implementation-class=org.me.MyGradlePlugin

我意识到我可以使用project.javaexecor调用 Java 代码JavaExec,但我担心这会使我的构建过程不那么可移植。

4

3 回答 3

69

这是一个基本的、独立的、基于 Java 的 Gradle 插件以及使其工作的步骤:

  1. 确保 Gradle 1.6 或更高版本并且已安装 Java JDK
  2. 使用指示的目录结构在下面创建这些文件
  3. 将目录更改为<projectRoot>/plugin目录
  4. 执行插件构建:$ gradle uploadArchives这个(非常重要的)步骤编译 Java 代码并将其放入本地 Maven 存储库 (../repo)。
  5. 现在通过将目录更改为来执行消费者脚本<projectRoot>/consumer
  6. 执行依赖插件的脚本:$ gradle checkitout

Java 类

projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaPlugin.java

package org.joefernandez.gradle;

import org.gradle.api.Project;
import org.gradle.api.Plugin;

public class MyJavaPlugin implements Plugin<Project> {

    @Override
    public void apply(Project target) {
        target.task("javaTask");
    }

}

projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaTask.java

package org.joefernandez.gradle;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;

public class MyJavaTask extends DefaultTask {

    @TaskAction
    public void javaTask() {
        System.out.println("Hello from MyJavaTask");
    }

}

插件类声明

projectRoot/plugin/src/main/resources/META-INF/gradle-plugins/test-plugin.properties

implementation-class=org.joefernandez.gradle.MyJavaPlugin

插件构建脚本

注意uploadArchives任务:您必须运行此任务以使插件可用于使用者脚本。

projectRoot/plugin/build.gradle

apply plugin: 'java'

dependencies {
    compile gradleApi()
}

apply plugin: 'maven'

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.11'
}

group = 'org.joefernandez'
version = '1.0-SNAPSHOT'

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}

插件设置

projectRoot/plugin/settings.gradle

rootProject.name = 'MyJavaPlugin'

根脚本

项目根/build.gradle

apply plugin: 'java'

dependencies {
    compile gradleApi()
}

消费者脚本

projectRoot/consumer/build.gradle

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'org.joefernandez',
                   name: 'MyJavaPlugin',
                version: '1.0-SNAPSHOT'
    }
}
apply plugin: 'test-plugin'

task checkitout(type: org.joefernandez.gradle.MyJavaTask) {
    println("running consumer task!")
}
于 2013-07-18T04:49:43.463 回答
24

我想对乔的好答案提出一些修改。

projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaPlugin.java

此更改将任务连接到提供的项目中,而无需对其进行子类化。

package org.joefernandez.gradle;

import org.gradle.api.Project;
import org.gradle.api.Plugin;

public class MyJavaPlugin implements Plugin<Project> {

    @Override
    public void apply(Project target) {
        // CHANGE HERE
        target.getTasks().create("javaTask", MyJavaTask.class);
    }

}

消费者脚本

projectRoot/consumer/build.gradle

此更改删除了现在不必要的任务定义

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
    }
    dependencies {
        classpath group: 'org.joefernandez',
                   name: 'MyJavaPlugin',
                version: '1.0-SNAPSHOT'
    }
}
apply plugin: 'test-plugin'

// CHANGE HERE

他们将步骤 6 更改为:

Execute the script that depends on the plugin: $ gradle javaTask

于 2013-12-18T18:04:23.693 回答
3

插件类必须实现org.gradle.api.Plugin接口。任务类通常扩展org.gradle.api.DefaultTask类。使用哪种(JVM)语言并不重要。Gradle 代码库包含许多用 Java 实现的插件和任务类。

如何构建和发布插件是另一个问题,同样与使用哪种语言无关。请参阅Gradle 用户指南samples/customPlugin完整的 Gradle 发行版。

于 2013-07-15T23:01:53.467 回答