使用JavaCompiler和ClassLoader编译和运行用户代码

tzi*_*zim 6 java classloader java-compiler-api

我正在为java学习编写web应用程序.使用哪些用户可以在我的服务器上编译他们的代码+运行该代码.使用JavaCompiler进行编译很容易:

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, prepareFile(nazwa, content));

    task.call();

    List<String> returnErrors = new ArrayList<String>();
    String tmp = new String();
    for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
        tmp = String.valueOf(diagnostic.getLineNumber());
        tmp += " msg: " + diagnostic.getMessage(null);
        returnErrors.add(tmp.replaceAll("\n", " "));
    }
Run Code Online (Sandbox Code Playgroud)

我设法用代码加载类:

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);

    try {
        URL[] urls = {new URL("file:///root/"), new URL("file://C:\\serv\\Apache Tomcat 6.0.20\\bin\\")};
        ClassLoader cl_old = Thread.currentThread().getContextClassLoader();
        ClassLoader cl_new = new URLClassLoader(urls, cl_old);
        Class compiledClass = cl_new.loadClass(CLASS_NAME);
        Method myMethod = compiledClass.getMethod(METHOD_NAME);
        Object tmp = myMethod.invoke(null);
    } catch (Exception ex) {
        Logger.getLogger(ITaskCompile.class.getName()).log(Level.SEVERE, null, ex);
    }
Run Code Online (Sandbox Code Playgroud)

我如何保护我的应用程序免受无限循环和邪恶的学生;)

  1. 有没有办法运行该代码一生?
  2. 是否存在内存泄漏的风险,我该怎么做才能解决这个问题.
  3. 这是一个很好的解决方案,还是你能提出更好的建议?

谢谢.Tzim

Ste*_*n C 2

我如何保护我的应用程序免受无限循环和邪恶学生的侵害;)

你不能在一个 JVM 中。邪恶的学生特别难对付,因为聪明的学生会想出一些方法来颠覆你的控制机制。

1)有什么办法可以在生命周期内运行该代码吗?

不可以,除非您在单独的 JVM 中运行它。

2)是否存在内存泄漏的风险,我可以采取什么措施来解决这个问题。

是的,确实有,但您对此无能为力(除了单独的 JVM)。事实上,即使您可以杀死陷入循环等的学生程序,这也会是一个问题。应用程序可能会通过多种方式导致 Java 类库泄漏内存/资源...即使在应用程序之后其本身已完成并已被 GC 处理。

3)这是一个好的解决方案吗?或者您能提出更好的建议吗?

在单独的 JVM 中运行每个学生应用程序,您可以使用和朋友从服务器启动该应用程序Process。您将需要编写主机操作系统特定的内容来设置执行时间限制,并终止死锁的学生应用程序。另外,您还会遇到各种各样的问题,以确保您不会因启动过多的 JVM 而意外地破坏主机性能。

更好的答案是为每个学生提供一台台式电脑或虚拟机,让他们做自己的事情。