2014-01-21 54 views
0

我们有一个web应用程序,它可以帮助学习者通过实践学习。所以有一个Java模块。为此,我们需要执行由用户编写的Java程序并读取其输出并将其显示给用户。执行java程序并以编程方式读取其输出。不执行java.exe(java应用程序启动器)

目前我们使用C#服务来执行此操作。我们将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; 
} 

我只给出了执行的代码类似的代码有编译。上述方法唯一的问题是,当有人以无限循环运行java程序时,服务器上会运行java.exe并占用50%或更多的CPU百分比,之后出现任何请求失败!

我们采用了一种解决方案,通过运行一个单独的线程来检查系统中运行超过3秒的所有“java.exe”,并终止它们。

仍然这种方法将开始失败,因为用户的数量将开始增加。就像10个用户同时执行一个程序一样,服务器将无法处理它。

我正在寻找一种解决方案,它可以在不运行java.exe的情况下编译和运行java程序。解决方案可以是java或c#(最好是c#)。我发现了一些使用java编写的使用JavaCompiler类的代码,我还发现了使用反射API执行程序的代码,但是我找不到执行后如何读取输出。

请帮忙!!在此先感谢...

+1

您正在使您的系统对安全风险高度开放。与其自己编写所有这些内容,您可能想要为此尝试一个现成的系统。你正在建设的这种系统称为“在线评委”。有关该主题的许多链接,请参阅此处:http://en.wikipedia.org/wiki/Online_judge –

回答

0

我同意user2613329,但你仍然可以按照java.exe的方法。您可以对用户执行进行排队并限制正在运行的执行次数。

0

您可以编写自己的Java应用程序,它将定期加载传入的.java文件,编译它们,然后在不同的线程中运行它们的main方法。然后可以在执行时间内限制这些线程,例如使用ExecutorService(请参阅Killing thread after some specified time limit in Java)。