2

我想重新审视我的一个关于类的内存“编译”的老问题。自从我问(并且得到了一些回答)以来,大约一年过去了 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 对我来说是一个非常糟糕的选择(我不会在这里讨论原因)。此外,最终产品必须是一个类(或该类的一个对象),以便我可以传递它。

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

有任何想法吗?

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

4

5 回答 5

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 实现所做的。

于 2009-11-24T21:26:45.257 回答
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();
    }
}
于 2009-11-24T20:28:28.947 回答
0

我记得很久以前读过有关字节码工程库 (BCEL) 的文章,当时 Java 1.4 风靡一时。请参阅http://jakarta.apache.org/bcel/index.html。我从未使用过它,所以我只提到它,因为它似乎与您所要求的很接近(并且它适用于,或者至少适用于较旧的虚拟机)而且我还没有看到有人提到它。

于 2009-11-24T23:44:37.260 回答
0

是否有特定原因必须是生成类/对象的Java字符串?我的自发反应是 JRuby 正是您正在寻找的东西——它似乎是一个非常稳固的平台,并且 Ruby 具有元编程的强大传统。

于 2009-11-25T08:29:35.687 回答
0

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

于 2011-05-26T13:42:59.907 回答