简体   繁体   English

使用Runtime.exec()运行Java程序?

[英]Running a java program using Runtime.exec()?

Im creating a java IDE application and have encountered a problem with running the users code. 我正在创建一个Java IDE应用程序,并且在运行用户代码时遇到问题。 Currently i am using Runtime.exec() to compile and then run the program while using the InputStream and ErrorStream to generate the output. 目前,我正在使用Runtime.exec()进行编译,然后在使用InputStream和ErrorStream生成输出时运行程序。 Which works fine if the program never stops to ask for input from the user. 如果程序永不停止请求用户输入,则可以正常工作。 In this case the program will crash and does not display any output. 在这种情况下,程序将崩溃,并且不显示任何输出。 I think this is because the readers will not read the output untill the program has finished running. 我认为这是因为在程序完成运行之前,读者不会读取输出。

I have tried using threads in order to get around this but with no success. 我尝试使用线程来解决此问题,但没有成功。 Is there any way to pause the program during run time to allow user input or is there any other way that i could create a console to run the users code? 有什么方法可以在运行时暂停程序以允许用户输入,或者有没有其他方法可以创建控制台来运行用户代码?

I think this is because the readers will not read the output untill the program has finished running. 我认为这是因为在程序完成运行之前,读者不会读取输出。

I don't know about exactly how you would get the process to "wait" until user input is written to the output stream of the process, but I can help clarify some things for you. 在将用户输入写入流程的输出流之前,我不知道您将如何确切地使流程“等待”,但是我可以为您澄清一些事情。

I know that the readers certainly do not wait until the program finishes running to read the output stream. 我知道读者当然不会等到程序完成运行才能读取输出流。

        LoggingProcessWrapperUtil.myPB = new ProcessBuilder(command);
        LoggingProcessWrapperUtil.myPB.redirectInput(Redirect.PIPE);
        LoggingProcessWrapperUtil.myPB.redirectOutput(Redirect.PIPE);

        StringBuilder commandStr = new StringBuilder();

        for (String str : command) {
            commandStr.append(str);
            commandStr.append(" ");
        }

        LoggingProcessWrapperUtil.log.debug("Executing command : {}", commandStr);

        Process p = LoggingProcessWrapperUtil.myPB.start();

        LoggingProcessWrapperUtil.log.debug("Starting ProcessStreamWorker pointed at process");

        for (String str : args_to_write_on_stream) {
            LoggingProcessWrapperUtil.log.debug("Writing arguments on inbound outputstream:");
            LoggingProcessWrapperUtil.log.debug(str);
        }

        ProcessStreamWorker w = new ProcessStreamWorker(p, args_to_write_on_stream);

        new Thread(w).start();

        int exitCode = w.waitOn(timeoutMS);

        SimpleEntry<Integer, String> returnEntry = new SimpleEntry<Integer, String>(exitCode,
                w.getAggregateOutput());

        return returnEntry;

This short snippet was my solution to a related problem, albeit I was looking to automate a process, not pause it for user input. 这个简短的代码片段是我对相关问题的解决方案,尽管我希望使流程自动化,而不是为了用户输入而暂停它。 I build the process, start it, and then immediately put it into a runnable process wrapper that appends the arguments onto the OutputStream of the process. 我先构建流程,然后启动它,然后立即将其放入可运行的流程包装器中,该包装器将参数附加到流程的OutputStream上。 This has worked for me, so the process output stream certainly does get read in realtime. 这对我有用,因此流程输出流确实可以实时读取。

One thing that you can try is ProcessBuilder.redirectInput and ProcessBuilder.redirectOutput(Redirect.Inherit), if you have a CLI java app launching another CLI app then the process you are launching should also accept input/output activity from the console window that your main app is running on. 您可以尝试的一件事是ProcessBuilder.redirectInput和ProcessBuilder.redirectOutput(Redirect.Inherit),如果您有一个CLI Java应用程序正在启动另一个CLI应用程序,那么您正在启动的进程还应该接受来自控制台窗口的输入/输出活动,主应用程序正在运行。

If you'd like there is another way to do what you requested. 如果您愿意,可以采用另一种方法来完成您所要求的操作。 You could redirect the input stream of your process (jdk 1.7 is required for this code): 您可以重定向流程的输入流(此代码需要jdk 1.7):

try {
     ProcessBuilder pb = new ProcessBuilder("cmd");  
     pb.redirectErrorStream(true);  // merge output and error streams
     pb.redirectInput(ProcessBuilder.Redirect.from(System.in));
     pb.redirectOutput(ProcessBuilder.Redirect.to(System.out));


     Process p = pb.start();
     int exitValue = p.waitFor();
     System.out.println("Process Completed with exit value of " + exitValue);
  } catch (java.io.IOException ex) {
  } catch (InterruptedException ex) {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM