14

I tried to call npm in my Gradle build. The npm is installed via homebrew into /usr/local/bin. The gradle will fail to find npm when executing it.

However it always failed after I added PATH environment variable when executing npm command.

The only workaround for me is using absolute path for npm, it does not make sense to use same gradle script in Linux.

Did anyone meet the similar issue? Should I open ticket for gradle?

Below is my build.gradle,

import org.gradle.api.tasks.Exec
import org.apache.tools.ant.taskdefs.condition.Os

ext {
        npmCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : 'npm'
        npmPath = Os.isFamily(Os.FAMILY_WINDOWS) ? '' : '/bin/:/usr/bin/:/usr/local/bin/'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.4'
}
// Install packages from package.json
task npm(type: Exec) {
        description = "Grab NodeJS dependencies (from package.json)"
        environment PATH: npmPath
        workingDir = 'src/webapp'
        commandLine = [npmCommand, "install"]
        inputs.file "src/webapp/package.json"
}

Below is complete output of gradle,

./gradlew npm -S
:npm FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':npm'.
> A problem occurred starting process 'command 'npm''

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

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':npm'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:310)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:90)
    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:41)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:49)
    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:37)
    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.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:66)
    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:71)
    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.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    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:246)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.process.internal.ExecException: A problem occurred starting process 'command 'npm''
    at org.gradle.process.internal.DefaultExecHandle.setEndStateInfo(DefaultExecHandle.java:196)
    at org.gradle.process.internal.DefaultExecHandle.failed(DefaultExecHandle.java:325)
    at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:83)
    ... 5 more
Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'npm'
    at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:27)
    at net.rubygrapefruit.platform.internal.WrapperProcessLauncher.start(WrapperProcessLauncher.java:36)
    at org.gradle.process.internal.ExecHandleRunner.run(ExecHandleRunner.java:65)
    ... 5 more
Caused by: java.io.IOException: Cannot run program "npm" (in directory "/Users/kane/git/videome/wechat/src/webapp"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
    ... 7 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 8 more


BUILD FAILED

Total time: 1.139 secs

The task will run fine if changing to the absolute path of npm,

npmCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : '/usr/local/bin/npm'

Kane
  • 8,035
  • 7
  • 46
  • 75

4 Answers4

26

I had the same problem after upgrading my OS. For me the fix was to check my PATH and stop the gradle daemon. After that, the daemon re-evaluates the path. E.g.:

gradle --stop
gradle npm
blootsvoets
  • 1,277
  • 11
  • 11
3

I had a similar problem when trying to run a yarn command from a gradle file in Android studio. What solved it for me was to disable the gradle daemon by adding org.gradle.daemon=false to ~/.gradle/gradle.properties. The problem seems to be caused by gradle daemon that somehow caches environment state. If you don't want to add permanent stuff to your gradle.properties you can also try to kill the gradle daemon as suggested above.

Solution suggested by aandriyc in this thread https://github.com/palantir/gradle-docker/issues/162

lejonl
  • 1,453
  • 15
  • 20
  • This is a workaround to the problem, and out of all the answers is the correct solution. It seems that when you run the gradle daemon, the current environment's PATH is not used when looking for the executable to invoke with the Exec task. This looks like a bug in the gradle daemon. I saw this with `executable "${python}"` where I wanted it to run using the python from a virtualenv and not /usr. `org.gradle.daemon=false` makes it work. – Roger Leigh Jun 30 '19 at 12:55
1

I got an error when the src/webapp dir didn't exist in the root project dir.

I ended up with just the following:

task npm(type: Exec) {
        description "Grab NodeJS dependencies (from package.json)"
        workingDir 'src/webapp'
        commandLine npmCommand, "install"
        doLast {
            def d1 = project.file('src/webapp')
            println "d1: $d1, ${d1.exists()}"
        }
}

with no need for the environment fixing, as long as the src/webapp dir was first created. I don't know what your inputs.file value is doing, the npm looks for src/webapp/package.json because of the workingDir being set in the task, so I removed it.

Additionally, you don't need the import for Exec.

If you add the output of ./gradlew npm -S to your question, I'll compare it to my failure and see if I can assist further.

EDIT: I've added a doLast block to the task. It should find the src/webapp dir and print its location and "true" for exists if the directory is there during the run of the task. What does the output say?

Mark Fisher
  • 9,838
  • 3
  • 32
  • 38
  • Mark, I already mentioned the failure caused by `npm` not found. `Caused by: net.rubygrapefruit.platform.NativeException: Could not start 'npm' ... Caused by: java.io.IOException: error=2, No such file or directory ... 5 more` It works fine when I use absolute path of `npm` as `/usr/local/bin/npm`. I tried your suggestion, the issue still is same. – Kane Jul 14 '15 at 13:12
  • I'm getting mixed results now. Can you add the output of "./gradlew npm -S" to your question please? I just found I get the error if I don't create the src/webapp dir first. I get the error "Cannot run program "npm" (in directory "/Users/markf/npm-gradle/src/webapp"): error=2, No such file or directory" – Mark Fisher Jul 14 '15 at 13:34
  • The error "No such file or directory" was happening because the directory is missing in my case, not because it can't find the npm program. Can you paste the exact error you get? You missed the bit I'm interested in in your comment with "...", but check if that directory is there or not. – Mark Fisher Jul 14 '15 at 13:45
  • pls see complete output of gradle in question – Kane Jul 14 '15 at 15:21
  • Does the directory `/Users/kane/git/videome/wechat/src/webapp` exist? – Mark Fisher Jul 14 '15 at 15:24
  • i've added a doLast block to the task you can use to see if the dir exists during the point the task is being run, can you try this and see what the output is? – Mark Fisher Jul 14 '15 at 16:14
  • Mark, pls check the complete gradle script and output in [this gist](https://gist.github.com/zxkane/c560e026c22f8947c0db) – Kane Jul 15 '15 at 03:26
0

Just change to this

ext {
    npmCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? 'npm.cmd' : '/usr/local/bin/npm'
    npmPath = Os.isFamily(Os.FAMILY_WINDOWS) ? '' : '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'
}
csk
  • 418
  • 1
  • 5
  • 11