Skip to content

Commit

Permalink
[MJLINK-85] Fix issue with single quoting every argument (#212)
Browse files Browse the repository at this point in the history
Each argument is first double quoted, but because of the default
configuration of `org.apache.maven.shared.utils.cli.shell.Shell`
is also single quoted on top. This leads to a shell command line
which is not executable.

To fix this, leave the double quoting of each argument as it was,
disable the single quoting of each argument with `Shell` configuration
and wrap all the arguments as a whole string with single quotes, so
that they are passed into `bin/sh -c`, example:

```
bin/sh -c '"--module-path" "foo:bar" "--add-modules" "mod1,mod2"'
```
  • Loading branch information
matriv authored Dec 2, 2024
1 parent a4f35a5 commit 3a466c1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
Expand Down Expand Up @@ -72,9 +73,7 @@ protected Optional<Toolchain> getToolchain() {
public int executeJlink(List<String> jlinkArgs) throws MojoExecutionException {
File jlinkExecutable = getJlinkExecutable();
getLog().info("Toolchain in maven-jlink-plugin: jlink [ " + jlinkExecutable + " ]");

Commandline cmd = createJLinkCommandLine(jlinkArgs);
cmd.setExecutable(jlinkExecutable.getAbsolutePath());
Commandline cmd = createJLinkCommandLine(jlinkExecutable, jlinkArgs);

return executeCommand(cmd);
}
Expand All @@ -100,10 +99,15 @@ public Optional<File> getJmodsFolder(/* nullable */ File sourceJdkModules) {
return Optional.of(jmodsFolder);
}

private Commandline createJLinkCommandLine(List<String> jlinkArgs) {
static Commandline createJLinkCommandLine(File jlinkExecutable, List<String> jlinkArgs) {
Commandline cmd = new Commandline();
jlinkArgs.forEach(arg -> cmd.createArg().setValue("\"" + arg + "\""));
// Don't quote every argument with single quote, but instead quote them with double quotes
// and enclose all of them with single quotes to then be passed to the shell command as
// /bin/sh -c '<all arguments, each one quoted with double quotes>'
cmd.getShell().setQuotedArgumentsEnabled(false);

String jlinkArgsStr = jlinkArgs.stream().map(arg -> "\"" + arg + "\"").collect(Collectors.joining(" "));
cmd.setExecutable(jlinkExecutable.getAbsolutePath() + " " + jlinkArgsStr);
return cmd;
}

Expand Down Expand Up @@ -148,7 +152,7 @@ private String getJLinkExecutable() {
private int executeCommand(Commandline cmd) throws MojoExecutionException {
if (getLog().isDebugEnabled()) {
// no quoted arguments ???
getLog().debug(CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", ""));
getLog().debug(CommandLineUtils.toString(cmd.getCommandline()));
}

CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
Expand Down
22 changes: 21 additions & 1 deletion src/test/java/org/apache/maven/plugins/jlink/JLinkMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
*/
package org.apache.maven.plugins.jlink;

import java.io.File;
import java.lang.reflect.Field;
import java.util.List;

import org.apache.maven.shared.utils.cli.Commandline;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class JLinkMojoTest {

@Test
void quote_every_argument() throws Exception {
void double_quote_every_argument() throws Exception {
// given
JLinkMojo mojo = new JLinkMojo();
Field stripDebug = mojo.getClass().getDeclaredField("stripDebug");
Expand All @@ -41,4 +43,22 @@ void quote_every_argument() throws Exception {
// then
assertThat(jlinkArgs).noneMatch(arg -> arg.trim().isBlank());
}

@Test
void single_quotes_shell_command() throws Exception {
// given
JLinkMojo mojo = new JLinkMojo();
Field stripDebug = mojo.getClass().getDeclaredField("stripDebug");
stripDebug.setAccessible(true);
stripDebug.set(mojo, Boolean.TRUE);

// when
List<String> jlinkArgs = mojo.createJlinkArgs(List.of("foo", "bar"), List.of("mvn", "jlink"));
Commandline cmdLine = JLinkExecutor.createJLinkCommandLine(new File("/path/to/jlink"), jlinkArgs);

// then
assertThat(cmdLine.toString())
.isEqualTo(
"/bin/sh -c '/path/to/jlink \"--strip-debug\" \"--module-path\" \"foo:bar\" \"--add-modules\" \"mvn,jlink\"'");
}
}

0 comments on commit 3a466c1

Please sign in to comment.