您可以告诉我一种从Java执行进程的方法,而不考虑底层操作系统吗?例如。
Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");
以上行在Windows环境中执行Maven但是如何在任何操作系统中运行以上命令?
如果我在开始时没有添加"cmd/c"
,那么我无法在Windows环境中运行,并且错误显示cannot find mvn.bat
,尽管maven home设置正确。
答案 0 :(得分:3)
您可以检查您所拥有的操作系统类型,然后执行命令行语句。
为了检查操作系统类型,您需要检索os.name
系统属性的值:
String OS = System.getProperty("os.name").toLowerCase();
然后使用简单的if/else
语句,您可以根据操作系统的类型执行命令行语句。
if (isUnix()) {
String statement = new String[] { "/bin/bash", "-c", "mvn clean install" };
Process p = Runtime.getRuntime().exec(statement);
else if (isWindows()) {
Process p = Runtime.getRuntime().exec("cmd /c mvn clean install");
}
...
检查操作系统类型的辅助方法:
public boolean isUnix() {
return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );
}
public boolean isWindows() {
return (OS.indexOf("win") >= 0);
}
您可以找到更多信息here。
答案 1 :(得分:0)
您可能必须检查它是哪个操作系统,然后将cmd /c
替换为该操作系统的相关命令。
请参阅此问题,了解如何确定您正在运行的系统:How do I programmatically determine operating system in Java?
答案 2 :(得分:0)
你真的不能“从Java执行进程而不管底层操作系统”,因为Runtime.exec
在操作系统之上转发启动命令。然后,您必须描述要启动的进程以及执行此操作的方法。
但是,您可以通过为您知道的进程实现一个ProcessLauncher
接口并为每个操作系统创建子类来“虚拟化”进程启动
如果工厂检测到您的操作系统,并创建正确的ProcessLauncher,那么您应该没问题
答案 3 :(得分:0)
执行外部程序是根据定义而非平台无关的。程序安装可能有不同的地方,PATH的不同设置或不同的调用语法。 (例如,Windows上的/all
和unix上的--all
。 (更不用说同一个任务可能有来自不同人的不同程序。)
您最好的选择是为您的程序使用配置文件,您可以在其中指定程序以及如何调用它,或者以特定于平台的方式设置程序执行环境(例如,使用start) .bat / start.sh)并使用System.getEnv()
。
我个人最喜欢的是第一种方法,因为它不会产生副作用。另一方面,第二个允许“系统黑客”在那里放置一些代码...... aehm ......他们的东西(例如看Tomcat的startup.sh/bat catalina.sh/bat):)
答案 4 :(得分:0)
对于这种特殊情况,有些库可以提供帮助,例如,您可以以编程方式使用maven-ant-tasks库,因为Ant会隐藏其独立于平台的API背后的所有特定于平台的混乱:
Project p = new Project();
p.init();
Mvn mvnTask = new Mvn();
mvnTask.setProject(p);
mvnTask.setPom(new File("path/to/pom.xml"));
mvnTask.createArg().setValue("clean");
mvnTask.createArg().setValue("install");
mvnTask.perform();
这应该在所有平台上都相同,并且不需要mvn
的独立安装 - 您只需要类路径上的Ant和maven-ant-tasks
库以及Mvn
任务将在第一次运行时下载所需的任何其他内容。
答案 5 :(得分:0)
更好地使用apache commons exec来运行外部程序,因为存在许多OS平台特定问题,如输出流缓冲区大小,错误处理等。