我们有一个网络应用程序,可以帮助学习者通过练习来学习。所以java也有一个模块。为此,我们需要执行用户编写的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百分比,之后任何请求都会失败!
我们通过运行一个单独的线程来使用一个解决方案,该线程检查系统中运行的所有“java.exe”超过3秒并终止它们。
当用户数量开始增加时,这种方法仍然会失败。好像10个用户同时执行程序一样,服务器将无法处理它。
我正在寻找一种可以在不运行java.exe的情况下编译和运行java程序的解决方案。解决方案可以是java或c#(最好是c#)。我找到了一些使用JavaCompiler
类使用java编译的代码,我还找到了使用反射API执行程序的代码,但是在执行后我找不到如何读取输出。
请帮忙!!提前谢谢......
答案 0 :(得分:0)
我同意user2613329,但您仍然可以遵循java.exe方法。您可以对用户执行进行排队,并限制正在运行的执行次数。
答案 1 :(得分:0)
您可以编写自己的Java应用程序,定期加载传入的.java文件,编译它们,然后在不同的线程中运行它们的main
方法。然后,您可以在执行时限制这些线程,例如使用ExecutorService
(请参阅Killing thread after some specified time limit in Java)。