有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用Java创建Gradle自定义插件

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

You can implement a custom plugin in any language you like, provided the implementation ends up compiled as bytecode. For the examples here, we are going to use Groovy as the implementation language. You could use Java or Scala instead, if you want.

然而,经过几个小时的谷歌搜索和阅读,我还没有找到任何关于如何用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.javaexecJavaExec调用Java代码,但我担心这会降低构建过程的可移植性


共 (3) 个答案

  1. # 1 楼答案

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

    1. 确保安装了Gradle 1.6或更高版本和Java JDK
    2. 使用指定的目录结构在下面创建这些文件
    3. 将目录更改为<projectRoot>/plugin目录
    4. 执行插件构建:$ gradle uploadArchives这一(非常重要)步骤编译Java代码并将其放入本地Maven repo(../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。属性

    implementation-class=org.joefernandez.gradle.MyJavaPlugin
    

    插件构建脚本

    请注意上载存档任务:您必须运行此任务才能使消费者脚本可以使用插件

    projectRoot/plugin/build。格拉德尔

    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/插件/设置。格拉德尔

    rootProject.name = 'MyJavaPlugin'
    

    根脚本

    projectRoot/build。格拉德尔

    apply plugin: 'java'
    
    dependencies {
        compile gradleApi()
    }
    

    消费者脚本

    projectRoot/consumer/build。格拉德尔

    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!")
    }
    
  2. # 2 楼答案

    我想对乔的回答提出一些修正

    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。格拉德尔

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

    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

  3. # 3 楼答案

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

    如何构建和发布插件是另一个问题,同样与使用哪种语言无关。请参阅完整Gradle分布中的Gradle User Guidesamples/customPlugin