Strange class not found error for closure

* What went wrong:
A problem occurred evaluating script.
> ThingUtilsPluginConvention$_parseVersion_closure3

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.GradleScriptException: A problem occurred evaluating script.
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:177)
        at org.gradle.configuration.DefaultScriptTarget.addConfiguration(DefaultScriptTarget.java:74)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:182)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyScript(DefaultObjectConfigurationAction.java:102)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$000(DefaultObjectConfigurationAction.java:36)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$1.run(DefaultObjectConfigurationAction.java:62)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:136)
        at org.gradle.api.internal.project.AbstractPluginAware.apply(AbstractPluginAware.java:44)
        at org.gradle.api.internal.project.ProjectScript.apply(ProjectScript.java:34)
        at org.gradle.api.Script$apply.callCurrent(Unknown Source)
        at build_ah8wffkch0k538un78ipd1jfu.run(/Users/scott/dev/Thing/ThingPlugins/EXAMPLES/ImageFlipper/ImageFlipperJava/build.gradle:2)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:177)
        at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
        at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:182)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:38)
        at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:25)
        at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:55)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:573)
        at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:125)
        at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:47)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
        at org.gradle.initialization.DefaultGradleLauncher$2.run(DefaultGradleLauncher.java:124)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:121)
        at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:82)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:59)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:49)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.HintGCAfterBuild.execute(HintGCAfterBuild.java:44)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:240)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: java.lang.NoClassDefFoundError: ThingUtilsPluginConvention$_parseVersion_closure3
        at ThingUtilsPluginConvention.parseVersion(/Users/scott/dev/ThingSDK/BuildScripts/ThingUtilsPlugin.gradle:270)
        at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:382)
        at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:170)
        at org.gradle.api.internal.plugins.DefaultConvention$ExtensionsDynamicObject.invokeMethod(DefaultConvention.java:220)
        at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
        at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.invokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
        at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:163)
        at org.gradle.api.internal.project.DefaultProject_Decorated.invokeMethod(Unknown Source)
        at ThingUtilsPluginConvention.ensureGradleVersion(/Users/scott/dev/ThingSDK/BuildScripts/ThingUtilsPlugin.gradle:325)
        at ThingUtilsPluginConvention$ensureGradleVersion.callCurrent(Unknown Source)
        at ThingUtilsPluginConvention.ensureGradleVersion(/Users/scott/dev/ThingSDK/BuildScripts/ThingUtilsPlugin.gradle:321)
        at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:382)
        at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:170)
        at org.gradle.api.internal.plugins.DefaultConvention$ExtensionsDynamicObject.invokeMethod(DefaultConvention.java:220)
        at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
        at org.gradle.api.internal.ExtensibleDynamicObject$InheritedDynamicObject.invokeMethod(ExtensibleDynamicObject.java:245)
        at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
        at org.gradle.api.internal.ExtensibleDynamicObject$InheritedDynamicObject.invokeMethod(ExtensibleDynamicObject.java:245)
        at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
        at org.gradle.api.internal.ExtensibleDynamicObject$InheritedDynamicObject.invokeMethod(ExtensibleDynamicObject.java:245)
        at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
        at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.invokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
        at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:163)
        at org.gradle.api.internal.project.DefaultProject_Decorated.invokeMethod(Unknown Source)
        at ThingSubprojectPlugin.apply(/Users/scott/dev/ThingSDK/BuildScripts/ThingSubprojectPlugin.gradle:19)
        at ThingSubprojectPlugin.apply(/Users/scott/dev/ThingSDK/BuildScripts/ThingSubprojectPlugin.gradle)
        at org.gradle.api.internal.plugins.ImperativeOnlyPluginApplicator.applyImperative(ImperativeOnlyPluginApplicator.java:35)
        at org.gradle.api.internal.plugins.RuleBasedPluginApplicator.applyImperative(RuleBasedPluginApplicator.java:43)
        at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:139)
        at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:116)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyType(DefaultObjectConfigurationAction.java:123)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyPlugin(DefaultObjectConfigurationAction.java:107)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.access$100(DefaultObjectConfigurationAction.java:36)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction$2.run(DefaultObjectConfigurationAction.java:71)
        at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.execute(DefaultObjectConfigurationAction.java:136)
        at org.gradle.groovy.scripts.DefaultScript.apply(DefaultScript.java:114)
        at org.gradle.api.Script$apply.callCurrent(Unknown Source)
        at ThingSubprojectPlugin_1lne4l8iehf8hw0uyvhjojfo7.run(/Users/scott/dev/ThingSDK/BuildScripts/ThingSubprojectPlugin.gradle:6)
        at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
        ... 70 more
Caused by: java.lang.ClassNotFoundException: ThingUtilsPluginConvention$_parseVersion_closure3
        ... 109 more

Gradle Version: 3.0
Operating System: OS X 10.11.6
Is this a regression?
Yes
If yes, which version of Gradle do you know it last worked for?
2.14.1

There are 275 sub-projects in the build.
“Configuring” gets to about 181 and then the above exception is triggered. Note that the closure that it is complaining about ran many many times already at that point! Most of the sub projects have identical structure and build scripts.

It is proprietary source… but the complaint is about this block:

// Expected version format is a sequence of numbers, separated by periods.  E.g. 1.2.3.4.5
private List<Integer> parseVersion(String version) {
    println "Parsing as version: $version"
    String[] sarr = version.split(/\./)
    Integer[] narr = sarr.collect() { String s ->  // <<< THIS CLOSURE IS NOT FOUND
        if (s == null) {
            return 0
        }
        // Pick leading digits with "\d+" to handle 2.4-20150222230019+0000
        def n = s =~ /\d+/
        if (n) {
            return n[0].toInteger()
        } else {
            return 0
        }
    }
    return narr.toList()
}

This block has ran over 100 times during the build before the error is reported.

Hi Scott !

Does this happen with a clean build? If so, could you try recompiling the build scripts? (--recompile-scripts). A build scan could also help us diagnose the problem if you’re still seeing it.

Thanks for the report, Scott! We’ve had other similar reports, too. I’ve created GRADLE-3526 to track the problem. Along with @CedricChampeau’s request, any further information you can provide to help us reproduce would be greatly appreciated.

I did try --recompile-scripts without success. (I should have mentioned that before).

I was considering a “build scan” but quite frankly I don’t know what I’m getting into with those. I followed the link to build scan info earlier and I couldn’t figure out what is collected, if there is some sort of charge for the service, would the build scan be publicly available to everyone, the terms of service were written by and for lawyers, etc. It looks like the build scan information has just been replaced. It is less scary now :slight_smile: but I’m still not sure how safe it is for me to do a build scan for a closed-source commercial product. I don’t want to publish private information in a public forum. Some clarification along those lines would be appreciated.

Hi Scott,

I’m looking into this now. To help me narrow down the issue and reproduce it, could you please answer the following:

  • Does the build fail consistently in the exact same place (from what you can tell)?
  • What version of Groovy are you using locally?
  • Does the build fail in the same way if you try Gradle 3.0-milestone-1 or 3.0-milestone-2? (Please run gradlew clean when testing)
    gradle wrapper --gradle-version 3.0-milestone-2

Regarding Build Scans: thank you for your honest questions.

Generating a Build Scan will collect only environment information, task execution information, and stacktraces; much like what you’ve provided here. It does not collect any other information about the codebase.

At the moment, a build scan URL is accessible publicly but not discoverable publicly. You’d expect the same level of privacy from, say, a private GitHub Gist.

I understand the motivation to want truly private sharing, and I want to note that we have 2 upcoming features to address this need, one of which will be available in Gradle 3.1 IIRC. I’m sorry I can’t let the cat out of the bag on this one, though :wink:

Looking forward to your answers or feedback.

Cheers,
Eric

Hi Scott

Thanks for your feedback. The onboarding pages are currently being improved to better communicate what you are ‘getting into’ when creating/publishing a build scan. This will go live within the next few weeks.

The build scan service available at scans.gradle.com is for free. We also have a commercial product called Gradle Enterprise that ships with its own on-prem Build Scan Server. It is used by various companies that do not want any build data to leave their company.

What exactly we capture will soon be described on our onboarding pages, too. For now, you can find the list here.

Kind regards, Etienne

Yes the build appears to fail at the same spot every time.
I’m using whatever version of Groovy is bundled with Gradle 3.0.

I just tried on Windows, where the project has 922 subprojects. (We haven’t ported many of them to OS X/Linux yet, so there is a filter in settings.gradle that picks the sub-projects that will build on the current platform.)

It gets much farther but fails with the exact same closure when configuring subproject 403 (or maybe it fails configuring 404, 403 is the last number I glimpse before the error).

Good news, 3.0-miestone-2 got past the problem!

In this case I’m not comfortable uploading a build scan. Project names and file paths can reveal information about business partners and implementation technologies. They don’t pay me enough to make those decisions :wink: I’ll play it safe for now.

Thanks for the quick response, Scott.

The use of Groovy bundled with Gradle and knowing 3.0 M2 passes helps narrow the changes that could be responsible for the bug.

The fact that the build fails consistently at the same point and the fact that it fails on both Mac and Windows indicates to me that something deterministic is causing this, almost as if configuring the 180th project causes the 181st one to fail.

I’m going to continue trying to create a reproducible test case so that I can then bisect to find the issue. Any information you can share that you think would help me reproduce this issue would be very helpful. One other thing that may be helpful for me is --info or --debug logs (just the last bits that may capture what’s going on with the build before it fails).

Cheers,
Eric

Here is the last chunk before it dies:
http://pastebin.com/4xVe8gr7

One thing I noticed with --info that the just before the failure I get this message:

Evaluating project ':EXAMPLES:ImageFlipper:ImageFlipperJava' using build file 'C:\Users\scott.palmer\dev\Kayak\KayakPlugins\EXAMPLES\ImageFlipper\ImageFlipperJava\build.gradle'.
Compiling build file 'C:\Users\scott.palmer\dev\Kayak\KayakPlugins\EXAMPLES\ImageFlipper\ImageFlipperJava\build.gradle' using SubsetScriptTransformer.
Compiling build file 'C:\Users\scott.palmer\dev\Kayak\KayakPlugins\EXAMPLES\ImageFlipper\ImageFlipperJava\build.gradle' using BuildScriptTransformer.
Compiling script 'C:\Users\scott.palmer\dev\KayakSDK\BuildScripts\KayakSubprojectPlugin.gradle' using SubsetScriptTransformer.
Compiling script 'C:\Users\scott.palmer\dev\KayakSDK\BuildScripts\KayakSubprojectPlugin.gradle' using BuildScriptTransformer.

99% of other projects prior to this have “Compiling build file” messages, but not the “Compiling script” messages. All of the other “Compiling script” messages were way in the beginning. when the first couple projects were evaluated. These scripts are used by the subprojects with “apply from”

Very interesting observation.

I now have a hunch which changes introduced this issue. However, I still don’t have a reproducible test case. Would you be willing to try out 2 these two nightly builds and tell me which ones pass or fail?

./gradlew wrapper --gradle-version 3.0-20160718000019+0000
./gradlew clean tasks
 
./gradle wrapper --gradle-version 3.0-20160719000054+0000
./gradlew clean tasks

If I’m correct 20160718 will pass and 20160719 will fail; and therefore this will have been caused by changes to how we close ClassLoaders (meant to avoid locking JAR files on Windows).

Meanwhile, I’m going to take a closer look at the logs and wrap my head around our ClassLoader handling in Gradle.

Thanks again for your speedy responses,
Eric

You got it right. Everything was as you expected. 20160718 worked, 20160719 failed.

The sub-project that it fails on is always the same one. In this case it is the 403rd on Windows and 180-ish on Mac, but it is the same project.

The good news is that we’ve isolated the issue. We will almost certainly have this fixed in Gradle 3.1.

The bad news is that I don’t have much to help you fix your situation for 3.0 since I don’t have access to your build. The problem is we’re closing a ClassLoader and perhaps an afterEvaluate or finalizedBy is applying a script plugin (that is, “apply from: ‘foo.gradle’” or similar) that’s trying to load a Class from that closed ClassLoader. Does that ring a bell?

One final question I just thought of. Are you using --configure-on-demand or --parallel config options? Just checking to make sure those couldn’t be affecting this as well.

I searched the scripts for finalizedBy and found no hits.

afterEvaluate is used but it never applies a script. It adds some configuration to a copySpec and defines some new tasks.

Not using --configure-on-demand or --parallel

Hey @swpalmer, we’ve been trying to reproduce the behavior here and so far we’ve been unsuccessful. I wonder if you can tell us a little more about the interactions between the various plugins at play here. From what I can tell looking at the stacktrace, I think you have the following:

  • A multiproject build with various subprojects and a number of script plugins.
  • A script plugin called ThingSubprojectPlugin.gradle which, when applied, applies a binary plugin ThingSubprojectPlugin.
  • The ThingSubprojectPlugin binary plugin then does something with ThingUtilsPluginConvention.
  • ThingUtilsPluginConvention is a class defined in a script plugin called ThingUtilsPlugin.gradle.
  • The closure that you’re getting the exception on is a closure inside the “parseVersion” method of ThingUtilsPluginConvention.

First of all, can you validate or correct the above. Second, a few questions:

  • Is the ThingSubprojectPlugin binary plugin class defined in ThingSubprojectPlugin.gradle or is it coming from somewhere else (i.e. buildSrc or an external library)?
  • How does ThingUtilsPluginConvention get created? Is it created directly by ThingUtilsPlugin.gradle or is a binary plugin being applied that creates ThingUtilsPluginConvention?
  • If a binary plugin is creating the convention, where is that class being defined?
  • It looks like ThingSubprojectPlugin.gradle is being directly applied in ImageFlipperJava/build.gradle - how is ThingUtilsPlugin.gradle being applied (i.e. is it applied in the same script, is it being injected from the root script, is it being applied from another script plugin, etc)

Thanks for taking the time to help us understand. We think we know what is causing the issue, but it’s not clear why it is causing an issue and until we can actually reproduce the problem, we can’t be sure we’re actually fixing it.

Yes. This is a multi project build with hundreds of sub-projects. The parent project is really just to control the build order of the sub projects as they are effectively a bunch of libraries that have dependencies between them

There are several more plugin scripts involved.
Each subproject of the root project does this:

apply from: "${System.getenv('THING_SDK')}/BuildScripts/ThingMasterPlugin.gradle"

(This is in fact the only line in ImageFlipper/build.gradle)
Each sub-project is called a ‘master’ project because it likely has two sub-project parts of its own that actually compile code (Java and Native) and it assembles them into a single module structure with metadata.

The first line of ThingMasterPlugin.gradle (after imports and a buildscript block to add a jar to the classpath) is:

apply from: “${System.getenv(‘THING_SDK’)}/BuildScripts/ThingUtilsPlugin.gradle”

ThingUtilsPlugin.gradle provides various utility methods, including parseVersion and other methods that rely on it.

The first line of ThingUtilsPlugin.gradle is:

apply plugin: ThingUtilsPlugin

ThingUtilsPluginConvention is defined in ThingUtilsPlugin.gradle and an instance is created when the ThingUtilsPlugin binary plugin is applied, like so:

class ThingUtilsPlugin implements Plugin {
    def void apply(project) {
        project.convention.plugins.generalUtilities = new ThingUtilsPluginConvention(project)
    }
}

class ThingUtilsPluginConvention {
    private Project project

...

The next thing in ThingMasterPlugin.gradle (before the binary plugin is applied) is a call to a utility method ‘validateBuildSystem’ that checks the Java version, Gradle version, and versions of Visual Studio installed. These will eventually call parseVersion.

Applying the binary ThingMasterPlugin calls one of these methods ‘ensureGradleVersion’ again (this appears to be an unnecessary redundancy)

Applying the binary ThingSubprojectPlugin also calls ‘ensureGradleVersion’ as you can see below.

Here is ThingSubprojectPlugin.gradle:

import org.gradle.api.Plugin
import org.gradle.api.Project

defaultTasks 'allRelease'

apply plugin: ThingSubprojectPlugin

if (project.ThingMaster.isMYCPlugin) {
    repositories {
        mavenLocal()
        maven {
            url = "http://dcm-maven-repo.mycompany.local/repo"
        }
    }
}

class ThingSubprojectPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.ensureGradleVersion()

        project.task('allDebug', dependsOn: [project.parent.allDebug]) {
        }

        project.task('allRelease', dependsOn: [project.parent.allRelease]) {
        }

        project.task('allFetch', dependsOn: [project.parent.allFetch]) {
        }

        project.task('allTest', dependsOn: [project.parent.allTest]) {
        }

        project.task('allPublish', dependsOn: [project.parent.allPublish]) {
        }

        project.task('allClean', dependsOn: [project.parent.allClean]) {
        }

        project.task('allPrebuild', dependsOn: [project.parent.allPrebuild]) {
        }

        project.task('allPostbuild', dependsOn: [project.parent.allPostbuild]) {
        }

        project.task('subPostbuild') {
        }
        project.parent.getTasksByName('subPostbuild', false).each() { t ->
            t.dependsOn(project.subPostbuild)
        }

        project.task('subPrebuild') {
        }
        project.parent.getTasksByName('subPrebuild', false).each() { t ->
            t.dependsOn(project.subPrebuild)
        }

        project.task('subBuild') {
        }
        project.parent.getTasksByName('subBuild', false).each() { t ->
            t.dependsOn(project.subBuild)
        }

        project.task('subTest') {
        }
        project.parent.getTasksByName('subTest', false).each() { t ->
            t.dependsOn(project.subTest)
        }

        project.task('subFetch') {
        }
        project.parent.getTasksByName('subFetch', false).each() { t ->
            t.dependsOn(project.subFetch)
        }

        project.task('subPublish') {
        }
        project.parent.getTasksByName('subPublish', false).each() { t ->
            t.dependsOn(project.subPublish)
        }

        project.task('subClean') {
        }
        project.parent.getTasksByName('subClean', false).each() { t ->
            t.dependsOn(project.subClean)
        }

        project.task('releasePerform') {
        }
        project.parent.getTasksByName('releasePerform', false).each() { t ->
            t.dependsOn(project.releasePerform)
        }

        project.task('initClean', dependsOn: [project.parent.initClean]) {
        }

        project.task('initBuild', dependsOn: [project.parent.initBuild]) {
        }
    }
}

I apologize that I can only provide sanitized clips from all the various scripts. I’m trying to capture the structure, but it can be rather complex.

Since I can reproduce reliably, I will be happy to test a build. I have never built Gradle from source, but if it is straight forward I should be able to test a patch.

However… I am on vacation for a week, so my response time will be affected accordingly.

Hey @swpalmer , I’m also trying to reproduce the problem. I’d like to know what JVM version you are using.
-Lari

I’m running 8u102 64-bit On Windows 10.

Hi Scott,

we really need to fix this for Gradle 3.1. We still have a hard time figuring out what is going wrong and we cannot reproduce the problem on our own infrastructure. Would you be willing to try out a special build of Gradle which has some extra logging in it and then share that log with us?

To all the other users having the same problem: Please post your errors and constellations here. We really want to track down that problem. If we could reproduce this consistently then we would have an easy time forging a fix.

Cheers,
Stefan

Yes. I can run any build you need me to.