Gradle 3.2-rc-1 is now available for testing

Gradle 3.2 RC1 is now available for testing

It’s a relatively quiet release this time around, but there are still plenty of reasons to upgrade.

Perhaps the most significant improvements are in the incremental build support, which now has better up-to-date checking for Java compilation, copying, and archiving. You can also have Gradle treat any task input as a classpath with the new @Classpath annotation.

Users of Gradle’s native build support gain an important tool in this release. Many of you will be familiar with the buildDependents task for classic multi-project builds. This is now available in native builds as well via new assembleDependents and buildDependents tasks. These are incredibly useful for determining whether your changes have adversely impacted anything that depends on them.

If you use an IDE and have a lot of dependencies in your build—particular dynamic ones—you may have experienced long import times. The underlying issue has been fixed in this release, resulting in significantly improved import times. One example enterprise build showed a 100-fold improvement!

Our users trialling the Kotlin build script support will be glad to hear that progress continues apace with support for multi-project builds. And it’s easier to try this feature on Windows now that a bug in compiling scripts on that platform has been fixed.

The last change we want to bring to your attention has been a long time coming and will affect a large number of builds: the shortcut syntax for declaring tasks (via <<) has now been deprecated. The eagle-eyed among you will notice that the user guide examples have been updated to use doLast() and we strongly recommend that you follow suit. This feature will be removed in Gradle 5.0! See the deprecations section of the release notes for more details.

Check the 3.2 RC1 release notes for more information. If no regressions are reported, a final release will typically follow in the next week.

Upgrade Instructions

Switch your build to use Gradle 3.2 RC1 quickly by updating your wrapper properties:

./gradlew wrapper --gradle-version=3.2-rc-1

Standalone downloads are available at https://gradle.org/release-candidate.

Reporting Problems

If you find a problem with Gradle 3.2 RC1, please file a bug on GitHub Issues adhering to our issue guidelines. If you’re not sure you’re encountering a bug, please use the forum.

This topic is now a banner. It will appear at the top of every page until it is dismissed by the user.

I encountered the following error in my lilith build:

* Where:
Build file '[..]/lilith/build.gradle' line: 467

* What went wrong:
Execution failed for task ':lilith:jarAll'.
> Cannot call TaskInputs.files(Object...) on task ':lilith:jarAll' after task has started execution.

This is the related stack trace: http://pastebin.com/xtsWaz1k

The task in question looks like this:

    task jarAll(dependsOn: configurations.default.allArtifacts.buildDependencies, type: Jar) {
        description = 'Creates a shaded/uberjar/fatjar of the application.'
        classifier = 'all'

        manifest.attributes(
            'Main-Class': "${mainClassName}"
        )

        from (sourceSets.main.output.classesDir)
        from (sourceSets.main.output.resourcesDir)

        doFirst {  // <- note the doFirst
            // the following must be executed in doFirst since the configuration
            // has not been initialized at configuration time
            from (configurations.runtime.resolve().collect { it.isDirectory() ? it : zipTree(it) }) {
                exclude 'META-INF/MANIFEST.MF'
                exclude 'META-INF/*.SF'
                exclude 'META-INF/*.DSA'
                exclude 'META-INF/*.RSA'
            }
        }
    }

This used to work in prior versions so this is at least some kind of incompatibility.

If this isn’t a bug and I’m doing something wrong then any hints about how to fix this would be appreciated.

Though, it is not the authoritative answer: I don’t think you are supposed to configure the task within the task itself. If for nothing else: Such configurations bypass the up-to-date checks. I usually just have it depend on a task and configure it within this “configuration task”. That is, I have utility methods like this:

public static Task lazilyConfiguredTask(Task task, Action<? super Task> taskConfiguration) {
    String configTaskName = "configure" + capitalizeFirst(task.getName());
    Task configTask = task.getProject().getTasks().findByName(configTaskName);
    if (configTask == null) {
        configTask = task.getProject().task(configTaskName);
        task.dependsOn(configTask);
    }

    configTask.doLast((Task ignore) -> {
        taskConfiguration.execute(task);
    });

    return task;
}

public static Task lazilyConfiguredTask(Task task, Closure<?> taskConfiguration) {
    return lazilyConfiguredTask(task, (configuredTask) -> {
        taskConfiguration.setDelegate(configuredTask);
        taskConfiguration.setResolveStrategy(Closure.DELEGATE_FIRST);
        taskConfiguration.call();
    });
}

private static String capitalizeFirst(String str) {
    if (str.isEmpty()) {
        return str;
    }

    char firstCh = str.charAt(0);
    char newFirstCh = Character.toUpperCase(firstCh);
    if (firstCh == newFirstCh) {
        return str;
    }

    return newFirstCh + str.substring(1);
}

With the above code, you code do something like this:

lazilyConfiguredTask(jarAll, {
    from (configurations.runtime.resolve().collect { it.isDirectory() ? it : zipTree(it) }) {
        exclude 'META-INF/MANIFEST.MF'
        exclude 'META-INF/*.SF'
        exclude 'META-INF/*.DSA'
        exclude 'META-INF/*.RSA'
    }
})

I should most likely change my build to use the shadow plugin instead. I heard it’s quite good.

I’ll keep my code unchanged for now so I can check it against the next RC.

Thanks for your answer, though!

Oh, and just for the record:
This was the only issue I encountered. Everything else in the projects I usually check against the RCs is working fine.

Hi Jörn,

we added improved up to date checking for the copy tasks in Gradle 3.2. More specifically, we now also track child specs correctly which fixes some bugs with up to date checking (see the release notes and GRADLE-1346).
Since your build is configuring child specs which have influence on the inputs and output of the task this now fails. As Attila already noted, it would be better to configure the task from a different task.
We will probably add something to the release notes to point out that breaking behavior.

Thanks for reporting,
Stefan

I assumed something like that… The code of this task is seriously old. I just checked and this is the commit that added it over 6 years ago! /o\

So this is indeed “works as expected”, right? I can safely clean it up, i.e. you don’t need me to check it against another RC? I’m fine with that. Just double-checking to make sure.

Found another smallish issue while testing my release procedure with the current RC:
I had the line Console console = System.console() in my build script and had to change it to java.io.Console console = System.console() since there is now a name clash between java.io.Console and org.gradle.api.tasks.Console.

This class wasn’t added in 3.2 but I wanted to mention it anyway since org.gradle.api.tasks.Console is still marked as incubating and you might want to avoid that clash.

I’m using java.io.Console for console.readPassword. You didn’t implement a “native” Gradle password input in the meantime, did you? I think I read something about enabling user input even in case of daemon somewhere but can’t remember the details anymore.

Replacing my allJar (see above) task with shadow plugin shadowAll was absolutely straightforward, btw.

The class org.gradle.api.tasks.Console was already introduced with Gradle 3.0 so I am kind of surprised you didn’t see the issue before. Can you please check with an older version again? Please make sure you test this with --no-daemon. Alternatively, you could just def your console variable to avoid the class conflict via def console = System.console().

You didn’t implement a “native” Gradle password input in the meantime, did you?

Sorry, so far we didn’t. We recognize the need to parse input from the command line. Could you please raise an issue on gradle/gradle as described in this blog post?

The last real release I performed was nearly a year ago. At that time I had to revert to Gradle 2.2.1 because of some issue introduced in 2.3 that has been fixed in the meantime. This console-related code is only executed in case of a release build (vs. SNAPSHOT build) to ask for the GPG password so I’m not too surprised that it didn’t bite me earlier.

I already try to remember performing a test release while checking Gradle RCs but I keep forgetting about it.

Should I raise an issue for the name clash, input from the daemon or both? I think there was a JIRA issue about daemon input already and I wanted to avoid duplicates…

This console-related code is only executed in case of a release build (vs. SNAPSHOT build) to ask for the GPG password so I’m not too surprised that it didn’t bite me earlier.

The code likely wasn’t executed. You probably read the console input in a task action that wasn’t run.

Should I raise an issue for the name clash, input from the daemon or both? I think there was a JIRA issue about daemon input already and I wanted to avoid duplicates…

I was referring to the console input. If there’s already an issue for it in JIRA then we are good. We’ll migrate open JIRA issues to GitHub issues in the upcoming weeks. Please see the blog post for reference:

Open JIRA issues will be migrated to GitHub, and no new issues will be put into JIRA after the release of Gradle 3.2.

The Console related issue was GRADLE-2310 so I’ll leave it at that.

Yes, the code is definitely only executing during release build. I just wanted to explain why I didn’t find the issue earlier.

Hi Jörn,

could you please try again with the Gradle nightly gradle-3.2-20161028095846+0000? The configuration of from during the execution phase should only yield a deprecation warning and shouldn’t fail the build. We are going to make it an error in Gradle 4.0.

Cheers,
Stefan

Yep, build works with that snapshot and prints the following warning as expected:
Configuring child specs of a copy task at execution time of the task has been deprecated and is scheduled to be removed in Gradle 4.0. Consider configuring the spec during configuration time, or using a separate task to do the configuration.

This topic is no longer a banner. It will no longer appear at the top of every page.

@huxi FYI, we just released Gradle 3.2-RC2 which contain the fixes for your reported issues. Would you mind giving it a spin as well?

Everything works. The warning is also generated as expected.