'Why can't Groovy find this program even though it's on my PATH?

tl;dr: Groovy cannot find a program (phantomjs, which is on my $PATH) when I attempt to execute the shell command from a class -- it's otherwise finds it just fine from the Groovy Console or from a Grails CLI script. What gives?

We have a Grails script to execute JavaScript unit tests in PhantomJS ("the headless WebKit"). When these tests are executed in a stand-alone script (call it grails test-js) things work just fine. The relevant line from the Grails/Gant script was:

// where 'jsTests' is a List with the paths to each test
def failures = 0
jsTests.each {
  Process p = "phantomjs lib/phantom-jasmine/lib/run_jasmine_test.coffee file://${it}".execute()
  failures += p.exitValue()
}

But since we want this to run as part of the usual grails test-app cycle, we created an implementation of org.codehaus.groovy.grails.test.GrailsTestType. When we get to the part in that implementation where we need to execute the tests, that same code (as above) doesn't work, and Groovy/Grails complains that:

java.io.IOException: Cannot run program "phantomjs": error=2, No such file or directory

My first thought was that phantomjs was not on my $PATH -- but I know that it is, and again: it worked when run from the Grails/Gant script. So I tried it in the Groovy Console, and it works OK from there.

Now, if I switch from phantomjs to /absolute/path/to/phantomjs, then it works fine. But hard-coding an absolute filesystem path into the class cannot be the solution.

So: why isn't Groovy finding phantomjs under those circumstances?

Update: I suspect that this might have something to do with my IDE (IntelliJ Idea), as this error doesn't appear to be happening when running this from the command line.



Solution 1:[1]

As it turns out, this had everything to do with trying to run the tests from within my IDE (IntelliJ IDEA) and, more specifically, trying to do this on an OS X machine.

The solution was to add phantomjs to my PATH using launchd.conf. I...

  1. created /etc/launchd.conf

  2. added the following line to it: (note: I installed PhantomJS with Homebrew)

    setenv PATH /usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

  3. restarted my machine so that the new launchd config would take effect.

  4. went back into my IDE and re-ran the tests.

And all the tests ran successfully.

Solution 2:[2]

You can try printing your path with groovy

['sh', '-c', 'echo $PATH' ].execute().text

or

println System.getenv('PATH')

You can to create an environment variable with absolute path to phantomjs and verify it in runtime and to alert if it is not properly configured.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Glorfindel
Solution 2