How can I write a custom plugin in Java?


(Pranav K Varshney) #1

Hi,

There are about 50 modules and hence 50 build files. These are common for all the build files -

sourceSets {
     main {
         java {
             srcDir 'src/main'
         }
     }
     test {
             java {
                 srcDir 'src/test'
             }
     }
 }
   version = "1.0"
 group = "com.xxx.inhouse"
   repositories {
     mavenRepo name: 'myCo', urls: "http://speke.xxx.co.in:8080/artifactory/myCo"
 }

I want to move this common code to custom plug-in (Say MyPlugin)

All the 50 build files would then use MyPlugin and give only the dependencies like

apply plugin: 'myPlugin'
   dependencies {
     compile group: 'log4j', name: 'log4j', version: '1.2.15', transitive: false
         testCompile group: 'junit', name: 'junit', version: '4.9', transitive: false
 }

I am using Java to write custom plugin in similar lines to JavaPlugin. Something like

public class MyGradlePlugin implements Plugin<Project>{
         public void apply(Project project) {
                 project.getPlugins().apply(JavaPlugin.class);
                          ............
             }
 }

Now how do I set sourceSets, repositories, version, group etc using Java?

Regards,

Pranav


(Luke Daley) #2

Hi Pranav,

My first question is whether or not you need to write your plugin in Java. The primary benefit of writing your plugin in Groovy is that you can use all of the exact same syntax that you use in your build.gradle file in your plugin, which makes it much easier for future maintenance of the plugin as anyone familiar with using Gradle will understand what it is doing.

That said, it is possible to use Java. However, you’ll have to go underneath the DSL layer and start working directly with the objects that support it.

For example, to add some repositories you’d need to work directly with the RepositoryHandler.

You can get it via: http://gradle.org/current/docs/javadoc/org/gradle/api/Project.html#getRepositories()

Here’s its API: http://gradle.org/current/docs/javadoc/org/gradle/api/artifacts/dsl/RepositoryHandler.html

For each case you are going to have to follow a similar process.

If you can at all manage it, I’d recommend using Groovy for your plugins for the reasons I cited above.


(Pranav K Varshney) #3

Hi Luke,

Thanks for the reply. I have written the following. Now how do I set sourceSet? Basically the following?

sourceSets {
    main {
        java {
            srcDir 'src/main'
        }
    }
    test {
            java {
                srcDir 'src/test'
            }
    }
}
package com.pg.gradle.plugins
  import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin;
  class PGPlugin implements Plugin<Project> {
 Project project
 public void apply(Project project) {
  project.getPlugins().apply(JavaPlugin.class);
  this.project = project
  project.version = 36.0
  project.group = 'com.xxx.inhouse'
  project.repositories {
   mavenRepo name: 'xxx', urls: "http://speke.xxx.co.in:8080/artifactory/xxx"
  }
 }
}

Regards, Pranav


(Luke Daley) #4

Pranav, that looks like Groovy code.

You would just do:

project.sourceSets {
    main {
        java {
            srcDir 'src/main'
        }
    }
    test {
        java {
          srcDir 'src/test'
        }
    }
}

(Pranav K Varshney) #5

Thanks Luke.

I am using Eclipse with Groovy plugin to write code. I am new to it and have some doubts. “project” dot ctrl + space (content assist / auto-complete) gives me options for version, group, repositories but not for sourceSets. Am I doing something wrong or have I missed including any library in build path? Apart from Groovy libraries I have included the following -

gradle-core-1.0-milestone-3.jar
gradle-plugins-1.0-milestone-3.jar
gradle-maven-1.0-milestone-3.jar
core-3.1.1.jar

How to fix this issue?

My custom plugin looks something like -

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.MavenPlugin
  class PGPlugin implements Plugin<Project> {
 Project project
 public void apply(Project project) {
  project.getPlugins().apply(JavaPlugin.class)
  project.getPlugins().apply(MavenPlugin.class)
  this.project = project
  project.version = 36.0
  project.group = 'com.xxx.inhouse'
  project.repositories {
   mavenRepo name: 'xxx', urls: "http://speke.xxx.co.in:8080/artifactory/xxx"
  }
                    project.sourceSets {
   main {
    java {
     srcDir 'src/main'
    }
   }
   test {
    java {
      srcDir 'src/test'
    }
   }
  }
 }
}

Regards, Pranav


(Luke Daley) #6

Eclipse can’t autocomplete it because it’s not part of Project’s API.

Gradle makes heavy use of dynamism to enable the DSL, and currently IDEs do not understand this very well.

You’re best strategy is to write your plugin like you would write your build script, using “project.” to derefence any top level method calls/properties.

As modern Java IDEs get better at working with DSLs over time you’ll get more and more completion, but right now it’s not as good as it is with Java.