• See all tags

Conditional dependencies with Gradle

21 March 2022

Tags: gradle dependencies

Introduction

If you ever wrote a Gradle plugin for a framework (e.g Micronaut ) or a plugin which needs to add dependencies if the user configures a particular flag, then it is likely that you’ve faced some ordering issues.

For example, imagine that you have this DSL:

Obviously, at some point in time , you have to figure out if the property useNetty is set in order to transparently add dependencies. A naive solution is to use the good old afterEvaluate block. Many plugins do this:

The problem is that while afterEvaluate seems to fix the problem, it’s just a dirty workaround which defers the problem to a later stage: depending on the plugins which are applied, which themselves could use afterEvaluate , your block may, or may not, see the "final" configuration state.

In a previous post , I introduced Gradle’s provider API. In this post, we’re going to show how to use it to properly fix this problem.

Using providers for dependencies

Let’s start with the easiest. It’s a common requirement of a plugin to provide the ability to override the version of a runtime. For example, the checkstyle plugin would, by default, use version of checkstyle by convention, but it would still let you override the version if you want to use a different one.

Micronaut provides a similar feature:

The Micronaut dependencies to be added on the user classpath depend on the value of the version in our micronaut extension. Let’s see how we can implement this. Let’s create our Gradle project (we’re assuming that you have Gradle 7.4 installed):

Now we’re going to create a folder for our build logic, which will contain our plugin sources:

Let’s update the settings.gradle file to include that build logic:

For now our plugin is an empty shell, so let’s create its build.gradle file so that we can use a precompiled script plugin .

Now let’s define our extension, which is simply about declaring an interface :

It’s now time to create our plugin: precompiled script plugins are a very easy way to create a plugin, simply by declaring a file in build-logic/src/main/groovy which name ends with .gradle :

Create our extension, named "micronaut"

Assign a default value to the "version" property

By convention, our plugin id will be my.plugin (it’s derived from the file name). Our plugin is responsible for creating the extension, and it assigns a convention value to the version property: this is the value which is going to be used if the user doesn’t declare anything explicitly.

Then we can use the plugin in our main build, that is, in the lib project:

If we look at the lib compile classpath, it will not include any Micronaut dependency for now:

Our goal is to add a dependency which is derived from the version defined in our Micronaut extension, so let’s do this. Edit our build-logic plugin:

Now let’s run our dependencies report again:

Victory! Now we can see our micronaut-core dependency. How did we do this?

Note that instead of using afterEvaluate , what we did is adding a dependency , but instead of using the traditional dependency notation, we used a provider : the actual dependency string is computed only when we need it . We can check that we can actually configure the version via our extension by editing our build file:

Maybe add, maybe not!

In the previous example, we have systematically added a dependency, based on the version defined in the extension. What if we want to add a dependency if a property is set to a particular value? For this purpose, let’s say that we define a runtime property which will tell what runtime to use. Let’s add this property to our extension:

Now let’s update our plugin to use that property, and add a dependency based on the value of the runtime property:

Add a dependency if the runtime is set to netty

Add a dependency if the runtime is set to tomcat

But do nothing if the runtime isn’t set

The trick, therefore, is to return null in the provider in case no dependency needs to be added. So let’s check first that without declaring anything, we don’t have any dependency added:

Now let’s switch to use tomcat :

Note how the dependency on Tomcat is added!

More complex use cases are supported!

We’ve shown how to add a dependency and derive the dependency notation from the version defined in our extension. We’ve then seen how we could add a dependency, or not, based on the value of an extension: either return a supported dependency notation , or null if nothing needs to be added.

Gradle actually supports more complex cases, that I will let as an exercise to the reader. For example:

adding a dependency provider and configure its rich version (see DependencyHandler#addProvider ).

adding a list of dependencies, instead of a single dependence (see Configuration#getDependencies and DependencySet#addAllLater ).

computing a dependency from two or more providers (see Provider#zip ).

In this post, we’ve seen how to leverage Gradle’s provider API to properly implement plugins which need to add dependencies conditionally. This can either mean that they need to add dependencies which version depend on some user configuration, or even full dependency notations which depend on configuration. The interest of using the provider API again lies in the fact that it is lazy and therefore is (largely) immune to ordering issues: instead of relying on hooks like afterEvaluate which come with a number of drawbacks (reliability, ordering, interaction with other plugins), we rely on the fact that it’s only when a value is needed that it is computed. At this moment, we know that the configuration is complete, so we can guarantee that our dependencies will be correct.

Creative Commons License

Baked with JBake v2.6.6

How to skip a task if another task is executed in Gradle?

This page shows you how you can skip a task if another task is executed.

It can happen in a test development when you have some build task you don't want to execute in a dev setting but that you want to execute for a release or a test.

  • The example below is written in kotlin
  • We will skip the task if the release task is not started.

The task to skip

This is a simple exec task that logs the word hello world

The calling task

This task includes the dependent task based on a conditional value.

The conditional is true only if the task release is asked from the command line.

Excluding the calling task

You can even go further and exclude the calling task

Task Runner

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Gradle@2 - Gradle v2 task

  • 3 contributors

Build using a Gradle wrapper script.

gradleWrapperFile - Gradle wrapper Input alias: wrapperScript . string . Required. Default value: gradlew .

Specifies the gradlew wrapper's location within the repository that will be used for the build. Agents on Windows (including Microsoft-hosted agents) must use the gradlew.bat wrapper. Agents on Linux or macOS can use the gradlew shell script. Learn more about the Gradle Wrapper .

workingDirectory - Working directory Input alias: cwd . string .

Specifies the working directory to run the Gradle build. The task uses the repository root directory if the working directory is not specified.

options - Options string .

Specifies the command line options that will be passed to the Gradle wrapper. See Gradle Command Line for more information.

tasks - Tasks string . Required. Default value: build .

The task(s) for Gradle to execute. A list of task names should be separated by spaces and can be taken from gradlew tasks issued from a command prompt.

See Gradle Build Script Basics for more information.

publishJUnitResults - Publish to Azure Pipelines boolean . Default value: true .

Publishes JUnit test results produced by the Gradle build to Azure Pipelines. The task publishes each test results file matching Test Results Files as a test run in Azure Pipelines.

publishJUnitResults - Publish to Azure Pipelines/TFS boolean . Default value: true .

publishJUnitResults - Publish to TFS/Team Services boolean . Default value: true .

testResultsFiles - Test results files string . Required when publishJUnitResults = true . Default value: **/TEST-*.xml .

The file path for test results. Wildcards can be used. For example, **/TEST-*.xml for all XML files whose name starts with TEST- .

testResultsFiles - Test results files string . Required when publishJUnitResults = true . Default value: **/build/test-results/TEST-*.xml .

testRunTitle - Test run title string . Optional. Use when publishJUnitResults = true .

Provides a name for the JUnit test case results for this build.

codeCoverageToolOption - Code coverage tool Input alias: codeCoverageTool . string . Allowed values: None , Cobertura , JaCoCo . Default value: None .

Specifies a code coverage tool to determine the code that is covered by the test cases for the build.

codeCoverageClassFilesDirectories - Class files directories Input alias: classFilesDirectories . string . Required when codeCoverageTool != None . Default value: build/classes/main/ .

The comma-separated list of directories containing class files and archive files (.jar, .war, and more). Code coverage is reported for class files in these directories. Normally, the task searches classes under build/classes/java/main (for Gradle 4+), which is the default class directory for Gradle builds.

codeCoverageClassFilesDirectories - Class files directories Input alias: classFilesDirectories . string . Required when codeCoverageTool = false . Default value: build/classes/main/ .

codeCoverageClassFilter - Class inclusion/exclusion filters Input alias: classFilter . string . Optional. Use when codeCoverageTool != None .

The comma-separated list of filters to include or exclude classes from collecting code coverage. For example: +:com.* , +:org.* , -:my.app*.* .

codeCoverageFailIfEmpty - Fail when code coverage results are missing Input alias: failIfCoverageEmpty . boolean . Optional. Use when codeCoverageTool != None . Default value: false .

Fails the build if code coverage did not produce any results to publish.

codeCoverageGradle5xOrHigher - Gradle version >= 5.x Input alias: gradle5xOrHigher . boolean . Optional. Use when codeCoverageTool = JaCoCo . Default value: true .

Set this to 'true' if gradle version is >= 5.x.

javaHomeOption - Set JAVA_HOME by Input alias: javaHomeSelection . string . Required. Allowed values: JDKVersion (JDK Version), Path . Default value: JDKVersion .

Sets JAVA_HOME by selecting a JDK version that the task discovers during builds or by manually entering a JDK path.

jdkVersionOption - JDK version Input alias: jdkVersion . string . Optional. Use when javaHomeSelection = JDKVersion . Allowed values: default , 1.17 (JDK 17), 1.11 (JDK 11), 1.10 (JDK 10 (out of support)), 1.9 (JDK 9 (out of support)), 1.8 (JDK 8), 1.7 (JDK 7), 1.6 (JDK 6 (out of support)). Default value: default .

Attempts to discover the path to the selected JDK version and set JAVA_HOME accordingly.

jdkVersionOption - JDK version Input alias: jdkVersion . string . Optional. Use when javaHomeSelection = JDKVersion . Allowed values: default , 1.11 (JDK 11), 1.10 (JDK 10 (out of support)), 1.9 (JDK 9 (out of support)), 1.8 (JDK 8), 1.7 (JDK 7), 1.6 (JDK 6 (out of support)). Default value: default .

jdkVersionOption - JDK version Input alias: jdkVersion . string . Optional. Use when javaHomeSelection = JDKVersion . Allowed values: default , 1.9 (JDK 9), 1.8 (JDK 8), 1.7 (JDK 7), 1.6 (JDK 6). Default value: default .

jdkDirectory - JDK path Input alias: jdkUserInputPath . string . Required when javaHomeSelection = Path .

Sets JAVA_HOME to the given path.

jdkArchitectureOption - JDK architecture Input alias: jdkArchitecture . string . Optional. Use when jdkVersion != default . Allowed values: x86 , x64 . Default value: x64 .

Supplies the JDK architecture (x86 or x64).

gradleOptions - Set GRADLE_OPTS Input alias: gradleOpts . string . Default value: -Xmx1024m .

Sets the GRADLE_OPTS environment variable, which is used to send command-line arguments to start the JVM. The xmx flag specifies the maximum memory available to the JVM.

sonarQubeRunAnalysis - Run SonarQube or SonarCloud Analysis Input alias: sqAnalysisEnabled . boolean . Default value: false .

This option has changed from version 1 of the Gradle task to use the SonarQube and SonarCloud marketplace extensions. Enable this option to run SonarQube or SonarCloud analysis after executing tasks in the Tasks field. You must also add a Prepare Analysis Configuration task from one of the extensions to the build pipeline before this Gradle task.

sqGradlePluginVersionChoice - SonarQube scanner for Gradle version string . Required when sqAnalysisEnabled = true . Allowed values: specify (Specify version number), build (Use plugin applied in your build.gradle). Default value: specify .

Specifies the SonarQube Gradle plugin version to use. Declare the version in the Gradle configuration file, or specify a version with this string.

sonarQubeGradlePluginVersion - SonarQube scanner for Gradle plugin version Input alias: sqGradlePluginVersion . string . Required when sqAnalysisEnabled = true && sqGradlePluginVersionChoice = specify . Default value: 2.6.1 .

Contains the version number of the SonarQube Gradle plugin .

checkStyleRunAnalysis - Run Checkstyle Input alias: checkstyleAnalysisEnabled . boolean . Default value: false .

Runs the Checkstyle tool with the default Sun checks. Results are uploaded as build artifacts.

findBugsRunAnalysis - Run FindBugs Input alias: findbugsAnalysisEnabled . boolean . Default value: false .

Uses the FindBugs static analysis tool to look for bugs in the code. Results are uploaded as build artifacts. In Gradle 6.0, this plugin was removed . Use the SpotBugs plugin instead.

pmdRunAnalysis - Run PMD Input alias: pmdAnalysisEnabled . boolean . Default value: false .

Uses the PMD Java static analysis tool to look for bugs in the code. The results are uploaded as build artifacts.

spotBugsAnalysis - Run SpotBugs Input alias: spotBugsAnalysisEnabled . boolean . Default value: false .

Runs spotBugs when true . This plugin works with Gradle v5.6 or later. Learn more about using the SpotBugs Gradle plugin . The plugin may work in an unexpected way or may not work at all with an earlier Gradle version.

spotBugsGradlePluginVersionChoice - Spotbugs plugin version string . Required when spotBugsAnalysisEnabled = true . Allowed values: specify (Specify version number), build (Use plugin applied in your build.gradle). Default value: specify .

Specifies the SpotBugs Gradle plugin version to use. The version can be declared in the Gradle configuration file, or the version can be specified in this string.

spotbugsGradlePluginVersion - Version number string . Required when spotBugsAnalysisEnabled = true && spotBugsGradlePluginVersionChoice = specify . Default value: 4.7.0 .

Contains the version number of the SpotBugs Gradle plugin .

Task control options

All tasks have control options in addition to their task inputs. For more information, see Control options and common task properties .

Output variables

There is a newer version of this task available at Gradle@3 .

Configuration of the SonarQube analysis was moved to the SonarQube or SonarCloud extensions in the task Prepare Analysis Configuration .

Use this task to build using a Gradle wrapper script.

How do I generate a wrapper from my Gradle project?

The Gradle wrapper allows the build agent to download and configure the exact Gradle environment that is checked into the repository without having any software configuration on the build agent itself other than the JVM.

Create the Gradle wrapper by issuing the following command from the root project directory where your build.gradle resides:

jamal@fabrikam> gradle wrapper

Upload your Gradle wrapper to your remote repository.

There is a binary artifact that is generated by the gradle wrapper (located at gradle/wrapper/gradle-wrapper.jar ). This binary file is small and doesn't require updating. If you need to change the Gradle configuration run on the build agent, you update the gradle-wrapper.properties .

The repository should look something like this:

How do I fix timeouts when downloading dependencies?

To fix errors such as Read timed out when downloading dependencies, users of Gradle 4.3+ can change the timeout by adding -Dhttp.socketTimeout=60000 -Dhttp.connectionTimeout=60000 to Options . This increases the timeout from 10 seconds to 1 minute.

Build your Java app with Gradle

Requirements

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

How to specify conditional Source and Destination directory for Copy task?

I want to set the destinationDir at runtime for Copy task.

Here is the scenario I am trying:

I have on text file where I am specifying the list of files. Content of temp.lst :

Here I want to copy the abc.h and pqr.h to DIR1/inc, similarly copy the xyz.h to DIR2 . ( Depends on the first string of each line) I am splitting the line with separator as " : " and I want destination Path to be dynamic depends on the first word of each line.

Below is the Task I am using to copy these listed file:

The problem I am seeing here is, it is always coping all listed files in temp.lst to the DIR2 directory.

Could you please help me to resolve this issue.

Please let me know if you need more information.

Thanks Mandar

Each time you call the into() method you are resetting the target destination directory. Only the last call has any effect. This is in contrast to each call to from(), which adds elements to an internal collection.

Take a look at the CopyTask’s usage of DefaultCopySpec:

public DefaultCopySpec into(Object destDir) {

this.destDir = destDir;

return this;

public CopySpec from(Object… sourcePaths) {

for (Object sourcePath : sourcePaths) {

this.sourcePaths.add(sourcePath);

I don’t think you’ll be able to do this with just one Copy task. I think you’ll need one instance of the task per destination.

Perhaps Task A just determines which files go to which destination, stores that in 2 collections for files headed into DIR1 and DIR2, and then Task B does the copy to DIR1 and Task C does the copy to DIR2. Tasks B and C could depend on Task A. You could even add a Task D which depends on B and C to do the whole thing via running a single task.

IMAGES

  1. How do I compile the project via gradle/maven?

    conditional task gradle

  2. Conditional Gradle Configuration by Build Variant

    conditional task gradle

  3. The Gradle build system- Tutorial

    conditional task gradle

  4. Getting Started with Gradle

    conditional task gradle

  5. Conditional Formatting Basics : Tutorial for Beginners

    conditional task gradle

  6. Conditional Probability Digital Task Cards

    conditional task gradle

VIDEO

  1. un conditional place 😰 Very risky working please support me

  2. Gradle dependencies

  3. Gradle Plugins

  4. SpringBoot x Gradle Task

  5. Conditional Formatting

  6. Gradle Task로 Tomcat 실행하기

COMMENTS

  1. conditional statements

    1 Answer Sorted by: 2 You sample shows that the build task is being created. Generally, this task is already created for you when you apply one of the provided Gradle plugins such as the Java Plugin. The Base Plugin is generally applied when applying a plugin Gradle provides. Some use cases you may apply the plugin manually.

  2. How to Configure Conditional Dependencies in Gradle

    1. Overview In this tutorial, we'll see how we can configure conditional dependencies in our Gradle projects. 2. Project Setup We'll be setting up a multi-module project for the demonstration. Let's head over to start.spring.io and create our root project conditional-dependency-demo. We'll use Gradle and Java along with Spring Boot.

  3. Authoring Tasks

    Gradle supports tasks that have their own properties and methods. Such tasks are either provided by you or built into Gradle. Task outcomes When Gradle executes a task, it can label the task with different outcomes in the console UI and via the Tooling API.

  4. Using Tasks

    The work that Gradle can do on a project is defined by one or more tasks. A task represents some independent unit of work that a build performs. This might be compiling some classes, creating a JAR, generating Javadoc, or publishing some archives to a repository.

  5. Part 2: Running Gradle Tasks

    Step 1. Viewing available Tasks A task is a basic unit of work that can be done by Gradle as part of the build. In the tutorial directory, enter the command below to list all the available tasks in the project: $ ./gradlew tasks The list includes tasks contributed by the application plugin and the plugin it applies:

  6. Cédric Champeau's blog: Conditional dependencies with Gradle

    Conditional dependencies with Gradle 21 March 2022 Tags: gradle dependencies Introduction If you ever wrote a Gradle plugin for a framework (e.g Micronaut) or a plugin which needs to add dependencies if the user configures a particular flag, then it is likely that you've faced some ordering issues. For example, imagine that you have this DSL:

  7. Understanding Gradle Tasks

    A Task is an executable piece of code that contains sequences of actions. Actions are added to a Task via the doFirst {} and doLast {} closures. A list of available tasks can be accessed by executing ./gradlew tasks. To better understand the structure, syntax, and relationship between Gradle project entities, look at my earlier article.

  8. How to skip a task if another task is executed in Gradle?

    tasks.register<Exec> ("ConditionalTask") { // gradle.startParameter.taskNames contains the name of tasks given at the command line val gradleReleaseTaskStarted = gradle.startParameter.taskNames.contains ("release") if (gradleReleaseTaskStarted) { dependsOn (halloWorldTask) } commandLine ("cmd", "/c", "echo", "hello from conditional") only...

  9. Best practices for authoring maintainable builds

    Example 1. A build script using conditional logic to create a task build.gradle.kts if (project.findProperty ("releaseEngineer") != null) { tasks.register ("release") { doLast { logger.quiet ("Releasing to production...") // release the artifact to production } } } build.gradle

  10. Gradle Custom Task

    The main goal of the above task is just to print text "Welcome in the Baeldung!". We can check if this task is available by running gradle tasks -all command: gradle tasks --all. The task is on the list under the group Other tasks: Other tasks ----------- welcome. It can be executed just like any other Gradle task:

  11. Conditional Gradle Configuration by Build Variant

    The name of the task, which was assembleNoDynatraceDebug, in our case, is passed as a parameter to the Gradle script. Therefore, it is only necessary to verify the task name to make our important decision. Since Gradle configuration scripts are simply Groovy files at heart, this task became trivial.

  12. Conditional Gradle dependency based on task output

    jjustinic (James Justinic) January 31, 2022, 5:47am #2 Dependencies really should not be dynamic. If you have code to generate flavors, use the same code to add the appropriate dependencies. When you create a flavor, there are also configurations created specifically for that flavor.

  13. Writing Tasks

    The simplest and quickest way to create a custom task is in a build script: To create a task, inherit from the DefaultTask class and implement a @TaskAction handler: build.gradle.kts abstract class CreateFileTask : DefaultTask() { @TaskAction fun action() { val file = File("myfile.txt") file.createNewFile()

  14. Conditional task dependencies

    bgeradz (Genadz Batsyan) December 23, 2021, 7:38pm 1 Let's say I have 3 tasks, clean, build and deploy In order to deploy I need to first clean and then build Using dependsOn, I would need to make deploy depend on clean and build and also build depend on clean to force the correct order.

  15. Gradle@2

    Normally, the task searches classes under build/classes/java/main (for Gradle 4+), which is the default class directory for Gradle builds. codeCoverageClassFilter - Class inclusion/exclusion filters Input alias: classFilter .

  16. Custom conditional configuration for Gradle project

    1 Answer Sorted by: 40 taskGraph.hasTask () tells if a task is in the task execution graph, that is whether it will get executed. Because the task execution graph is only created after the configuration phase, this method has to be called from a whenReady callback (or in the execution phase): gradle.taskGraph.whenReady { graph ->

  17. How to specify conditional Source and Destination ...

    Perhaps Task A just determines which files go to which destination, stores that in 2 collections for files headed into DIR1 and DIR2, and then Task B does the copy to DIR1 and Task C does the copy to DIR2. Tasks B and C could depend on Task A. You could even add a Task D which depends on B and C to do the whole thing via running a single task.

  18. Customizing publishing

    If you use artifact() with an archive task, Gradle automatically populates the artifact's metadata with the classifier and extension properties from that task. ... Gradle allows you to skip any task you want based on a condition via the Task.onlyIf(String, org.gradle.api.specs.Spec) method. The following sample demonstrates how to implement ...

  19. groovy

    Can someone tell me how could I write the if else condition in the gradle script I mean i have two different types of zip files one is LiceseGenerator-4.0.0.58 and other one is CLI-4...60.My deployment script is working fine but I am using the shell script to do this and I want everything in gradle instead of doing it in the shell script.I wan...