Show List

Create and Build Project Using Gradle

In this example we are going to create a Java project using Gradle. IntelliJ provides very good integration with Gradle so we will be using this IDE. 

Create Project Structure Using Gradle Settings File

Create an empty folder and open in IntelliJ.
Now add a file with name "settings.gradle.kts". It is the entry point of the project and will help IntelliJ understand that it is a Gradle project. Extension .kts is for Kotlin language we are going to use for this settings file.
Click on the "Load Gradle Project" from IntelliJ suggestions. IntelliJ automatically adds some file. 
  • gradlew is Gradle wrapper file. There is one wrapper for UNIX and other for Windows to start the Gradle wrapper.
  • gradle-wrapper.jar contains implementation for wrapper.
  • gradle-wrapper.properties to configure the wrapper.
Gradle settings file is used to describe the project. It is the entry point of the project. In Gradle the projects are divided in to sub projects (Software components).

Here we are adding three sub project folders and including them in the properties file.
Adding the blocks to locate the plugins, dependencies and giving fixed name to the project.

settings.gradle.kts
//Plugins to implement gradle interfaces
pluginManagement{
repositories.gradlePluginPortal()
}


//Location to potentially find components/dependencies
dependencyResolutionManagement{
repositories.mavenCentral();
}

//Giving a fixed name to the build. If not provided it will be picked up as the project folder name.
rootProject.name = "my-sample-project"

//Include sub projects
include("app-layer")
include("business-layer")
include("data-layer")

Build Sub Projects

Our sub projects app-layer, business-layer and data-layer are currently empty. So Gradle would not know what to do with these. Lets add a Java class file src/main/java/com/demo/DataModel.java and build.gradle.kts file. And load the gradle changes.
Now adding the plugin information and java version. As soon as Gradle is reloaded after adding java plugin, Gradle recognizes the project as java project and marks the packages.

build.gradle.kts
plugins{
//This is a project that has java code that can be built and can be used in another project
id("java-library") //plugin to compile, test Java code
}

//Configure java version
java{
toolchain.languageVersion.set(JavaLanguageVersion.of(11));
}
We can add the build.gradle.kts file with same details to app-layer and business-layer sub projects as well.

Creating convention plugin

We have three build.gradle.kts files used in the three sub projects. The files have some common configurations. These common configurations can be put in a convention plugin. Plugins that only reconfigure the existing plugins are called convention plugins.

To create a convention plugin, add a "plugins" folder under "gradle" directory. Create settings.gradle.kts file and add configuration.
Create a my-java-plugins folder and create build.gradle.kts file. Plugin info has been added in this file to tell gradle that we will be writing gradle plugin here.

Include "my-java-plugins" as sub project in the settings.gradle.kts file.
Now add the src/main/kotlin/my-plugin-file.gralde.kts file in my-java-plugins folder. In this plugin file now we can add the common configuration. 
Import this custom plugin by including gradle/plugins project in the pluginManagement section.
Now we can replace the plugin information in the build.gradle.kts file of data-layer, business-layer and app-layer 

Adding Dependency on Sub Projects

In our example Business layer is going to depend on Data layer and App layer is going to depend on both Data layer and Business layer.

Adding dependency in the build.gradle.kts file of business-layer sub project
Adding dependencies in build.gradle.kts file of  app-layer sub project:
Here are the java classes in the data layer, business layer and app layer.

DataModel.java
package com.demo;

public class DataModel {
private String name;

public DataModel(String name){
this.name = name;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
BusinessCls.java
package com.demo.bus;

import com.demo.DataModel;

public class BusinessCls {

public void displayName(DataModel dm){
System.out.println(dm.getName());
}
}
AppCls.java
package com.demo.app;

import com.demo.DataModel;
import com.demo.bus.BusinessCls;

public class AppCls {

public static void main(String[] args) {
new BusinessCls().displayName(new DataModel("Full Name"));
}
}
We can also specify the main application if we are using "application" plugin. For example, we can specify the main class in the build.gradle.kts of the app-layer project.

build.gradle.kts
We can run the application now using the Gradle view on IntelliJ and see the output on the console.

Registering a task using existing task implementation

In this example we are registering a task to package the jars and run time dependencies. We are using existing "Zip" task. 

After the code has been added, do a gradle sync using the Gradle view. The new task will appear under the group name provided for the task.
When the task is run, the output can be seen in the "distribution" folder.

Register a task with own build logic

Here is an example of task registered to count jars used in the application. 

Here CountAppJars is not an existing task in Gradle so we are going to create it as a Java class under my-java-plugins/src/main/java folder.

CountAppJars.java
import org.gradle.api.DefaultTask;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.Set;

public abstract class CountAppJars extends DefaultTask {

@InputFiles
public abstract ConfigurableFileCollection getAllJars();
// Gradle will get the jars using this interface

@OutputFile
public abstract RegularFileProperty getCountFile();

@TaskAction
public void doCount() throws IOException {
Set<File> jarFiles = getAllJars().getFiles();
int count = jarFiles.size();
File out = getCountFile().get().getAsFile();
Files.write(out.toPath(), Collections.singleton("" + count));
}
}
Here existing interfaces ConfigurableFileCollection is used to get the jars. Method doCount counts the number of jars.

When the task is run from the Gradle view on IntelliJ, the output can be seen under output folder.

Source Code:

https://github.com/it-code-lab/gradle-demo-project

    Leave a Comment


  • captcha text