Gradle Exec task hangs when setting the environment property

Executing the following task, within a subproject, …

task makeTree(type: Exec) {
        //environment taskEnv
        workingDir rootProject.getProjectDir()
        commandLine perlExec + args
    }

Fails, as expected, because the script being called requires specific environment settings.

$ gradlew makeTree
:oldBuildscripts:makeTree
executing set
              system(set)=-1
                             :oldBuildscripts:makeTree FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':oldBuildscripts:makeTree'.
> Process 'command 'cmd'' finished with non-zero exit value 69
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 7.369 secs

However, when providing the environment for this task, gradlew hangs, indefinitely.

Code:

task makeTree(type: Exec) {
        environment taskEnv
        workingDir rootProject.getProjectDir()
        commandLine perlExec + args
    }

Result:

$ gradlew makeTree
> Building > :oldBuildscripts:makeTree
...have to Ctrl-C out of it...

The task is specific to Windows, so I’ve only reproduced this on two different Windows 7 machines, both using the gradle 1.9 wrapper. One with JDK 1.7 and the other with JDK 1.6.

I also verified that I’m setting the environment property, correctly, by passing the current environment:

environment System.getenv()

and the task executes, as expected. So, there is something wrong with the environment map, which I’m passing in, that seems to get gradle (or something deeper) into a bad state. Any ideas? Should I debug deeper?

You’ll have to dig deeper. Run with ‘–debug’, try to figure out where the task hangs (maybe in your script?), get a thread dump, inspect the map that you are passing in, try to convert all map keys and values to strings beforehand, etc.

Yeah, after reading my post, I knew that I needed to spend more time on this. :frowning:

I did verify that it isn’t the script. I know that it is within the task execution of gradle. I verified by simply changing to the commandLine to execute a simple windows ‘dir’ command.

I switched to a simple ‘dir’ command, in order to eliminate any doubt. Here is what I see with --debug:

15:21:02.489 [INFO] [org.gradle.process.internal.DefaultExecHandle] Starting process 'command 'cmd''. Working directory: D:\repos\xxx Command: cmd /c dir
15:21:02.499 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Environment for process 'command 'cmd'':..
  for environment, see http://pastebin.com/hnHdwxD1
  ...
15:21:02.559 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: STARTING
15:21:02.568 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Waiting until process started: command 'cmd'.

Okay…after digging deeper…I kept adding environment variables until I encountered the issue…and it was user error…my error, as environment variable names should not contain equal signs. But, this still shouldn’t hang, right? Also, I have a slight gripe about the pretty printing of the environment map in the gradle debug output. Read on…

For your thorough understanding and reading enjoyment.

The issue was with a regex of mine not accounting for environment variable’s with equals signs in the variable’s value. I was accidentally capturing the equals as a part of the environment variable’s name.

Gripe #1

It wasn’t easy to see the equals sign in the variable name, in the gradle debug output. This appears to be because the environment isn’t printed in groovy map notation. E.g. gradle’s debug output doesn’t really distinguish which equals represents the beginning of the environment variable’s value and which is a part of the value. After all, it is valid to have an equals sign as a part of a variable’s value.

From gradle’s debug output:

...PROCESSOR_LEVEL=6, VC_VER=VC_VERSION=10.0, PLATFORM=X64....

From printing the groovy map, I can clearly see that ‘VC_VER=VC_VERSION’ is an invalid environment variable name (damn greedy .* in my regex).

...NUMBER_OF_PROCESSORS:4, SYSTEMROOT:C:\Windows, VC_VER=VC_VERSION:10.0]

Gripe #2

The task hangs when the environment variable contains an equals sign in the name. I will admit invalid user input, but this can’t be acceptable behavior, can it? A reproducible test case:

def isWindows = System.properties['os.name'].toLowerCase().contains('windows')
def commandLinePrefix = isWindows ? ['cmd', '/c'] : []
  task someTask(type: Exec) {
    def myMap = ['foo=bar':'foobared']
    environment myMap
    executable 'dir'
    commandLine commandLinePrefix + 'dir'
}

Hangs…

$ gradle someTask
> Building > :someTask
...have to Ctrl-C to exit...

All that being said, I still love Gradle!

Raised GRADLE-2996 for the ‘=’ in env var name issue.