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?
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.
There are two general types of plugins in Gradle, binary plugins and script plugins.
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.
IDE support. The Kotlin DSL is fully supported by IntelliJ IDEA and Android Studio.
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.
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With