使用 Java 创建 Gradle 自定义插件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17664183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a Gradle Custom Plugin with Java
提问by Joe Fernandez
I'm creating a build process with Gradle and I want to provide a plugin that uses Java code. The Gradle plugin documentationsaysthis is possible:
我正在使用 Gradle 创建一个构建过程,我想提供一个使用 Java 代码的插件。Gradle插件文档说这是可能的:
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.
您可以使用您喜欢的任何语言实现自定义插件,前提是实现最终编译为字节码。对于此处的示例,我们将使用 Groovy 作为实现语言。如果需要,您可以改用 Java 或 Scala。
However, after multiple hours of Googling and reading, I have yet to find any explanation of how to create a Gradle custom plugin with Java. It seems like you could create the code for it in a directory like:
然而,经过数小时的谷歌搜索和阅读,我还没有找到任何关于如何使用 Java 创建 Gradle 自定义插件的解释。似乎您可以在如下目录中为其创建代码:
<rootProjectDir>/buildSrc/src/main/java/
MyGradlePlugin.java
MyGradleTasks.java
But the question then becomes:
但问题就变成了:
- How to implement the plugin class and tasks in Java to be compatible with Gradle?
How to get Gradle to recognize the Java classes and tasks so you can use them in a build?
Can you just reference the plugin class like you do for the Groovy equivalent?
src/main/resources/META-INF/gradle-plugins/myjavaplugin.properties
implementation-class=org.me.MyGradlePlugin
- 如何在Java中实现插件类和任务以兼容Gradle?
如何让 Gradle 识别 Java 类和任务,以便您可以在构建中使用它们?
您可以像对 Groovy 等效项一样引用插件类吗?
src/main/resources/META-INF/gradle-plugins/myjavaplugin.properties
implementation-class=org.me.MyGradlePlugin
I realize that I could just call the Java code with project.javaexec
or JavaExec
, but I'm concerned this will make my build process less portable.
我意识到我可以只用project.javaexec
或调用Java代码JavaExec
,但我担心这会使我的构建过程不那么便携。
回答by Joe Fernandez
Here's a basic, stand-alone, Java-based Gradle plugin and the steps to get it working:
这是一个基本的、独立的、基于 Java 的 Gradle 插件以及使其工作的步骤:
- Make sure Gradle 1.6 or higher and Java JDK is installed
- Create these files below with the directory structure indicated
- Change directories to the
<projectRoot>/plugin
directory - Execute the plugin build:
$ gradle uploadArchives
This (very important) step compiles the Java code and puts it in your local Maven repo (../repo). - Now execute the consumer script by changing directories to
<projectRoot>/consumer
- Execute the script that depends on the plugin:
$ gradle checkitout
- 确保 Gradle 1.6 或更高版本和 Java JDK 已安装
- 使用指示的目录结构在下面创建这些文件
- 将
<projectRoot>/plugin
目录更改为目录 - 执行插件构建:
$ gradle uploadArchives
此(非常重要)步骤编译 Java 代码并将其放入您的本地 Maven 存储库 (../repo)。 - 现在通过将目录更改为执行消费者脚本
<projectRoot>/consumer
- 执行依赖插件的脚本:
$ gradle checkitout
Java Classes
Java 类
projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaPlugin.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
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");
}
}
Plugin Class declaration
插件类声明
projectRoot/plugin/src/main/resources/META-INF/gradle-plugins/test-plugin.properties
projectRoot/plugin/src/main/resources/META-INF/gradle-plugins/test-plugin.properties
implementation-class=org.joefernandez.gradle.MyJavaPlugin
Plugin Build Script
插件构建脚本
Note the uploadArchivestask: You must run this task to make the plugin available to the consumer script.
请注意uploadArchives任务:您必须运行此任务才能使插件可用于使用者脚本。
projectRoot/plugin/build.gradle
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'))
}
}
}
Settings for the Plugin
插件设置
projectRoot/plugin/settings.gradle
projectRoot/plugin/settings.gradle
rootProject.name = 'MyJavaPlugin'
Root script
根脚本
projectRoot/build.gradle
projectRoot/build.gradle
apply plugin: 'java'
dependencies {
compile gradleApi()
}
Consumer script
消费者脚本
projectRoot/consumer/build.gradle
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!")
}
回答by Corey Scott
I would like to propose a few amendments to Joe's great answer.
我想对乔的好答案提出一些修正。
projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaPlugin.java
projectRoot/plugin/src/main/java/org/joefernandez/gradle/MyJavaPlugin.java
This change wires the task into the supplied project without the need to sub-class it.
此更改将任务连接到提供的项目中,而无需对其进行子类化。
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);
}
}
Consumer script
消费者脚本
projectRoot/consumer/build.gradle
projectRoot/consumer/build.gradle
This change removes the now unnecessary task definition
此更改删除了现在不必要的任务定义
buildscript {
repositories {
maven {
url uri('../repo')
}
}
dependencies {
classpath group: 'org.joefernandez',
name: 'MyJavaPlugin',
version: '1.0-SNAPSHOT'
}
}
apply plugin: 'test-plugin'
// CHANGE HERE
This them changes step 6, to:
他们将第 6 步更改为:
Execute the script that depends on the plugin: $ gradle javaTask
Execute the script that depends on the plugin: $ gradle javaTask
回答by Peter Niederwieser
Plugin classes must implement the org.gradle.api.Plugin
interface. Task classes typically extend the org.gradle.api.DefaultTask
class. It doesn't matter which (JVM) language is used for this. The Gradle codebase contains many plugin and task classes implemented in Java.
插件类必须实现org.gradle.api.Plugin
接口。任务类通常扩展org.gradle.api.DefaultTask
类。为此使用哪种(JVM)语言并不重要。Gradle 代码库包含许多用 Java 实现的插件和任务类。
How to build and ship a plugin is another question, again mostly unrelated to which language is used. See the Gradle User Guideand samples/customPlugin
in the full Gradle distribution.
如何构建和发布插件是另一个问题,同样与使用哪种语言无关。请参阅Gradle 用户指南和samples/customPlugin
完整的 Gradle 发行版。