Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between registering and creating in Gradle Kotlin DSL

There are two methods of creating, i.e. tasks, in Gradle (5.0+):

tasks {
    val javadocJar by creating(Jar::class) {
        val javadoc by tasks

        from(javadoc)
        classifier = "javadoc"
    }
}

and

tasks {
    val javadocJar by registering(Jar::class) {
        val javadoc by tasks

        from(javadoc)
        classifier = "javadoc"
    }
}

Basically the same API, so what's the difference?

like image 528
madhead - StandWithUkraine Avatar asked Dec 06 '18 15:12

madhead - StandWithUkraine


People also ask

What does DSL mean in Gradle?

Simply, it stands for 'Domain Specific Language'. IMO, in gradle context, DSL gives you a gradle specific way to form your build scripts. More precisely, it's a plugin-based build system that defines a way of setting up your build script using (mainly) building blocks defined in various plugins.

Which are the two types of plugins in Gradle?

There are two general types of plugins in Gradle, binary plugins and script plugins.

What is kotlin gradle DSL?

Kotlin DSL brings the simplicity of the Kotlin language syntax and rich API set right into the script files on top of that code completion makes it perfect to work with Gradle script files. We will use this to manage our dependencies and project settings configurations more elegantly.

Which DSL does Gradle use?

IDE support. The Kotlin DSL is fully supported by IntelliJ IDEA and Android Studio.


2 Answers

See https://docs.gradle.org/current/userguide/kotlin_dsl.html#using_the_container_api:

tasks.named("check")                  
tasks.register("myTask1")

The above sample relies on the configuration avoidance APIs. If you need or want to eagerly configure or register container elements, simply replace named() with getByName() and register() with create().

Difference between creating and registering (or create and register in Gradle versions prior to 5.0) is related to Task Configuration Avoidance new API, which is exaplined in details here (see this section):

How do I defer task creation?

This feature requires build authors to opt-in by migrating task creation from the TaskContainer.create(java.lang.String) APIs to the TaskContainer.register(java.lang.String) APIs. The register(…​) API registers a task to be created at a later time if and only if the task is needed. The create(…​) API continues to eagerly create and configure tasks when it is called.

like image 134
M.Ricciuti Avatar answered Sep 29 '22 23:09

M.Ricciuti


The accepted answer is great, but I want to add that if you want to actually use the reference created by created / registering call later, then there will be a difference in API. Compare

create<MavenPublication>("main") {
    …

    val sourcesJar by tasks.creating(Jar::class) {
        val sourceSets: SourceSetContainer by project
        from(sourceSets["main"].allJava)
        classifier = "sources"
    }

    artifact(sourcesJar)
}

and

create<MavenPublication>("main") {
    …

    val sourcesJar by tasks.registering(Jar::class) {
        val sourceSets: SourceSetContainer by project
        from(sourceSets["main"].allJava)
        classifier = "sources"
    }

    artifact(sourcesJar.get())
}

In case of registering, because it is lazy, you'll need an additional .get() call, or you'll get an exception:

* What went wrong:
Cannot convert the provided notation to an object of type MavenArtifact: task ':experiments:sourcesJar'.
The following types/formats are supported:
  - Instances of MavenArtifact.
  - Instances of AbstractArchiveTask, for example jar.
  - Instances of PublishArtifact
  - Maps containing a 'source' entry, for example [source: '/path/to/file', extension: 'zip'].
  - Anything that can be converted to a file, as per Project.file()
like image 8
madhead - StandWithUkraine Avatar answered Sep 29 '22 22:09

madhead - StandWithUkraine