t |
The big news in Gradle 2.1 is the new, simpler, mechanism for using community plugins in your build, integrated with the newGradle Plugin Portal. This is one of many improvements planned to expand the Gradle platform by making the lives of both plugins developers and users better through new features and tooling.
Another very new exciting feature is the addition of incremental Java compilation, which promises to significantly reduce compilation times during the development cycle. Users of Apache Ant and Apache Maven may be familiar with incremental Java compilation from those tools. Gradle's incremental Java compiler is not based on the same approach as these tools and does not suffer from the same set of problems that plague incremental compilation with these tools. Please see the “Incremental Java compilation” section in “New and noteworthy” for more information.
Themaven-publish
andivy-publish
plugins have been improved in this release. When using themaven-publish
plugin, dependency exclusions specified when consuming dependencies are now translated to the published POM when publishing in Maven format. Theivy-publish
plugin is continuing to expand and support more of Apache Ivy's extensive configuration options. In this release it is now easier to specify thebranch
attribute for Ivy publications and to specify arbitrary “extra info”.
IDE integration continues to be a strong area of focus. TheTooling API, which is used by IDEs and other tooling to embed Gradle, now supports canceling a running operation or build. This is a particularly welcome improvement for Android Studio users, who can expect the coming releases of Android Studio to leverage this new functionality.
We are particularly proud of Gradle 2.1 containing contributions from 18 people outside of the core Gradle development team, which is a new record for the project. Thank you to everyone who contributed. Also, thanks to all who raise issue reports for the Gradle 2.0 release allowing us to make Gradle 2.1 even better.
As usual there's also a smattering of other improvements and bug fixes, detailed below.
We hope you enjoy Gradle 2.1.
maven-publish
pluginLanguageBasePlugin
Here are the new features introduced in this Gradle release.
The new plugin resolution mechanism, backed by the newGradle Plugin Portal, makes it easier to use community Gradle plugins. Instead of combining abuildscript
script block and anapply
statement, both statements can be replaced by aplugins script block.
plugins { id 'com.company.myplugin' version '1.3'}
Gradle will query the Plugin Portal for the implementation details of the specified plugins. The Plugin Portal's pluginbrowsing interface provides copy/paste friendly snippets.
All plugin authors are encouraged to submit their plugins for inclusion in the Plugin Portal. Submission instructions can be foundon the Plugin Portal site.
Many enhancements and features are planned for both the Plugin Portal and plugins in general. The newplugins {}
block is not yet a complete replacement for the existingapply()
method that is used to apply plugins. Its functionality will be expanded over coming releases.
Gradle 2.1 adds, incubating, support for compiling Java code incrementally.
Gradle has long had the ability to perform any build task incrementally by only performing the task if the inputs or outputs of the task change. When applied to Java compilation, this means that all the source for a given task will be compiled if any source file needs to be recompiled. The new incremental compilation feature compliments incremental task execution by only recompiling the actual source that needs to be recompiled, instead of all the source.
Incremental compilation has two key benefits:
The second point above is important for tools such asJRebel that watch for changed class files in order to reload the class at runtime.
Incremental compilation can be enabled via theoptions
property of theJavaCompile
task. The following example illustrates enabling incremental compilation for allJavaCompile
tasks.
allprojects { tasks.withType(JavaCompile) { options.incremental = true }}
Incremental compilation requires extra work and record keeping during compilation to achieve. This means that a full compile when incremental compile is enabled can be slower than if it was not enabled. However, this cost is offset for subsequent compile operations as only a subset of the source is compiled.
The current implementation is not able to fully analyze the impact of all changes to the source code in terms of identifying exactly which classes need to be recompiled. In such situations, all of the source will be recompiled in order to avoid inconsistent compilation results. Incremental Java compilation will improve over coming Gradle versions to be generally faster, and to invoke a full recompile in response to fewer types of changes.
It is worthwhile to note that Gradle's incremental Java compiler is not based on Apache Ant's incremental compiler (which is also used by Apache Maven). Incremental compilation with Ant (and Maven) has severe limitations and is notorious for producing inconsistent results. That is, it frequently produces different set of bytecode to what a full recompile would produce. This is due to it being based on timestamp comparisons and dependency analysis through bytecode analysis alone. The Gradle incremental compiler is not based on timestamps and also employs bytecodeand source analysis in order to more thoroughly analyze the impact of a change.
While we have extensively tested this feature during development, it will significantly benefit from usage “in the field”. Please try out this exciting new feature and report any problems encountered via theGradle Forums.
For more information please see the user guide section on “Incremental Java Compilation”.
The commonly used Maven Central and Bintray jCenter repositories are now accessed over the HTTPS protocol. No change is required to builds to take advantage of this change.
If you are using themavenCentral()
orjcenter()
repository notations your build will now access these repositories via HTTPS.
Gradle 2.1 includes Groovy 2.3.6, where Gradle 2.0 included Groovy 2.3.4.
This is a non breaking change. All build scripts and plugins that work with Gradle 2.0 will continue to work without change.
Gradle often launches child processes during a build to perform work. For example, Gradle executes test in a forked JVM process. During a large build, particularly whenbuilding in parallel, there may be more than one forked Gradle process at any time. In previous Gradle versions, there was no practical way to determine which process was doing what without looking inside the JVM of each process. Processes are now started with a description as a command line argument. Command line arguments are usually displayed by process listing utilities such asps
andjps
, which makes it easy to now identify what kind of Gradle process it is.
The following is an example of output from'jps -m'
during a Gradle 2.1 build:
28649 GradleWorkerMain 'Gradle Test Executor 17'28630 GradleWorkerMain 'Gradle Compiler Daemon 1'
This feature was contributed byRob Spieldenner during the“Contributing To Gradle Workshop” at theGradle Summit 2014 Conference.
It is now possible to perform advanced Groovy compilation configuration by way of the newGroovyCompileOptions.configurationScript
property (theGroovyCompileOptions
instance is available as thegroovyOptions
property of theGroovyCompile
task). This makes it possible to impose global compiler transformations and other configuration.
For example, to globally enable Groovy's strict type checking, a compiler config script can be created with…
import groovy.transform.TypeCheckedwithConfig(configuration) { ast(TypeChecked)}
And specified in the build script as…
compileGroovy { groovyOptions.configurationScript = file("myConfigScript.groovy")}
Wherefile("myConfigScript.groovy")
contains the Groovy code from above.
This feature was contributed byCédric Champeau.
It is now possible to havePMD static analysis print results directly to the console.
pmd { consoleOutput = true}
Output will be written toSystem.out
in addition to any configured reports.
This feature was contributed byVyacheslav Blinov.
maven-publish
pluginincubating featureThe incubatingmaven-publish plugin will now handle dependency excludes when generating a POM file for publishing.
So for a dependency declaration like:
dependencies { compile("my.org:my-module:1.2") { exclude group: 'commons-logging', module: 'commons-logging' exclude group: 'commons-collections' }}
The generated POM file will contain the following content:
<dependency> <groupId>my.org</groupId> <artifactId>my-module</artifactId> <version>1.2</version> <scope>runtime</scope> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> <exclusion> <groupId>commons-collections</groupId> <artifactId>*</artifactId> </exclusion> </exclusions></dependency>
This feature addresses [GRADLE-2945] and was contributed byBiswa Dahal.
The incubatingivy-publish plugin now supports setting the 'branch' attribute on the module being published:
publishing { publications { ivy(IvyPublication) { descriptor.branch = 'testing' } }}
When resolving Ivy modules, component metadata rules can also access the branch attribute via theIvyModuleDescriptor interface.
dependencies { components { eachComponent { ComponentMetadataDetails details, IvyModuleDescriptor ivyModule -> if (details.id.group == 'my.org' && ivyModule.branch == 'testing') { details.changing = true } } }}
The incubatingivy-publish plugin now supports publishing extra'info'
elements to the ivy.xml file generated via theIvyModuleDescriptorSpec interface. Configured extra info elements are added as children of the ivy'info'
element.
publishing { publications { ivy(IvyPublication) { descriptor.extraInfo 'http://my.namespace', 'myElement', 'Some value' } }}
Note that theivy schema demands that any extra info elements be added after any child elements of'info'
that are defined in the schema (e.g.'description'
or'ivyauthor'
).
This means that anywithXml() actions must take care to insert any schema-defined 'info' child elementsbefore any extra'info'
elements that may have been added.
Furthermore, retrieving extra info elements with namespace when resolving Ivy modules is also available now.
This is exposed via theIvyExtraInfo object in component metadata rules.
dependencies { components { eachComponent { ComponentMetadataDetails details, IvyModuleDescriptor ivyModule -> if (ivyModule.extraInfo.get('http://my.namespace', 'myElement') == 'changing') { details.changing = true } } }}
Note that theMap<String, String>
representation for extra info elements inIvyModuleDescriptor has been replaced withIvyExtraInfo.
Thetooling API is used to embed and programmatically invoke Gradle builds. This release sees some new features added to the tooling API.
The Tooling API now provides a way to canceloperations, such as running a build, using theCancellationTokenSource API to submit cancel requests. The current implementation attempts to cancel the build first, and then will resort to stopping the daemon.
This release sees further improvements to theBuildInvocations
model added in Gradle 1.12. In particular, tasks and selectors accessible from this model now expose information about theirvisibility as thepublic
property.
This change means that it is now possible to implement the equivalent ofgradle tasks
using the tooling API.
Sometimes it can be difficult to figure out exactly how Gradle has been configured and what a given build will produce. To help address this, Gradle now includes a new command line report that shows you some useful details about the components that your project produces. To use the report, simply rungradle components
.
In this release, the report shows details of the native libraries and executables defined by the native language plugins. It also shows some basic details about the components defined by the Jvm language plugins. Over the next few releases, this report will grow to include more information about other types of components.
The version of Groovy that Gradle uses to compile and run build scripts has been upgraded from 2.3.4 to 2.3.6. This should be a non-breaking change, but is mentioned as it is an update to a library that is used by all Gradle builds.
TheScalaCompile
task type now uses the same Java compiler integration as theJavaCompile
andGroovyCompile
task types for performing joint Java - Scala compilation. Previously it would use the old Ant-based Java compiler integration, which is no longer supported in the Gradle 2.x stream.
This change should be backwards compatible for all users, and should improve compilation time when compiling Java and Scala together.
Thejcenter()
repository definition now uses HTTPS instead of HTTP. This should be backwards compatible for all users. If for any reason you want to use explicitly HTTP for connecting the Bintray's JCenter repository you can simply reconfigure the URL:
repositories { jcenter { url = "http://jcenter.bintray.com/" }}
ThemavenCentral()
repository definition now uses HTTPS instead of HTTP. This should be backwards compatible for all users. If for any reason you want to use explicitly HTTP for connecting the Maven Central repository you can simply add the repo with the HTTP protocol explicitly:
repositories { maven { url = "http://repo1.maven.org/maven2/" }}
This way the FindBugs plugin works out of the box with newer Java versions (most notably: Java 1.8). If you use Java 1.6 you need to configure an older version of FindBugs explicitly:
findbugs { toolVersion = '2.0.3'}
The Gradle team is currently working hard on a new, faster configuration model as well as rework that will enable full dependency management support for native binaries. As part of this work, many changes have been made to the incubating native language plugins. While some effort has been made to avoid unnecessary breakages, in many cases such changes have been required.
It is anticipated that these plugins will remain unstable for the next release or two. Considering that fact, it may be prudent to hold off upgrading your native build until the underlying infrastructure has stabilised. Naturally, we'll behappy to assist with your migration, whether you choose to stick with the 'bleeding-edge' or prefer to wait.
The native language plugins now apply theLifecycleBasePlugin
instead of theBasePlugin
. This means that the default values defined by theBasePlugin
are not available.
Of note, the following actions of theBasePlugin
will be missing:
org.gradle.api.plugins.BasePluginConvention
and it's use to configure thedists
directory,libs
directory andarchivesBaseName
build<Configuration>
task ruleupload<Configuration>
task ruleConfiguration
instancesMany domain model classes have been renamed for consistency, and to permit better integration with the newjvm
component model.
In general, model classes that define how a component or binary is built have been renamed with theSpec
suffix. (Previously, we inconsistently used theProject
prefix for this purpose). For example,ProjectNativeComponent
is nowNativeComponentSpec
andCUnitTestSuiteBinary
is nowCUnitTestSuiteBinarySpec
.
In addition to these renames for consistency, the following changes were made:
NativeTestSuite
andProjectComponentNativeTestSuite
NativeTestSuiteBinary
no longer extendsNativeExecutableBinary
TestSuiteExecutableBinary
intoNativeTestSuiteBinary
To avoid a proliferation of methods onPlatformConfigurableToolChain, we removed:
target(Platform, Action)
target(Platform)
target(Iterable<? extends Platform>)
target(List<String>)
target(String... platformNames)
target(Iterable<? extends Platform>, Action<? super TargetedPlatformToolChain>)
sources
DSLWhen a language plugin is applied, aLanguageSourceSet
is only added to aFunctionalSourceSet
when thatFunctionalSourceSet
is associated with a component. In practise, this means that a build script should configure any language source sets after the components have been defined.
More details are available in the following section:Changes to the incubatingLanguageBasePlugin
.
src/<test-suite-name>/c
.The CUnit test suite components are created via model rules, and must be configured via model rules:
model { testSuites { helloTest { binaries.all { lib library: "cunit", linkage: "static" } } } }
The source set for a test suite component is created via model rules, and must be configured via model rules:
model { sources { variantTest { c { lib sources.hello.c lib sources.helloTest.cunitLauncher } } } }
TheRunTestExecutable
task now implementsExecSpec
, allow test execution to be further configured.
RunTestExecutable.testExecutable
property has been removed and replaced byRunTestExecutable.executable
.Very early versions of thecpp-lib
andcpp-exe
plugins had rudimentary support for publishing and resolving native components. This support was never fully functional, and has now been completely removed in preparation for full support in the upcoming releases.
LanguageBasePlugin
TheLanguageBasePlugin
serves as a basis for the new component-based native and java language plugin suites. As part of ongoing work in these domains, major changes have been made to this base plugin.
ProjectComponent
->ComponentSpec
ProjectComponentContainer
->ComponentSpecContainer
ComponentSpecIdentifier
->NamedProjectComponentIdentifier
ProjectBinary
->BinarySpec
projectComponents
container tocomponentSpecs
TheprojectComponents
container extension has been renamed tocomponentSpecs
. This container is now added by theComponentModelBasePlugin
and not by theLanguageBasePlugin
.
LanguageSourceSet
instancesIn previous Gradle versions each language plugin applied triggered the automatic creation of aLanguageSourceSet
for each FunctionalSourceSet in the project. With Gradle 2.1, this has been changed to that only languages appropriate to the respective component are added to theFunctionalSourceSet
.
To facilitate this change, a functional source set is created for each declared component in the build at the point of constructing the component.
Consider the example:
apply plugin: 'cpp'apply plugin: 'java-lang'executables { main}
This example defines aNativeExecutable
component named 'main' and will also create theFunctionalSourceSet
'sources.main'. ACppSourceSet
'cpp' will be added to 'sources.main', but noJavaSourceSet
will be added because this language is not applicable to aNativeExecutable
.
Similarly, when a jvm library is defined noc
orcpp
source sets will be created, even when thec
andcpp
language plugins are applied.
If the source sets of a component require further configuration, it is necessary to place this configurationafter the declaration of the component:
executables { main}sources { main { cpp { source { srcDirs "src/main/cpp", "src/shared/c++" include "**{@literal /}*.cpp" } } }}
Alternatively, you can create and configure anyFunctionalSourceSet
andLanguageSourceSet
instances directly via thesources
DSL at any time:
apply plugin:'cpp'sources { lib { // explicitly create a cpp source set of type CppSourceSet cpp(CppSourceSet) }}
To better support the production of multiple binary outputs for a single set of sources, a new set of Java language plugins was introduced in Gradle 1.x. This development continues in this release, with the removal of thejvm-lang
plugin, and the replacement of thejava-lang
plugin with a completely new implementation.
The existingjava
plugin is unchanged: only users who explicitly applied thejvm-lang
orjava-lang
plugins will be affected by this change.
The plugin classesorg.gradle.api.plugins.JvmLanguagePlugin
andorg.gradle.api.plugins.JavaLanguagePlugin
were merged intoorg.gradle.api.plugins.LegacyJavaComponentPlugin
to avoid confusions withorg.gradle.language.java.plugins.JavaLanguagePlugin
.
The new plugin classorg.gradle.language.java.plugins.LegacyJavaComponentPlugin
does not register a factory forJavaSourceSet
andResourceSourceSet
on eachFunctionalSourceSet
.
ProjectClassDirectoryBinary
->ClassDirectoryBinarySpec
ProjectJarBinary
->JarBinarySpec
Themaven-publish
plugin will now correctly add required 'exclusion' elements to the generated POM. If you have a build or plugin that applies these exclusions itself, the generated POM file may contain duplicate 'exclusion' elements.
Javadoc.setJavadocExecHandleBuilder()
has been removed. You should usesetToolChain()
instead.Previously, Gradle initialized test classes before trying to execute any individual test case. As of Gradle 2.1, classes are not initialized until the execution of the first test case (GRADLE-3114). This change was made for compatibility with the popular Android unit testing library,Robolectric.
This change impacts how classes that fail to initialize are reported. Previously a single failure would be reported with a test case name ofinitializerError
with the details of the failure. After this change, the first test case of the class that cannot be initialized will contain details of the failure, while subsequent test cases of the class will fail with aNoClassDefFoundError
.
This change will not cause tests that previously passed to start failing.
Previously, a typo in a configuration-level dependency exclude rule remained undetected and led to problems likeGRADLE-3124. Now the build fails fast when exclude rule is configured with a wrong key.
//fails fast now, 'module' is the correct keyconfigurations.compile.exclude modue: "kafka"
We suspect that the impact will be minimal to none hence we don't deprecate this behavior.
In response to the Gradle 2.0 regressionGRADLE-3126, a change has been made to how container element configuration methods are dispatched. This is unlikely to impact builds as the actual implementation now matches what is usually the intended behavior.
Prior to Gradle 2.1, the following build script would fail:
apply plugin: "java"task integrationTest {}sourceSets { integrationTest {}}assert sourceSets.findByName("integrationTest") != null
TheintegrationTest
source set would not be created because there is already a viableintegrationTest {}
method.
As of Gradle 2.1 the above script will not fail because it is interpreted that the intent is to create a new source set namedintegrationTest
. This applies to all named domain object containers in Gradle.
These incubating classes formed the API being used to manage model configuration by plugins. They have been removed in favor of a different approach.
The replacement mechanism is currently undocumented and not yet designed for public use.
TaskParameter
has been replaced withTaskExecutionRequest
.StartParameter.taskParameters
has been replaced withStartParameter.taskRequests
.IvyModuleDescriptor
has been renamed toIvyModuleDescriptorSpec
IvyModuleMetadata
has been renamed toIvyModuleDescriptor
IvyModuleDescriptor.getExtraInfo()
now returns anIvyExtraInfo instead of Map<String, String>We would like to thank the following community members for making contributions to this release of Gradle.
maven-publish
.CUnit
executable binaryRunTestExecutable
task implementsExecSpec
We love getting contributions from the Gradle community. For information on contributing, please seegradle.org/contribute.
Known issues are problems that were discovered post release that are directly related to changes made in this release.