Over a million developers have joined DZone.

Gradle Tooling API Introduction

Gradle has developed an API to query the Gradle project artifacts like taskNames, dependencies, etc. It allows users to execute builds programatically. Read on to learn more.

· Integration Zone

Learn how API management supports better integration in Achieving Enterprise Agility with Microservices and API Management, brought to you in partnership with 3scale

Gradle has developed an API to query the Gradle project artifacts like taskNames, dependencies, etc. It allows users to execute builds programatically.

According to official Gradle Website documentation:

"The Tooling API provides a programmatic interface to Gradle, allowing the execution of builds and querying of the build model"

Features of Tooling API

  • You can query Gradle for the details of a build, including: the project hierarchy, the project dependencies, external dependencies (including source and Javadoc jars), source directories, and tasks of each project.
  • You can execute a build and listen to stdout and stderr logging and progress (e.g. the stuff shown in the status bar when you run on the command line).
  • Tooling API can download and install the appropriate Gradle version, similar to the wrapper. Bear in mind that the tooling API is wrapper aware, so you should not need to configure a Gradle distribution directly.
  • The implementation is lightweight, with only a small number of dependencies. It is also a well-behaved library, and makes no assumptions about your classloader structure or logging configuration. This makes the API easy to bundle in your application.

While you can get more details about the theory on the Gradle website this article is about practical implementation of this API. I would also like to discuss the approach I took to learn this API.

I thought it was really simple task to write a sample "Hello World" program, but initially I faced a few issues. I had to find correct dependencies. As one jar has a dependency on another I received lots of this: 

ClassNotFoundException

What to Expect From This Article

My aim of writing this article is to provide enough information/examples which will make it easy for you to work with this API successfully. 

Gradle Dependencies 

You will require a minimum of the below dependencies to start writing your first example.

  1. gradle-base-services-2.1.jar

  2. gradle-core-2.1.jar

  3. gradle-messaging-2.1.jar

  4. gradle-resources-2.1.jar

  5. gradle-tooling-api-2.1.jar

  6. gradle-wrapper-2.1.jar

  7. guava-jdk5-17.0.jar

  8. slf4j-api-1.7.5.jar

Let's write our first progam.

  •    Get the TaskNames defined for project 

Assuming build.gradle for project is defined as:  

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'war'
defaultTasks 'clean', 'build', 'war', 'copyDepJars'
sourceCompatibility = 1.6
repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile 'org.springframework:spring-core:4.2.3.RELEASE'
    compile 'org.springframework.amqp:spring-rabbit:1.5.2.RELEASE'
}

task copyDepJars(type: Copy) {
    from configurations.compile
    into 'C:\\Users\\athakur\\Desktop\\lib'
}

 This program finds all tasks defined for projects.

public class GradleConnector {    
  private org.gradle.tooling.GradleConnector connector;    
  public GradleConnector(String gradleInstallationDir, String projectDir) {        
    File gradleInstallationDir1 = new File(gradleInstallationDir);        
    connector = org.gradle.tooling.GradleConnector.newConnector();        
    connector.useInstallation(gradleInstallationDir1);        
    connector.forProjectDirectory(new File(projectDir));    
  }    

  public String getGradleVersion() {        
    return GradleVersion.current().getVersion();    
  }    

  public List<String> getGradleTaskNames() {        
    List<String> taskNames = new ArrayList<>();        
    List<GradleTask> tasks = getGradleTasks();        
    return tasks.stream().map(task -> task.getName()).collect(Collectors.toList());    
  }    
  public List<GradleTask> getGradleTasks() {        
    List<GradleTask> tasks = new ArrayList<>();        
    ProjectConnection connection = connector.connect();        
    try {            
      GradleProject project = connection.getModel(GradleProject.class);            
      for (GradleTask task : project.getTasks()) {                
        tasks.add(task);            
      }        
    } finally {            
      connection.close();        
    }        
    return tasks;    
  }
}

Let's talk about this sample program. 

Class GradleVersion gives us the version number of gradle installed. It refers to the directory mentioned in useInstallation() method of GradleConnector class. 

connector.useInstallation(gradleInstallationDir)

GradleConnector

This is an important class of tooling API.

connector.forProjectDirectory(new File(projectDir));

This method allows us to set the Gradle project directory for which we need to query using the Gradle API. We can connect to an external project or to the current one. To be able to connect with current project you should use: 

connector.forProjectDirectory(".");

I think it's a great feature, enabling you to query/build a current project or any project which is external to your program.

Getting a connection to the project:


ProjectConnection connection = connector.connect();
try {    
  GradleProject project = connection.getModel(GradleProject.class);        
    for(GradleTask task : project.getTasks()){            
          tasks.add(task);        
       }
  } finally {    
  connection.close();
  }

Calling connect() method gives you the connection(ProjectConnection) object .

GradleProject has method getTasks(); which returns to you all the tasks defined for a project. 

For example, if you call getGradleTaskNames() Method, you will get list of TaskNames equivalent to: 

Arrays.asList("spring-core-4.2.3.RELEASE.jar",        
              "spring-rabbit-1.5.2.RELEASE.jar","commons-logging-1.2.jar",        
               "spring-messaging-4.2.2.RELEASE.jar","spring-retry-1.1.2.RELEASE.jar",       
              "spring-amqp-1.5.2.RELEASE.jar","spring-tx-4.2.2.RELEASE.jar",        
              "http-client-1.0.0.RELEASE.jar","spring-web-4.2.2.RELEASE.jar",        
              "amqp-client-3.5.6.jar","spring-context-4.2.2.RELEASE.jar",        
              "spring-beans-4.2.2.RELEASE.jar","httpclient-4.3.6.jar",        
              "jackson-databind-2.5.1.jar","spring-aop-4.2.2.RELEASE.jar",       
              "spring-expression-4.2.2.RELEASE.jar","httpcore-4.3.3.jar",        
              "commons-codec-1.6.jar","jackson-annotations-2.5.0.jar",        
              "jackson-core-2.5.1.jar","aopalliance-1.0.jar")

Build a Gradle Project

Add the below method in GradleConnector class to build the project.

public boolean buildProject() 
  {    
    ProjectConnection connection = connector.connect();    
    BuildLauncher build = connection.newBuild();    
    try {
            build.run();
        }finally {
            connection.close();
        }   
    return true;
}

By default, it will execute all the tasks defined in the build.gradle file.

If you want to execute specific tasks use the method below.

public boolean buildProject(String... tasks) {   
  ProjectConnection connection = connector.connect();    
  BuildLauncher build = connection.newBuild();    
  build.forTasks(tasks);    
   try {        
     build.run();    
   }finally {       
     connection.close();   
   }
  return true;
}

Note: Dont forget to close the connection. 

I have shared the sample working project on Github https://github.com/ShirishkumarBari/LearnGradleToolingApi

Please feel free to download it and provide any suggestions you may have.

I plan on adding more examples and explanations in the next article... until then, stay tuned.

Unleash the power of your APIs with future-proof API management - Create your account and start your free trial today, brought to you in partnership with 3scale.

Topics:
gradle:goodness ,api

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}