我正在尝试从 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()
的独立于平台的方法是什么?
最佳答案
一种简洁的方法是将可执行文件的绝对路径作为某种配置参数传递给您的应用程序。
您还可以解析 PATH
环境变量并自行搜索,但是:
- 不同的平台可以有不同的搜索可执行文件的机制。例如,他们使用不同的 path separator characters ,你需要处理这个问题。
- 这是一种安全问题。攻击者可能会将指向名为
groovy
的恶意程序的PATH
环境变量传递给您的程序。
我建议采取不同的方法。您可以使用单独的类加载器来加载您的 groovy 脚本。优点:
- 您还可以避免 JAR 冲突问题。
- 但您不需要生成任何外部进程。
- 您还可以使用自定义 SecurityManager 限制允许脚本执行的操作.
- 您可以更好地与脚本进行通信 - 使用方法调用而不是仅使用 stdin/out。
另请参阅:
- Java class loader tutorial
- Java security: Sandboxing plugins loaded via URLClassLoader
- URLClassloader
您还可以将它与 Java 脚本 API 结合起来。这也许是最强大、最灵活的解决方案。为此,请参阅
关于java - 如何从 Java 作为单独的进程运行 groovy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12158271/