我正在尝试从java程序中运行一个groovy脚本,作为一个单独的进程(为了避免jar冲突问题)。
这是我到目前为止所做的:
public static void runGroovyScript(Path scriptPath, String... args) {
try {
List<String> argsList = newArrayList();
argsList.add("groovy");
argsList.add(scriptPath.toAbsolutePath().toString());
Collections.addAll(argsList, args);
Process process = Runtime.getRuntime().exec(argsList.toArray(new String[argsList.size()]));
// Note - out input is the process' output
String input = Streams.asString(process.getInputStream());
String error = Streams.asString(process.getErrorStream());
logger.info("Groovy output for " + Arrays.toString(args) + "\r\n" + input);
logger.info("Groovy error for " + Arrays.toString(args) + "\r\n" + error);
int returnValue = process.waitFor();
if (returnValue != 0) {
throw new RuntimeException("Groovy process returned " + returnValue);
}
} catch (Throwable e) {
throw new RuntimeException("Failure running build script: " + scriptPath + " " + Joiner.on(" ").join(args), e);
}
}
问题当然是groovy
不是公认的命令。由于PATH
环境变量以及cmd.exe所做的解析,它可以在命令行中运行。在linux上,有一种不同的解析机制。什么是与平台无关的方法来查找groovy可执行文件,以便将其传递给Runtime.exec()
?
答案 0 :(得分:1)
一种干净的方法是将可执行文件的绝对路径作为某种配置参数传递给您的应用程序。
你也可以解析PATH
环境变量并自己搜索,但是:
PATH
环境变量,该变量指向名为groovy
的恶意程序。我建议采取不同的方法。您可以使用单独的ClassLoader来加载groovy脚本。 Advanages:
另见:
您也可以将它与Java Scripting API结合使用。这可能是最强大和最灵活的解决方案。为此,请参阅
答案 1 :(得分:1)
java-sandbox允许远程执行沙盒代码。看看http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html。
答案 2 :(得分:0)
我们实际上摆弄了另一个类装载机,但没有雪茄。我们所做的是在系统变量中定义groovy可执行文件的位置,并为Windows添加“cmd / c”:
import com.google.common.base.Joiner;
import org.apache.commons.lang.SystemUtils;
import org.apache.log4j.Logger;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static org.apache.ivy.util.Checks.checkNotNull;
public class GroovyRunner {
private final static Logger logger = LoggerHelper.getLogger();
public static void runGroovyScript(Path scriptPath, String... args) {
try {
List<String> argsList = newArrayList();
String groovyPath = System.getenv("PLAY_GROOVY_PATH");
if (SystemUtils.IS_OS_WINDOWS) {
// Window, no easy default for PLAY_GROOVY_PATH
checkNotNull(groovyPath, "Missing Env Var 'PLAY_GROOVY_PATH'");
argsList.add("cmd");
argsList.add("/c");
argsList.add(groovyPath);
} else {
if (groovyPath == null) {
// Provide a reasonable default for linux
groovyPath = "/usr/bin/groovy";
}
argsList.add(groovyPath);
}
argsList.add(scriptPath.toAbsolutePath().toString());
Collections.addAll(argsList, args);
String join = Collections3.join(argsList, " ");
ExecCommand process = new ExecCommand(join);
// Note - out input is the process' output
String output = process.getOutput();
String error = process.getError();
logger.info("Groovy output for " + Arrays.toString(args) + "\r\n" + output);
logger.info("Groovy error for " + Arrays.toString(args) + "\r\n" + error);
if (process.getReturnValue() != 0) {
throw new RuntimeException("Groovy process returned " + process.getReturnValue());
}
} catch (Throwable e) {
throw new RuntimeException("Failure running groovy script: " + scriptPath + " " + Joiner.on(" ").join(args), e);
}
}
}