javaenvironment-variablesapache-commons-exec

Commons exec looking for main class in environment variable value


I'm trying to launch a script from within a Java application using Apache commons exec, and getting the following error:

Error: Could not find or load main class "-DappEnv=te
org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
    at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:402)
    at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:164)
    at TestRunner.runTest(TestRunner.java:37)
    at TestMain.main(TestMain.java:6)

For the following code:

String jOpts = "JAVA_OPTS=\"-DappEnv=te -DsetInstance=true -Dinstance=.01\"";
String command = "/path/to/bin/script.sh -s argVal";
try {
  Map<String, String> procEnv = EnvironmentUtils.getProcEnvironment();
  EnvironmentUtils.addVariableToEnvironment(procEnv, jOpts);
  CommandLine cmdLine = CommandLine.parse(command);
  DefaultExecutor executor = new DefaultExecutor();
  executor.setWorkingDirectory(new File("/path/to"));
  executor.execute(cmdLine, procEnv);
} catch (Exception e) {
  e.printStackTrace();
}

The error is throwing me for a loop, because it appears to be splitting a quoted value for an environment variable and looking for a class by that name instead of running the command with the environment variable. For what it's worth, the following executes fine in bash:

JAVA_OPTS="-DappEnv=te -DsetInstance=true -Dinstance=.01" /path/to/bin/script.sh -s argVal

Can anyone offer some insight as to why that quoted value is being split on whitespace, and/or why it's looking for a main class in the value of JAVA_OPTS? Am I using the environment map properly?


Solution

  • Part of the problem was exec adding its own quotes to the value of JAVA_OPTS. Without quotes around the value, the environment variable gets set fine:

    String jOpts = "JAVA_OPTS=-DappEnv=te -DsetInstance=true -Dinstance=.01";
    

    The command is also in the wrong format. The argument passed to commandLine.parse() should be just the name of the program to run:

    String command = "/path/to/bin/script.sh";
    CommandLine cmdLine = CommandLine.parse(command);
    

    The remaining arguments need to be added with addArgument():

    cmdLine.addArgument("-s");
    cmdLine.addArgument("argVal");