Tag: apache commons exec

使用流程构建器或apache commons exec执行外部程序

我需要执行一个外部应用程序,它返回大量数据(需要2个多小时才能完成)并连续输出数据。 我需要做的是异步执行该程序并捕获文件中的输出。 我尝试使用java进程构建器,但它似乎挂起并仅在程序退出或强制终止时返回输出。 我尝试使用进程构建器并spwaned一个新的线程来捕获输出,但它仍然没有帮助。 然后我读了关于apache commons exec并尝试了同样的事情。 然而,这似乎也需要很长时间并返回不同的错误代码(对于相同的输入) CommandLine cmdLine = new CommandLine(“/opt/testsimulator”); DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); ByteArrayOutputStream stdout = new ByteArrayOutputStream(); PumpStreamHandler psh = new PumpStreamHandler(stdout); ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000); Executor executor = new DefaultExecutor(); executor.setStreamHandler(psh); executor.setWatchdog(watchdog); try { executor.execute(cmdLine); } catch (ExecuteException e) { // TODO Auto-generated catch block e.printStackTrace(); } […]

使用Java在Windows上“杀死进程树”

我有一个Java webstart进程,它是Windows批处理脚本的一部分。 在这种情况下,我在批处理脚本中使用javaws命令。 使用“apache commons exec”以编程方式调用此匹配脚本(start.bat)。 在某些情况下,javaws调用的java进程会挂起,我必须从批处理脚本start.bat开始终止整个进程线程。 是否有通过apache commons exec杀死整个进程树的编程方式? 我尝试过使用“execWatchdog.destroyProcess();” 在“start.bat”脚本上。 但是它只会杀死start.bat进程而不是整个进程树。 有没有办法通过apache-commons-exec或类似的代码杀死整个进程树? 我已经看到这个问题在c ++中执行相当于“杀死进程树”的Windows ,它在c ++中执行相同的任务。 我想知道是否有人通过JNI实现了调用Windows本机系统调用。

Apache Commons Exec为包含空格的参数生成了太多引号?

要么Apache Commons Exec中存在错误,要么我错误地使用API​​,但是当我使用CommandLine类添加包含空格的参数时,会添加一些引号,然后是给定参数的一部分。 例如:当我调用java “what version”我得到java.lang.NoClassDefFoundError: what version ,当我调用java “\”what version\”” (包含转义引号,它们是命令行参数本身的一部分) ),我得到java.lang.NoClassDefFoundError: “what version” 。 因此,以下测试失败,因为正如您在最后一行中所看到的,Apache Exec正在生成后一版本,它应该生成第一个版本: @Test public void testArgumentQuoting() throws Exception { DefaultExecutor executor = new DefaultExecutor(); DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); ByteArrayOutputStream out = new ByteArrayOutputStream(); PumpStreamHandler streamHandler = new PumpStreamHandler(out, out); executor.setStreamHandler(streamHandler); CommandLine cmdLine = new CommandLine(“java”); cmdLine.addArgument(“what version”); executor.execute(cmdLine, […]

无法使用Apache Commons Exec为命令提供多个输入并提取输出

我正在编写一个Java应用程序,需要使用Apache Commons Exec库来使用外部命令行应用程序。 我需要运行的应用程序具有相当长的加载时间,因此最好保持一个实例处于活动状态而不是每次都创建一个新进程。 应用程序的工作方式非常简单。 一旦启动,它会等待一些新输入并生成一些数据作为输出,两者都使用应用程序的标准I / O. 因此,我们的想法是执行CommandLine,然后将PumpStreamHandler与三个独立的流(输出,错误和输入)一起使用,并使用这些流与应用程序进行交互。 到目前为止,我已经在基本场景中完成了这项工作,我有一个输入,一个输出,然后应用程序关闭。 但是一旦我试图进行第二次交易,就会出现问题。 在创建了我的CommandLine之后,我创建了我的Executor并像这样启动它: this.executor = new DefaultExecutor(); PipedOutputStream stdout = new PipedOutputStream(); PipedOutputStream stderr = new PipedOutputStream(); PipedInputStream stdin = new PipedInputStream(); PumpStreamHandler streamHandler = new PumpStreamHandler(stdout, stderr, stdin); this.executor.setStreamHandler(streamHandler); this.processOutput = new BufferedInputStream(new PipedInputStream(stdout)); this.processError = new BufferedInputStream(new PipedInputStream(stderr)); this.processInput = new BufferedOutputStream(new PipedOutputStream(stdin)); this.resultHandler […]

来自apache-commons exec的进程输出

我在这里结束了我的智慧。 我确信这很简单,我很可能在理解java和流时遇到很大漏洞。 我认为有这么多课程,我试图通过API来弄清楚我何时以及如何使用大量的输入/输出流,我有点不知所措。 我刚刚了解了apache commons库的存在(自学java失败),我正在尝试将我的一些Runtime.getRuntime()。exec转换为使用commons – exec。 已经修复了一些每6个月一次这个问题的问题,然后消除了exec的风格问题。 代码执行perl脚本,并在GUI运行时显示GUI中脚本的stdout。 调用代码在swingworker内部。 我迷路了如何使用pumpStreamHandler ……无论如何这里是旧代码: String pl_cmd = “perl script.pl” Process p_pl = Runtime.getRuntime().exec( pl_cmd ); BufferedReader br_pl = new BufferedReader( new InputStreamReader( p_pl.getInputStream() ) ); stdout = br_pl.readLine(); while ( stdout != null ) { output.displayln( stdout ); stdout = br_pl.readLine(); } 我想这就是我在很久以前不完全理解的复制粘贴代码。 上面我假设正在执行该过程,然后抓取输出流(通过“getInputStream”?),将其放入缓冲读取器,然后将循环直到缓冲区为空。 我没有得到的是为什么这里不需要’waitfor’样式命令? 是否可能有一段时间缓冲区将为空,退出循环,并在进程仍在进行时继续? 当我运行它时,情况似乎并非如此。 […]

如何将字符串参数传递给使用Apache Commons Exec启动的可执行文件?

我需要将一个文本参数传递给使用Apache Commons Exec启动的命令的stdin(对于好奇,命令是gpg,参数是密钥库的密码; gpg没有明确提供密码的参数,仅从stdin接受它。 另外,我需要它来支持Linux和Windows。 在shell脚本中,我会这样做 cat mypassphrase|gpg –passphrase-fd 要么 type mypassphrase|gpg –passphrase-fd 但是类型在Windows上不起作用,因为它不是可执行文件,而是命令内置的命令(cmd.exe)。 代码不起作用(出于上述原因)如下。 为此产生一个完整的shell太难看了,我一直在寻找更优雅的解决方案。 不幸的是,BouncyCastle库和PGP之间存在一些不兼容问题,因此我无法在(非常短的)时间内使用完全编程的解决方案。 提前致谢。 CommandLine cmdLine = new CommandLine(“type”); cmdLine.addArgument(passphrase); cmdLine.addArgument(“|”); cmdLine.addArgument(“gpg”); cmdLine.addArgument(“–passphrase-fd”); cmdLine.addArgument(“0”); cmdLine.addArgument(“–no-default-keyring”); cmdLine.addArgument(“–keyring”); cmdLine.addArgument(“${publicRingPath}”); cmdLine.addArgument(“–secret-keyring”); cmdLine.addArgument(“${secretRingPath}”); cmdLine.addArgument(“–sign”); cmdLine.addArgument(“–encrypt”); cmdLine.addArgument(“-r”); cmdLine.addArgument(“recipientName”); cmdLine.setSubstitutionMap(map); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine);