14

I have a pom that uses the exec-maven-plugin to execute a shell script with three parameters. When running mvn clean install -X -e, it fails at that step with the error,

[DEBUG] Toolchains are ignored, 'executable' parameter is set to C:\dev\intellij\projects\project-in-question\driver/src/main/scripts/dependencies.sh
[DEBUG] Executing command line: [C:\dev\intellij\projects\project-in-question\driver\src\main\scripts\dependencies.sh, C:\dev\intellij\projects\project-in-question\driver\target/project-in-question.dependencies, C:\dev\intellij\projects\project-in-question\driver\target, third-parameter]  

[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (dependencies) on project project-in-question: Command execution failed.: Cannot run program "C:\dev\intellij\projects\project-in-question\driver\src\main\scripts\dependencies.sh" (in directory "C:\dev\intellij\projects\project-in-question\driver"): CreateProcess error=193, %1 is not a valid Win32 application -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (dependencies) on project project-in-question: Command execution failed.

Relevant portion of the pom.xml:

        ...
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.3.2</version>
            <executions>
                <execution>
                   ...
                </execution>
                <execution>
                    <id>dependencies</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <workingDirectory>${project.basedir}</workingDirectory>
                        <executable>${project.basedir}/src/main/scripts/dependencies.sh</executable>
                        <arguments>
                            <argument>${project.build.directory}/${project.artifactId}.dependencies</argument>
                            <argument>${project.build.directory}</argument>
                            <argument>project-in-question</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

I feel like this may be related to Operating Systems, where I'm (the only one) running on Windows 10 x64, and others are running on Macs. If I run this command in Cygwin, it completes successfully, executing the shell script with the correct parameters. Even with cmd.exe, I can execute this script.

But building the project using Maven, it fails every time. I even emptied the shell script so it literally was comprised of the following:

#!/bin/sh
echo "hello world"

While the real, original shell script does take three parameters, I get the exact same error message about %1 not being a valid Win32 application, and this script does not take any arguments, nor does it try to reference any either; it just echoes "hello world."

I did notice that the slashes in the various parameters are mixed, and I'm not sure that's the culprit; it seems more to do with attempting to execute a shell script on Windows from Maven.

Can anyone help me with this and explain what's going on? If any additional details are needed, just let me know and I'll provide more context.

0

4 Answers 4

9
+50

Your commandline is*:

[dependencies.sh, project-in-question.dependencies, target, third-parameter]

But on Windows the dependencies.sh is not an executable. To run it with cygwin you would have to run it like this*:

[c:\cygwin\bin\run.exe, dependencies.sh, project-in-question.dependencies, target, third-parameter]

Now I guess, that the others would not be happy with changing the pom.xml to that.


One possible solution should be to install "Windows Subsystem For Linux".


Another solution would be to create a dependencies.sh.bat containing something like:

c:\cygwin\bin\run.exe dependencies.sh %*

but with this solution you probably have to rename the dependencies.sh on your computer so that windows will pick the .bat file first.


Another compromise might be to change the execution to

<executable>sh</executable>
  <arguments>
    <argument>-c</argument>
    <argument>${project.basedir}/src/main/scripts/dependencies.sh ${project.build.directory}/${project.artifactId}.dependencies ${project.build.directory} project-in-question</argument>

And on your system have a sh.bat in your PATH with:

c:\cygwin\bin\run.exe sh %*

*I omitted the folders for better readability

Sign up to request clarification or add additional context in comments.

1 Comment

got it to work using a combination of your suggestions. need to update to use a profile so that the pom is system-agnostic, and then clean up my various changes a bit. will post final solution when complete.
5

Try using cmd as your executable, followed by /C as first argument and pathname of your shell script as next argument, followed by the rest of your arguments:

            <executable>cmd</executable>
            <arguments>
                <argument>/C</argument>
                <argument>${project.basedir}/src/main/scripts/dependencies.sh</argument>

Comments

2

I would add the cygwin\bin path to the Windows %PATH% environment variable, since Cygwin provides a bash.exe executable. Then modify the .pom to be platform independent:

           ...
                    <execution>
                        <id>dependencies</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <workingDirectory>${project.basedir}</workingDirectory>
                            <executable>bash</executable>
                            <arguments>
                                <argument>${project.basedir}/src/main/scripts/dependencies.sh</argument>
                                <argument>${project.build.directory}/${project.artifactId}.dependencies</argument>
                                <argument>${project.build.directory}</argument>
                                <argument>project-in-question</argument>
                            </arguments>
                        </configuration>
                    </execution>
           ...

As @Samuel Kirschner pointed out above you can also use Windows Subsystem for Linux (WSL) instead of Cygwin which automatically provides the bash executable on the Windows %PATH% and works with the .pom config given

Comments

0

For people in >= 2024 having issues executing script with git-bash.
It may be due to wsl2 being executed instead of git bash when running bash command.

Wsl2 also won't inherit parent's environment variables, which may cause the shell script to break when executed.

Here is a simple solution.

<profile>
    <id>os-windows</id>
    <activation>
        <os>
            <family>windows</family>
        </os>
    </activation>
    <properties>
        <!-- Workaround bash command executing wsl2 instead of git-bash -->
        <bash.path>C:\Program Files\Git\bin\bash.exe</bash.path>
    </properties>
</profile>
<profile>
    <id>os-unix</id>
    <activation>
        <os>
            <family>unix</family>
        </os>
    </activation>
    <properties>
        <!-- Running maven from wsl2 fall in unix family, which is fine -->
        <bash.path>bash</bash.path>
    </properties>
</profile>

Then simply specify the path when executing the plugin

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>example</id>
            <phase>install</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <arguments>
                    <argument>--verbose</argument>
                </arguments>
                <environmentVariables>
                    <EXAMPLE_VAR>value</EXAMPLE_VAR>
                </environmentVariables>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <executable>${bash.path}</executable>
        <commandlineArgs>-c ../example.sh</commandlineArgs>
        <environmentVariables>
            <VAR_ONE>Hello world</VAR_ONE>
            <VAR_TWO>example</VAR_TWO>
        </environmentVariables>
    </configuration>
</plugin>

If using wsl2 is required then here is a workaround for passing variables to the script in wsl2:

<configuration>
    <!-- bash defaults to wsl2 when it's installed -->
    <executable>bash</executable>
    <arguments>
        <argument>-c</argument>
        <argument>MY_VAR=${my.var.value} ./example.sh</argument>
        <!-- warn be aware of spaces in the value  -->
    </arguments>
</configuration>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.