I'm creating a build process with Gradle and I want to provide a plugin that uses Java code. The Gradle plugin documentation says this is possible:
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.
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:
<rootProjectDir>/buildSrc/src/main/java/ MyGradlePlugin.java MyGradleTasks.java
But the question then becomes:
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
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.
Java Gradle Development Plugin. When we're writing our plugins in Java, we can benefit from the Java Gradle Development Plugin. This will automatically compile and add gradleApi() dependencies. It will also perform plugin metadata validation as a part of the gradle jar task.
To create a Gradle plugin, you need to write a class that implements the Plugin interface. When the plugin is applied to a project, Gradle creates an instance of the plugin class and calls the instance's Plugin. apply() method.
The Java Gradle Plugin development plugin can be used to assist in the development of Gradle plugins. It automatically applies the Java Library plugin, adds the gradleApi() dependency to the api configuration and performs validation of plugin metadata during jar task execution.
Here's a basic, stand-alone, Java-based Gradle plugin and the steps to get it working:
<projectRoot>/plugin
directory$ gradle uploadArchives
This (very important) step compiles the Java code and puts it in your local Maven repo (../repo).<projectRoot>/consumer
$ gradle checkitout
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
Note the uploadArchives task: You must run this task to make the plugin available to the consumer script.
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'
projectRoot/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!") }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With