简体   繁体   English

执行Java程序并以编程方式读取其输出。 不执行java.exe(Java应用程序启动器)

[英]Executing java program and reading its output programmatically. Without executing java.exe(java application launcher)

we have a web application, which helps learners to learn by practice. 我们有一个网络应用程序,可帮助学习者通过实践学习。 So there is a module for java as well. 因此,还有一个适用于Java的模块。 For this we require executing the java program written by user and reading its output and displaying it to user. 为此,我们需要执行用户编写的Java程序并读取其输出并将其显示给用户。

Currently we use a C# service to do this. 当前,我们使用C#服务执行此操作。 We save the java program in a .java file on server and compile it by executing javac.exe command and then run it by executing java.exe and read the output from console and transferring it back to user. 我们将Java程序保存在服务器上的.java文件中,并通过执行javac.exe命令进行编译,然后通过执行java.exe来运行它,并从控制台读取输出并将其传输回用户。

public String ExecuteProgramFetchOutput(String classpath, String filename){
    String output = "";
    String command = "java -classpath " + classpath + " " + filename;
    System.Diagnostics.Process _objProcess = new System.Diagnostics.Process();
    try
    {
        System.Diagnostics.ProcessStartInfo _objProcessInfo = new System.Diagnostics.ProcessStartInfo();
        _objProcessInfo.FileName = "cmd.exe";
        _objProcessInfo.RedirectStandardInput = true;
        _objProcessInfo.RedirectStandardOutput = true;
        _objProcessInfo.RedirectStandardError = true;
        _objProcessInfo.CreateNoWindow = true;
        _objProcessInfo.UseShellExecute = false;
        _objProcess.StartInfo = _objProcessInfo;
        _objProcess = System.Diagnostics.Process.Start(_objProcessInfo);
        _objProcess.StandardInput.AutoFlush = true;
        _objProcess.StandardInput.WriteLine(command);
        _objProcess.WaitForExit(3000);

        if (!_objProcess.HasExited)
        {
            _objProcess.Kill();
        }
        output = _objProcess.StandardOutput.ReadToEnd();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        output = ex.ToString();
    }
    finally
    {
        if (_objProcess != null)
        {
            if (!_objProcess.HasExited)
            {
                _objProcess.Kill();
            }
            _objProcess.Dispose();
        }
    }
    return ouput;
}

I have only given the code for execution similar kind of code is there for compilation. 我只给了执行代码,那里有类似的代码可以编译。 The only problem with the above approach is that when someone runs the java program with an infinite loop there is a java.exe running on the server and taking CPU percentage of 50% and more, After that any request which comes fails!! 上面方法的唯一问题是,当有人运行无限循环的Java程序时,服务器上运行的是java.exe并占用了50%或更多的CPU百分比,此后发出的任何请求都会失败!

We employed a solution to that as well by running a separate thread which checks in the system what and all "java.exe"s running for more than 3 secs and terminating them. 我们还通过运行一个单独的线程来解决此问题,该线程在系统中检查什么以及所有“ java.exe”在运行超过3秒钟并终止它们。

Still this approach will start failing as the number of users will start increasing. 随着用户数量的增加,这种方法仍然会失败。 As if 10 users simultaneously execute a program the server will not be able to handle it. 好像有10个用户同时执行一个程序,服务器将无法处理该程序。

I am looking for a solution which can compile and run the java program without running the java.exe. 我正在寻找一种无需运行java.exe即可编译和运行Java程序的解决方案。 The solution can be either in java or c# (preferably c#). 解决方案可以是Java或c#(最好是c#)。 I found some code for compiling using java by using JavaCompiler class, I also found code for executing the program using reflection API, but I could not find how to read the output after executing. 我找到了一些使用JavaCompiler类使用java进行编译的代码,也找到了使用反射API执行该程序的代码,但是执行后找不到如何读取输出的代码。

Please help!! 请帮忙!! Thanks in advance... 提前致谢...

I agree with user2613329, but you could still follow the java.exe approach. 我同意user2613329,但是您仍然可以遵循java.exe方法。 You could queue user execution and limit the number of running executions. 您可以将用户执行排队,并限制正在运行的执行次数。

You can write your own Java application that will periodically load incoming .java files, compile them, and then run their main methods in separate threads. 您可以编写自己的Java应用程序,该应用程序将定期加载传入的.java文件,进行编译,然后在单独的线程中运行其main方法。 You can then limit these threads in execution time, for example using an ExecutorService (see Killing thread after some specified time limit in Java ). 然后,您可以在执行时间上限制这些线程,例如使用ExecutorService (请参阅在Java中指定的时间限制后杀死线程 )。

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

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