插入 Java 编译器 [英] Plugging in to Java compilers

查看:29
本文介绍了插入 Java 编译器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个编译后步骤来操作生成的类的 Java 字节码.我想让图书馆消费者的生活尽可能轻松,所以我正在寻找可以使这个过程自动化并且(如果可能)编译器不可知的方法.

I have a post-compilation step that manipulates the Java bytecode of generated classes. I'd like to make life as painless as possible for library consumers, so I'm looking at ways I can make this process automatic and (if possible) compiler agnostic.

注解处理 API 提供了许多所需的功能(自动服务发现;Eclipse 支持).不幸的是,这是针对代码生成器的,没有'不支持对现有人工制品的操纵:

The Annotation Processing API provides many of the desired features (automatic service discovery; supported by Eclipse). Unfortunately, this is aimed at code generators and doesn't support manipulation of existing artefacts:

该工具的初始输入是被认为是由第零创造的圆形的;因此,试图创造对应的源文件或类文件这些输入之一将导致一个 FilerException.

The initial inputs to the tool are considered to be created by the zeroth round; therefore, attempting to create a source or class file corresponding to one of those inputs will result in a FilerException.

API 推荐的装饰器模式不是一个选项.

The Decorator pattern recommended by the API is not an option.

我可以看到如何使用运行时代理/检测来执行该步骤,但这是一个比手动构建步骤更糟糕的选择,因为它需要任何人甚至被 API 外围接触到以不明显的方式配置他们的 JVM.

I can see how to perform the step with a runtime agent/instrumentation, but this is a worse option than a manual build step as it would require anyone even peripherally touched by the API to configure their JVMs in a non-obvious manner.

有没有办法插入或包装编译器工具javac调用?有没有人成功颠覆注释处理器来操纵字节码,不管文档怎么说?

Is there a way to plug into or wrap the compiler tool as invoked by javac? Has anyone successfully subverted the annotation processors to manipulate bytecode, no matter what the doc says?

推荐答案

Groovy 编译器是唯一允许挂钩到编译过程的字节码编译器(例如:生成字节码以支持单例模式)

The Groovy compiler is the only bytecode compiler which allows to hook into the compilation process (example: Generate bytecode to support the Singleton pattern)

注解处理 API 并非旨在更改代码.正如您已经发现的那样,您所能做的就是安装一个类加载器,在运行时检查字节码并对其进行操作.这是脑残,但它的工作原理.这遵循了我们担心开发人员会尝试一些愚蠢的事情"的一般主题,您会在整个 Java 中找到这一主题.没有办法扩展 javac.相关类要么是私有的,要么是最终的,要么会随着 Java 的下一个版本而改变.

The Annotation Processing API is not meant to change the code. As you have already found out, all you can do is install a classloader, examine the bytecode at runtime and manipulate it. It's braindead but it works. This follows the general "we're afraid that a developer could try something stupid" theme which you will find throughout Java. There is no way to extend javac. The relevant classes are either private, final or will change with the next version of Java.

另一种选择是编写带注释的 Java,例如您编写一个类ExampleTpl.java".然后,您使用预编译器扩展该文件中的注释以获取Example.java".在其余代码中,您使用 Example 并忽略 ExampleTpl.

Another option is to write annotated Java, for example you write a class "ExampleTpl.java". Then, you use a precompiler which expands the annotations in that file to get "Example.java". In the rest of the code, you use Example and ignore ExampleTpl.

对于 Eclipse,有一个错误报告可自动执行此步骤.我不知道这方面的任何其他工作.

For Eclipse, there is a bug report to automate this step. I'm not aware of any other work in this area.

这篇关于插入 Java 编译器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆