JDK 1.6 中的 JavaCompiler:如何将类字节直接写入 byte[] 数组?

发布于 2024-08-18 15:28:15 字数 1257 浏览 8 评论 0原文

所以我最近了解了新的 JavaCompiler API 在 JDK 1.6 中可用。这使得直接从运行代码将 String 编译为 .class 文件变得非常简单:

String className = "Foo";
String sourceCode = "...";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>() 
    {{ 
         add(new JavaSourceFromString(className, sourceCode)); 
    }};

StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();    

ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);

return bos.toByteArray();

您可以从 JavaSourceFromString 获取源代码a href="http://java.sun.com/javase/6/docs/api/javax/tools/JavaCompiler.html" rel="nofollow noreferrer">Javadoc。

这将非常方便地将当前工作目录中的 sourceCode 编译为 Foo.class

我的问题是:是否可以直接编译为 byte[] 数组,并完全避免处理 File I/O 的混乱?

So I recently learned of the new JavaCompiler API available in JDK 1.6. This makes it very simple to compile a String to a .class file directly from running code:

String className = "Foo";
String sourceCode = "...";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>() 
    {{ 
         add(new JavaSourceFromString(className, sourceCode)); 
    }};

StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();    

ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);

return bos.toByteArray();

You can grab the source to JavaSourceFromString from the Javadoc.

This will very handily compile sourceCode to Foo.class in the current working directory.

My question is: is it possible to compile straight to a byte[] array, and avoid the messiness of dealing with File I/O altogether?

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

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

发布评论

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

评论(3

明天过后 2024-08-25 15:28:15

也许您可以创建自己的 javax.tools.JavaFileManager 实现类,在其中返回您自己的 javax.tools.FileObject 实现,然后将其写入内存而不是磁盘。因此,对于 javax.tools.FileObject 的子类 Writer openWriter() throws IOException 方法,您将返回一个 java.io.StringWriter。所有方法都应转换为其对应的 String 方法。

Maybe you could create your own javax.tools.JavaFileManager implementing class where you would return your own implementation of javax.tools.FileObject which would then write it out to memory instead to disk. So for your subclass of javax.tools.FileObject Writer openWriter() throws IOException method you would return a java.io.StringWriter. All the methods should be converted to their String counterparts.

乙白 2024-08-25 15:28:15

没有标准 API 将字节码写入字节数组的原因是编译单个 Java 源文件可能会产生多个字节码文件。例如,任何具有嵌套/内部/匿名类的源文件都将生成多个字节码文件。

如果您推出自己的 JavaFileManager,则需要处理这种情况。

The reason that there is no standard API to write bytecodes to a byte array is that compiling a single Java source file may result in multiple bytecode files. For example, any source file with nested / inner / anonymous classes will result in multiple bytecode files.

If you roll your own JavaFileManager, you will need to deal with this situation.

流年已逝 2024-08-25 15:28:15

JSR 199 API 附带的演示应用程序有一个内存中的字符串编译示例(它确实使用了 MemoryFileManager)。也许看一下此处此处(不过这些示例有点过时,需要稍作更改)。也可以检查如何即时编译? Java.net 上的文章。

PS:我没有查看所有细节,但我认为它不能处理 Stephen C

The demo application that shipped with the JSR 199 API had an in-memory compile-from-string example (which is indeed using a MemoryFileManager). Maybe have a look at it here or here (these samples are a bit outdated though, they will require slight changes). Also maybe check the How to compile on the fly? article on Java.net.

PS: I didn't look at all the details, but I'm don't think it handles the cases mentioned by Stephen C.

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