banner
jzman

jzman

Coding、思考、自觉。
github

Java Gradle Plugin in the Gradle Series

In the previous articles, we learned the basics of Gradle build tasks. It is recommended to read the earlier articles:

In the previous article, we learned about Gradle plugins and how to customize a Gradle plugin. This article mainly focuses on the knowledge related to the Java Gradle plugin, as the content related to the Java Gradle plugin is also the foundation for the Android Gradle plugin. Using Gradle to build projects is essentially to help developers perform some repetitive tasks, such as configuring third-party dependencies, compiling source files, unit testing, packaging, and releasing. Using the corresponding Gradle plugins can facilitate project building and improve development efficiency to a certain extent. The main content we will learn today includes:

  1. Using the Java Gradle plugin
  2. Project structure conventions for the Java plugin
  3. Configuring third-party dependencies
  4. How to build a Java project
  5. Concept of SourceSet
  6. Tasks that can be added by the Java plugin
  7. Properties that can be added by the Java plugin
  8. Multi-project builds
  9. Publishing artifacts

Using the Java Gradle Plugin#

To use a Gradle plugin, the Project's apply() method is used:

//java is the plugin id for the Java Gradle plugin
apply plugin:'java'

After using the Java plugin, default settings and conventions will be added to the current project, such as the location of source code, the location of unit test code, the location of resource files, etc. Generally, the default settings can be used.

Project Structure Conventions for the Java Plugin#

The Java plugin sets some default settings and conventions. Let's take a look at the default project directory for a Java project, which is structured as follows:

JavaGradle
└─src
    ├─main
    │  ├─java
    │  └─resources
    └─test
        ├─java
        └─resources

In the above directory structure, src/main/java is the default directory for source code, src/main/resources is the directory for resource files and configuration files, and the directories under src/test are for storing corresponding unit test-related files. The main and test are two built-in source code sets in the Java Gradle plugin. In addition to these, other source code sets can be defined as follows:

apply plugin : 'java'

sourceSets{
    //Specify a new source code set
    vip{
        
    }
}

Then create the corresponding java and resources directories under src, with the file contents in these directories similar to the defaults. The default directory structure is as follows:

//Source code directory
src/vip/java
//Resource files directory
src/vip/resource

The above directory structure is the default implementation of the Java Gradle plugin. Of course, specific directory locations can also be modified, as configured below:

sourceSets{
    //Modify the default directories, the following are still the same as the default locations; modify as needed for other directories
    main{
        java{
            srcDir 'src/java'
        }
        
        resources{
            srcDir 'src/resources'
        }
        
    }
}

Configuring Third-Party Dependencies#

During development, third-party jar packages are often used, and at this point, dependency configuration for the jar packages is necessary. The type of repository and the location of the repository must be specified. When dependencies are configured, Gradle will look for the relevant dependencies in the configured repositories. The configuration of repositories and specific dependencies is as follows:

//Configure repository locations
repositories{
    //Repository types such as jcenter, ivy, maven central, maven local, maven private server, etc.
    mavenCentral()
    mavenLocal()
    maven {
        uri "http"//xxxx
    }
    jcenter()
    google()
    //...
}

//Configure specific dependencies
dependencies{
    //Three essential elements of a dependency: group, name, version
    //Corresponding to Maven's GAV (groupId, artifactId, version)
    
    //Full syntax
    compile group: 'com.squareup.okhttp3', name: 'okhttp', version:'3.0.1'
    //Short syntax
    compile 'com.squareup.okhttp3:okhttp:3.0.1'
}

In the above code, compile is a compile-time dependency. Gradle also provides other dependency types, as follows:

compile:Compile-time dependency
runtime:Runtime dependency
testCompile:Compile-time dependency for testing
testRuntime:Dependency only during test case execution
archives:Dependency for publishing artifacts, such as jar packages
default:Default dependency configuration

After Gradle 3.0, implementation and api will replace compile, but we won't elaborate on these two dependency methods here, as learning about the new API is not the focus of this article. The Java Gradle plugin also supports specifying different dependencies for different source code sets, as shown below:

//Configure different dependencies for different source code sets
dependencies{
    //Configuration format: sourceSetCompile, sourceSetRuntime
    mainCompile 'com.squareup.okhttp3:okhttp:3.0.1'
    vipCompile 'com.squareup.okhttp3:okhttp:2.0.1'
}

The above introduces the dependency of an external library. In addition, during development, there will also be module dependencies and file dependencies. In fact, module dependencies refer to dependencies on a subproject, while file dependencies generally refer to dependencies on jar packages.

In the article on the basics of Gradle build scripts, it has been established that to build a subproject, the include keyword must be used in the setting.gradle file to include the subproject. The same applies here; the projects to be depended upon must be included in the setting.gradle file, and then a specific subproject can be depended upon as follows:

//Depend on a subproject
dependencies{
    //Include ':childProject' in the setting.gradle file
    
    //Depend on the subproject
    compile project('childProject')
}

File dependencies mainly refer to jar package dependencies. Generally, jar packages are placed in the project's libs directory, and then the jar packages are referenced, as shown below:

//Depend on a jar package
dependencies{
    //Configure a single jar
    compile file('libs/java1.jar')
    //Configure multiple jars
    compile files('libs/java1.jar','libs/java2.jar')
    //Batch configure jars; by configuring the jar location, all files with the jar suffix will be included as dependencies in the project
    compile fileTree(dir:'libs',include:'*.jar')
}

How to Build a Java Project#

All operations in Gradle are based on tasks. The Java Gradle plugin also includes a series of tasks to help us build projects. By executing the build task, Gradle will start building the current project. You can use gradlew build to start executing the build task. Gradle will compile source code files, process resource files, generate jar packages, compile test code, run unit tests, etc.

For example, in Android development, there is a clean task. Executing the clean operation will delete the build folder and other files generated during the project build. If there is a compilation error, you can try to clean and then build. Additionally, there is a check task, which will be used during unit testing. The javadoc task can conveniently generate Java-formatted doc API documentation. The purpose of learning how to build a Java project is to prepare for learning how to build Android projects, so this concludes how to use Gradle to build a Java project.

Concept of SourceSet#

In this section, we will get to know SourceSet, which is the source code collection mentioned earlier. It is an abstract concept used by the Java Gradle plugin to describe and manage source code and its resources. It is a collection of Java source code files and resource files, allowing configuration of the location of source code files and setting properties of the source code set. Source sets can group and manage source code for different business purposes, such as the main and test source code directories provided by the Java Gradle plugin by default, one for business code and the other for unit testing, which is very convenient.

The Java Gradle plugin provides a sourceSet property and a sourceSet{} closure under Project to access and configure source sets. The sourceSet is a SourceSetContainer, and the common properties of source sets are as follows:

//For example, main, test, etc. represent the names of the source sets
name(String)
//Represents the directory for class files generated after compilation
output.classDir(File)
//Represents the directory for resource files generated after compilation
output.resourcesDir(File)
//Represents the classpath required for the source set after compilation
compileClasspath(FileCollection)
//Represents the Java source files of the source set
java(SourceDirectorySet)
//Represents the directory where the Java source files of the source set are located
java.srcDirs(Set)
//Represents the resource files of the source set
resources(SourceDirectorySet)
//Represents the directory where the resource files of the source set are located
resources.srcDirs(Set)

Below is how to set the output directory for the main source set:

//Set properties for a specific source set
sourceSets{
    main{
        //Source set name is read-only
        println name
        //Other property settings
        //From 4.0 onwards, this has been deprecated. The replacement is dir
        output.classesDir = file("a/b")
//        output.dir("a/b")
        output.resourcesDir = file("a/b")
        //....
    }
}

Tasks That Can Be Added by the Java Plugin#

The project build is still done through a series of tasks provided by Gradle plugins. Below are commonly used tasks in Java projects:

Task NameTypeDescription
Default source set common tasks
compileJavaJavaCompileIndicates using javac to compile Java source files
processResourcesCopyIndicates copying resource files to the generated resource file directory
classesTaskIndicates assembling the generated class and resource file directory
compileTestJavaJavaCompileIndicates using javac to compile test Java source files
processTestResourcesCopyIndicates copying resource files to the generated resource file directory
testClassesTaskIndicates assembling the generated test classes and related resource files
jarJarIndicates assembling jar files
javadocJavadocIndicates using javadoc to generate Java API documentation
uploadArchivesUploadIndicates uploading the build containing the Jar, configured using the archives{} closure
cleanDeleteIndicates cleaning up the generated directory files from the build
cleanTaskNameDeleteIndicates deleting files generated by a specified task, such as cleanJar which deletes files generated by the jar task
Custom source set tasks(SourceSet is the specific source set name)
compileSourceSetJavaJavaCompileIndicates using javac to compile the source code of the specified source set
processSouceSetResourcesCopyIndicates copying the resource files of the specified source set to the resource directory in the generated files
sourcesSetClassesTaskIndicates assembling the classes and resource files of the given source set

Properties That Can Be Added by the Java Plugin#

Common properties in the Java Gradle plugin are added to the Project, and these properties can be used directly, as follows:

Property NameTypeDescription
sourceSetsSourceSetContainerSource sets for Java projects, can be configured within closures
sourceCompatibilityJavaVersionJava version used to compile Java source files
targetCompatibilityJavaVersionJava version for the generated classes
archivesBaseNameStringName of the jar or zip file after packaging
manifestManifestUsed to access and configure the manifest file
libsDirFileDirectory for storing generated libraries
distsDirFileDirectory for storing generated release files

Multi-Project Builds#

Using Gradle for multi-project builds generally involves a main project depending on other submodule projects. Whether to build these subprojects is mainly configured in the setting.gradle file. Whether to use these subprojects must be configured in the main project. The three dependency methods mentioned earlier are library dependencies, project dependencies, and file dependencies. Here, project dependencies are used, and subprojects and allprojects are often used in multi-project configurations, as follows:

//Unified configuration for subprojects
subprojects{
    //Configure all subprojects to use the Java Gradle plugin
    apply plugin: 'java'
    //Configure all subprojects to use the Maven central repository
    repositories{
        mavenCentral()
    }
    //Other common configurations
    //...
}
//Unified configuration for all projects
allprojects{
    //Configure all projects to use the Java Gradle plugin
    apply plugin: 'java'
    //Configure all projects to use the Maven central repository
    repositories{
        mavenCentral()
    }
    //Other common configurations
    //...
}

Publishing Artifacts#

The products of Gradle builds are generally referred to as artifacts. A build can be a jar package, zip package, etc. So how do we publish artifacts? Below is how to publish a jar artifact to the local project folder or mavenLocal(), as follows:

/**
 * Publish artifacts to the project folder or mavenLocal()
 */
apply plugin : 'java'
//Task to generate jar, similar to custom wrapper
task publishJar(type:Jar)
//Artifact version
version '1.0.0'
//Artifacts are configured through the artifacts{} closure
artifacts{
    archives publishJar
}
//Artifact publishing and uploading
uploadArchives{
    repositories{
        flatDir{
            name 'libs'
            dirs "$projectDir/libs"
        }
        //Publish the build to mavenLocal()
        mavenLocal()
    }
}

Executing the uploadArchives task will generate the corresponding jar file in the appropriate location. The command is as follows:

//Execute uploadArchives
gradle uploadArchives

After successful execution, the generated jar file will be found in the project's libs directory, as shown below:

image

After successful execution, the generated jar file will also be found in the user's .m2/repository directory, as shown below:

image

Below is how to publish the jar to a built maven private server, with the code as follows:

/**
 * Publish artifacts to a maven private server
 */
apply plugin : 'java'
apply plugin : 'maven'
//Task to generate jar, similar to custom wrapper
task publishJar(type:Jar)
//Artifact version
version '1.0.0'
//Artifacts are configured through the artifacts{} closure
artifacts{
    archives publishJar
}
//Artifact publishing and uploading
uploadArchives{
    repositories{
        mavenDeployer{
            repository(url:'http://xxx'){
                //Repository username and password
                authentication(userName:'username',password:'pass')
            }
            snapshotRepository(url:'http://xxx'){
                authentication(userName:'username',password:'pass')
            }
        }
    }
}

The upload process also involves executing the uploadArchives task. If you have a maven private server, you can try it out. This concludes the study of the Java Gradle plugin, and the next article will officially begin the study of the Android Gradle plugin.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.