java 内存中动态类编译(和加载)

发布于 2024-08-11 23:32:03 字数 841 浏览 4 评论 0原文

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

老问题可以在这里找到: Java 5 和 Java 6 的即时、内存中 java 代码编译 - 我建议在回答这个问题之前阅读它(以及答案)。

我对 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(){ ...}”。

I want to revisit an old question of mine about in-memory "compilation" of classes. Since about 1/2 a year have passed since I asked (and was somewhat answered), I'd like to re-raise the issue and see if something new would come up (so no, I don't consider this a duplicate).

The old question can be found here: On-the-fly, in-memory java code compilation for Java 5 and Java 6 - I suggest reading it (and the answers) before answering this question.

I'm quite content with beanshell doing the heavy work of evaluating string of a java class to an actual Class object. However, beanshell has been standing on version 2.0b4 for ages now and its limitations (no constructor, not even default; no generics, no for-each, no enums...) are annoying.

Reminder - this is to be used as a debugging interface, so performance considerations are negligible. However, I can't have server restarts, can't send class files to the location and JSPs are a very bad choice for me (I won't go into reasons here). Also, the end product must be a Class (or an Object of that class) so I could pass it around.

Some limitations: I can't have a JDK, so no javax.tools.JavaCompiler. I can't have JSPs since I don't have tomcat or other "real" web container. Java 5 syntax support would be great, especially generics, enums and parameterization. Support for default constructors would be very nice.

Any ideas?

Edit 1: I just found out that there is a round-about way of having constructors in beanshell - however you have to declare them "public void XXX(){...}" instead of the usual way "public XXX(){...}".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

留蓝 2024-08-18 23:32:03

如果由于许可原因无法捆绑 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 实现的作用。

If you can't bundle the SUN JDK tools.jar due to licensing reasons, perhaps you could include the Eclipse JDT Core compiler instead, see

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

This is e.g. what the Jetty web server's JSP implementation does.

蓝颜夕 2024-08-18 23:32:03

难道你不能复制到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();
    }
}

Can't you just copy over to tools.jar and get the javax.tools.JavaCompiler and add it to the classpath? Or is it a licensing issue.

This code, and tools.jar on the classpath, seems to work:

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();
    }
}
泪冰清 2024-08-18 23:32:03

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

I remember reading about the Bytecode Engineering Library (BCEL) a long time ago, back when Java 1.4 was all the rage. See http://jakarta.apache.org/bcel/index.html. I never used it, so I only mention it because it seems close to what you are asking about (and it works, or at least worked, with older VMs) and I didn't see anybody mention it yet.

五里雾 2024-08-18 23:32:03

是否有特定原因为什么它必须是生成类/对象的 Java 字符串?我的本能反应是 JRuby 就是您正在寻找的 - 它似乎是一个非常可靠的平台,并且 Ruby 具有强大的元编程传统。

Is there a specific reason why it has to be a Java string that produces the class/object? My spontaneous reaction is that JRuby is what you're looking for - it seems to be a very solid platform, and Ruby has a strong tradition of meta-programming.

深陷 2024-08-18 23:32:03

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

I ended up using Bean Shell. It's not perfect, but it solved 99% of the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文