vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
618 stars 167 forks source link

Exceptions when building on Docker: Cannot run program "which" #8083

Open tulioag opened 4 years ago

tulioag commented 4 years ago

I get several exceptions like this when trying to build a project on a docker image.

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

The build still continues running after the exceptions, it is unclear to me what are the effects.

According to this answer https://stackoverflow.com/a/677212 , command -v would be a more portable alternative to which.

The issue can be reproduced by building an image based in this Dockerfile

FROM maven:latest
RUN curl -sL https://github.com/vaadin/vaadin-tabs-flow/archive/master.tar.gz | tar xz \
    && cd vaadin-tabs-flow-master \
    && mvn install -DskipTests -Dmaven.javadoc.skip=true

Example exception

[ERROR] Failed to execute the command '[which, pnpm]'
java.io.IOException: Cannot run program "which": error=2, No such file or directory
    at java.lang.ProcessBuilder.start (ProcessBuilder.java:1128)
    at java.lang.ProcessBuilder.start (ProcessBuilder.java:1071)
    at com.vaadin.flow.server.frontend.FrontendToolsLocator.executeCommand (FrontendToolsLocator.java:120)
    at com.vaadin.flow.server.frontend.FrontendToolsLocator.tryLocateTool (FrontendToolsLocator.java:75)
    at com.vaadin.flow.server.frontend.FrontendTools.getPnpmExecutable (FrontendTools.java:311)
    at com.vaadin.flow.server.frontend.FrontendTools.getSuitablePnpm (FrontendTools.java:635)
    at com.vaadin.flow.server.frontend.FrontendTools.ensurePnpm (FrontendTools.java:381)
    at com.vaadin.flow.server.frontend.FrontendTools.doEnsurePnpm (FrontendTools.java:586)
    at com.vaadin.flow.server.frontend.FrontendTools.getPnpmExecutable (FrontendTools.java:230)
    at com.vaadin.flow.server.frontend.TaskRunNpmInstall.runNpmInstall (TaskRunNpmInstall.java:177)
    at com.vaadin.flow.server.frontend.TaskRunNpmInstall.execute (TaskRunNpmInstall.java:87)
    at com.vaadin.flow.server.frontend.NodeTasks.execute (NodeTasks.java:587)
    at com.vaadin.flow.plugin.maven.BuildFrontendMojo.runNodeUpdater (BuildFrontendMojo.java:173)
    at com.vaadin.flow.plugin.maven.BuildFrontendMojo.execute (BuildFrontendMojo.java:126)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:564)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
pleku commented 4 years ago

The command is used for detecting all the frontend tools used, node, bower, npm, pnpm, webpack ... While the failure is visible, it will not have any effect as this is just "overly verbose way" of indicating that we were not able to discover the used tool and will install it in almost all cases.

But it seems that there might be some undesired side effects from which so it should not be used.

pleku commented 4 years ago

Changing to use command -v instead of which makes the output differ and that would require changing the logic in which the tools are located, so it would require some rework. At least in TC all unit tests trying to locate anything would start to fail.

So in case we discover how using which will actually be broken or cause undesired side effects, this does not seem like a priority thing to do.

tulioag commented 4 years ago

I did some further investigation on that issue using these images.

docker run -it  maven:3-jdk-8 which ls
docker run -it  maven:3-jdk-8 command -v ls
docker run -it  maven:3-jdk-8 sh -c 'command -v ls'
docker run -it  maven:latest which ls
docker run -it  maven:latest command -v ls
docker run -it  maven:latest sh -c 'command -v ls'
docker run -it  maven:alpine which ls
docker run -it  maven:alpine command -v ls
docker run -it  maven:alpine sh -c 'command -v ls'

The only command that worked on all was sh -c 'command -v ls', because command is in many cases a shell builtin.

which is available on Debian and Alpine, but not on Oracle Linux. command is available as a standalone command only on Oracle Linux, but is always present at least as a shell builtin.