Here are the new features introduced in this Gradle release.
Because Gradle's build lifecycle clearly distinguishes between configuration phase and execution phase the evaluation of property values has to be deferred under certain conditions to properly capture end user input. A typical use case is the mapping of extension properties to custom task properties as part of a plugin implementation. In the past, many plugin developers were forced to solve evaluation order problems by using the concept of convention mapping, an internal API in Gradle subject to change.
This release of Gradle introduces a mutable type to the public API representing a property with state. The relevant interface is called PropertyState
. An instance of this type can be created through the method Project.property(Class)
.
The following example demonstrates how to use the property state API to map an extension property to a custom task property without running into evaluation ordering issues:
apply plugin: GreetingPlugin
greeting {
message = 'Hi from Gradle'
outputFiles = files('a.txt', 'b.txt')
}
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
// Add the 'greeting' extension object
def extension = project.extensions.create('greeting', GreetingPluginExtension, project)
// Add a task that uses the configuration
project.tasks.create('hello', Greeting) {
message = extension.messageProvider
outputFiles = extension.outputFiles
}
}
}
class GreetingPluginExtension {
final PropertyState<String> message
final ConfigurableFileCollection outputFiles
GreetingPluginExtension(Project project) {
message = project.property(String)
setMessage('Hello from GreetingPlugin')
outputFiles = project.files()
}
String getMessage() {
message.get()
}
Provider<String> getMessageProvider() {
message
}
void setMessage(String message) {
this.message.set(message)
}
FileCollection getOutputFiles() {
outputFiles
}
void setOutputFiles(FileCollection outputFiles) {
this.outputFiles.setFrom(outputFiles)
}
}
class Greeting extends DefaultTask {
final PropertyState<String> message = project.property(String)
final ConfigurableFileCollection outputFiles = project.files()
@Input
String getMessage() {
message.get()
}
void setMessage(String message) {
this.message.set(message)
}
void setMessage(Provider<String> message) {
this.message.set(message)
}
FileCollection getOutputFiles() {
outputFiles
}
void setOutputFiles(FileCollection outputFiles) {
this.outputFiles.setFrom(outputFiles)
}
@TaskAction
void printMessage() {
getOutputFiles().each {
it.text = getMessage()
}
}
}
--offline
When running with --offline
, Gradle will disable the remote build cache.
When two tasks write into the same directory, Gradle will now disable task output caching for the second task to execute. This prevents issues where task outputs for a different task are captured for the wrong build cache key. On subsequent builds, if overlapping outputs are detected, Gradle will also prevent you from loading task outputs from the cache if it would remove existing outputs from another task.
You can diagnose overlapping task output issues by running Gradle at the --info
log level. If you are using Gradle Build Scans, the same detailed reason for disabling task output caching will be included in the build timeline.
When a plugin is built with the Java Gradle Plugin Development Plugin, custom task types declared in the plugin will go through validation. In Gradle 4.0, additional problems are now detected.
A warning is shown when: * a task has a property without an input or output annotation (this might indicate a forgotten input or output), * a task has @Input
on a File
property (instead of using @InputFile
of @InputDirectory
), * a task declares conflicting types for a property (say, both @InputFile
and @InputDirectory
), * a cacheable task declares a property without specifying @PathSensitive
. In such a case, we default to ABSOLUTE
path sensitivity, which will prevent the task's outputs from being shared across different users via a shared cache.
For more info on using task property annotations, see the user guide chapter.
Gradle will now download dependencies from remote repositories in parallel. It will also make sure that if you build multiple projects in parallel (with --parallel
) and that 2 projects try to download the same dependency at the same time, that dependency wouldn't be downloaded twice.
This will take advantage of performance optimizations in the latest Zinc releases.
Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backwards compatibility. See the User guide section on the “Feature Lifecycle” for more information.
The following are the features that have been promoted in this Gradle release.
Features that have become superseded or irrelevant due to the natural evolution of Gradle become deprecated, and scheduled to be removed in the next major Gradle version (Gradle 4.0). See the User guide section on the “Feature Lifecycle” for more information.
The following are the newly deprecated items in this Gradle release. If you have concerns about a deprecation, please raise it via the Gradle Forums.
When using the java
plugin, all compile
and runtime
dependencies will now be mapped to the compile
scope, i.e. "leaked" into the consumer's compile classpath. This is in line with how these legacy configurations work in multi-project builds. We strongly encourage you to use the api
(java-library plugin only), implementation
and runtimeOnly
configurations instead. These are mapped as expected, with api
being exposed to the consumer's compile classpath and implementation
and runtimeOnly
only available on the consumer's runtime classpath.
JacocoPluginExtension
methods getLogger()
, setLogger(Logger)
are removed.JacocoTaskExtension
methods getClassDumpFile()
, setClassDumpFile(File)
, getAgent()
and setAgent(JacocoAgentJar)
are removed.AccessRule(Object, Object)
.ProjectDependency(String, String)
and the methods getGradlePath()
, setGradlePath(String)
.WbDependentModule(Object)
.WbProperty(Object)
.WbResource(Object)
.JarDirectory(Object, Object)
.Jdk(Object, Object, Object, Object)
.ModuleDependency(Object, Object)
.RhinoWorkerHandleFactory
and RhinoWorkerUtils
into internal package.RhinoWorker
.EarPluginConvention(Instantiator)
.registerWatchPoints(FileSystemSubset.Builder)
from FileCollectionDependency
.getConfiguration()
from ModuleDependency
.getProjectConfiguration()
from ProjectDependency
.BuildCache
.MapBasedBuildCache
.ActionBroadcast
.@OrderSensitive
and the method TaskInputFilePropertyBuilder.orderSensitive
.dependencyCacheDir
getter and setters in java plugin, JavaCompileSpec
, and CompileOptions
AntDepend
,
AntDependsStaleClassCleaner
, and
DependOptions
Javadoc#setOptions
Manifest.writeTo(Writer)
. Please use Manifest.writeTo(Object)
TaskInputs.source()
and sourceDir()
. Please use TaskInputs.file().skipWhenEmpty()
, files().skipWhenEmpty()
and dir().skipWhenEmpty()
.TaskInputs.file()
, files()
, dir()
and TaskOutputs.file()
, files()
and dir()
are not supported anymore.TaskOutputs.doNotCacheIf(Spec)
, use doNotCacheIf(String, Spec)
instead.The deprecated jetty
plugin has been removed. We recommend using the Gretty plugin for developing Java web applications. The deprecated pluginRepositories
block for declaring custom plugin repositories has been removed in favor of pluginManagement.repositories
.
AbstractCopyTask
taskYou can no longer add copy specs to a copy (like Copy
and Sync
) or archive task (like Zip
and Tar
) when the task is executing. Tasks that used this behavior could produce incorrect results and not honor task dependencies.
Starting with Gradle 4.0, builds that rely on this behavior will fail. Previously, Gradle only failed if the task was cacheable and emitted a warning otherwise.
```groovy // This task adds a copy spec during the execution phase. task copy(type: Copy) { from ("some-dir") into ("build/output")
doFirst {
// Adding copy specs during runtime is not allowed anymore
// The build will fail with 4.0
from ("some-other-dir") {
exclude "non-existent-file"
}
}
} ```
We would like to thank the following community members for making contributions to this release of Gradle.
FileReferenceFactory.toString()
(gradle/gradle#1440)We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.
Known issues are problems that were discovered post release that are directly related to changes made in this release.