java in-memory on-the-fly类编译(和加载)

时间:2009-11-24 20:22:01

标签: java compilation in-memory evaluate

我想重新讨论一个关于类的内存“编译”的旧问题。自从我问过(并且得到一定程度的回答)以来已经过去了大约1/2年,我想重新提出这个问题并看看是否会出现新问题(所以不,我不认为这是重复的)

旧问题可以在这里找到:On-the-fly, in-memory java code compilation for Java 5 and Java 6 - 我建议在回答这个问题之前阅读它(和答案)。

我很满意beanshell正在将一个java类的字符串评估为实际的Class对象。然而,beanshell现在已经在版本2.0b4上站了很久,它的局限性(没有构造函数,甚至没有默认值;没有泛型,没有for-each,没有枚举......)很烦人。

提醒 - 这将用作调试接口,因此性能考虑因素可以忽略不计。但是,我不能让服务器重启,不能将类文件发送到该位置而JSP对我来说是一个非常糟糕的选择(我不会在这里讨论原因)。此外,最终产品必须是Class(或该类的Object),所以我可以传递它。

一些限制:我不能拥有JDK,所以没有javax.tools.JavaCompiler。我没有JSP,因为我没有tomcat或其他“真正的”Web容器。 Java 5语法支持很棒,特别是泛型,枚举和参数化。对默认构造函数的支持非常好。

有什么想法吗?

编辑1:我刚刚发现有一种在beanshell中使用构造函数的循环方式 - 但是你必须声明它们“public void XXX(){...}”而不是通常的方式“public XXX (){...}”。

5 个答案:

答案 0 :(得分:2)

如果由于许可原因无法捆绑SUN JDK tools.jar,也许您可​​以包含Eclipse JDT Core编译器,请参阅

http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm

这是例如Jetty Web服务器的JSP实现做了什么。

答案 1 :(得分:0)

难道你不能只是复制到tools.jar并获取javax.tools.JavaCompiler并将其添加到类路径中吗?或者这是许可问题。

这个代码和类路径上的tools.jar似乎有效:

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


public class Main
{
    public static void main(final String[] argv)
        throws IOException
    {
        final File[]                             files;
        final JavaCompiler                       compiler;
        final StandardJavaFileManager            fileManager;
        final Iterable<? extends JavaFileObject> compilationUnits;

        files = new File[]
        {
            new File(argv[0]),
        };        
        compiler         = ToolProvider.getSystemJavaCompiler();
        fileManager      = compiler.getStandardFileManager(null, null, null);
        compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files));

        compiler.getTask(null, fileManager, null, null, null, compilationUnits).call();
        fileManager.close();
    }
}

答案 2 :(得分:0)

我记得很久以前读过字节码工程库(BCEL),当时Java 1.4风靡一时。见http://jakarta.apache.org/bcel/index.html。我从来没有使用它,所以我只提到它,因为它看起来接近你所询问的(并且它可以工作,或者至少可以使用较旧的VM)并且我没有看到任何人提及它。

答案 3 :(得分:0)

是否有一个特定原因导致它必须是生成类/对象的 Java 字符串?我的自发反应是JRuby是你正在寻找的东西 - 它似乎是一个非常可靠的平台,而Ruby拥有强大的元编程传统。

答案 4 :(得分:0)

我最终使用了Bean Shell。它并不完美,但它解决了99%的问题。