用Java创建Gradle自定义插件

用Java创建Gradle自定义插件,java,gradle,Java,Gradle,我正在用Gradle创建一个构建过程,我想提供一个使用Java代码的插件。格拉德尔说这是可能的: 您可以用任何喜欢的语言实现自定义插件,前提是实现最终编译为字节码。对于这里的示例,我们将使用Groovy作为实现语言。如果您愿意,您可以使用Java或Scala 然而,经过几个小时的谷歌搜索和阅读,我还没有找到任何关于如何用Java创建Gradle自定义插件的解释。您似乎可以在如下目录中为其创建代码: <rootProjectDir>/buildSrc/src/main/java/

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

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

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

<rootProjectDir>/buildSrc/src/main/java/
  MyGradlePlugin.java
  MyGradleTasks.java 
/buildSrc/src/main/java/
MyGradlePlugin.java
MyGradleTasks.java
但问题是:

  • 如何在Java中实现插件类和任务以与Gradle兼容
  • 如何让Gradle识别Java类和任务,以便在构建中使用它们

    你能像对待Groovy一样引用插件类吗

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


  • 我意识到我可以用
    project.javaexec
    javaexec
    调用Java代码,但我担心这会降低构建过程的可移植性。

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


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

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

  • 确保安装了Gradle 1.6或更高版本和Java JDK
  • 使用指定的目录结构在下面创建这些文件
  • 将目录更改为
    /plugin
    目录
  • 执行插件构建:
    $gradle uploadArchives
    此(非常重要)步骤编译Java代码并将其放入本地Maven repo(../repo)中
  • 现在通过将目录更改为
    /consumer
    来执行consumer脚本
  • 执行依赖于插件的脚本:
    $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");
        }
    
    }
    
    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'))
            }
        }
    }
    
    rootProject.name = 'MyJavaPlugin'
    
    apply plugin: 'java'
    
    dependencies {
        compile gradleApi()
    }
    
    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!")
    }
    
    插件的设置 projectRoot/plugin/settings.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'))
            }
        }
    }
    
    rootProject.name = 'MyJavaPlugin'
    
    apply plugin: 'java'
    
    dependencies {
        compile gradleApi()
    }
    
    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!")
    }
    
    根脚本 projectRoot/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'))
            }
        }
    }
    
    rootProject.name = 'MyJavaPlugin'
    
    apply plugin: 'java'
    
    dependencies {
        compile gradleApi()
    }
    
    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!")
    }
    
    消费者脚本 projectRoot/consumer/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'))
            }
        }
    }
    
    rootProject.name = 'MyJavaPlugin'
    
    apply plugin: 'java'
    
    dependencies {
        compile gradleApi()
    }
    
    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!")
    }
    

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

    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");
        }
    
    }
    
    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");
        }
    
    }
    
    此更改将任务连接到提供的项目中,而无需对其进行子类化

    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);
        }
    
    }
    
    这将步骤6更改为:


    执行依赖于插件的脚本:$gradle javaTask

    谢谢,彼得!这让我走上了正确的道路。我将很快发布我的解决方案。指定
    存储库(url:uri('../repo'))
    是可选的。您可以改为导出到默认的本地回购。并从mavenLocal()导入。我根据Joe在上的描述创建了一个Android Studio项目。随便用叉子或抄袭意大利面吧。不为我工作。格雷德尔可能改变了什么