Java 6向前兼容注解处理器和SupportedSourceVersion

27

我正在为一个项目尝试使用Java 7,并从注解处理器(Bindgen和Hibernate JPA modelgen)收到以下警告:

warning: Supported source version 'RELEASE_6' from annotation processor 'org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor' less than -source '1.7'

这是由注解处理器类上的@SupportedSourceVersion(SourceVersion.RELEASE_6)注解引起的。因为它们是使用Java 6编译的,所以它们可以使用的最高版本的SourceVersion值是RELEASE_6。Java 7版本的SourceVersion引入了RELEASE_7

我的问题是:注解处理器应该如何处理向前兼容?它们是否必须有单独的jdk6和jdk7二进制版本?我是否没有理解其他内容?

我只找到了有关此问题的以下信息:

Querdydsl bug report,其中使用了

@Override
public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latest();
}

Oracle博客中的评论者建议支持最新的源代码版本。

1个回答

19

前向兼容性通过适当处理未知的语言结构来实现,例如实现ElementVisitor.visitUnknown

在提到的Oracle博客中还有另一个条目,建议采取两种前向兼容性策略:

  • 编写处理器仅适用于当前语言版本。
  • 编写处理器以应对未来未知结构。

第二种策略是通过返回SourceVersion.latest()来实现,这已经在问题中发布过了。

我认为在大多数情况下,这样做是可以的,但必须确定额外的语言元素不会破坏任何东西。当然,在较新版本中也不能仅仅假设一切都会顺利,你也应该进行测试。


好吧,我想“适当处理未知的语言结构”听起来有点模糊,因此这里有一些例子。

假设您有一个处理器,检查已知语言结构上的自定义类型注释(例如类上的注释),并创建所找到内容的简单文档,那么您可以放心地假设它也适用于新版。我认为限制它只能适用于特定版本是不明智的决定。

假设您有一个处理器,检查它能够找到的每个元素,并分析代码结构以生成图表。您可能会遇到较新版本的问题。您可能能够以某种方式处理未知的语言结构(例如通过添加“未知”节点到图表中),但只有在有意义且值得麻烦时才这样做。如果处理器在面对未知的东西时根本没有用处,那么它应该坚持使用特定的Java版本。

无论使用何种策略,我认为最好的方法是监测语言的最新变化并相应地更新处理器。例如,在Java 7中,Coin项目引入了一些新的语言特性,这些特性可能对处理器甚至都不可见。而Java 8则有一些新的结构会影响处理,例如类型注解。不过,新的语言特性并不经常出现,所以很可能您很长时间内都不需要做任何更改。


1
感谢您的初步发布和更新。我还没有接受您的答案,因为我仍在(非常兼职地)将注释处理器转换为Java 7的过程中。我想看看是否会出现其他问题。 - bernie
在我看来,SourceVersion.latest()SourceVersion.latestSupported() 之间存在差异。第一个使用来自注解处理器编译 JDK 的硬编码常量。它不能被内联化,从而失去了动态方面。而 SourceVersion.latestSupported() 使用目标代码编译时所用的 JDK 版本,由 AP 处理。 - Ondřej Fischer
@OndřejFischer 很好的问题。我认为这不可能发生,因为它是一个返回枚举常量的方法调用。据我所知,方法内联只在JIT运行时进行,而从未在编译时进行。我甚至不确定枚举是否被内联了。 - kapex
好的观点。那么我不确定,哪种更好用。无论如何,这个答案非常有价值,指出了这些方法。谢谢。 - Ondřej Fischer
@SupportedSourceVersion(SourceVersion.latest())失败,因为.latest()不是一个"枚举常量表达式" - 指定向前兼容的唯一方法是使用getSupportedSourceVersion方法本身吗? - theonlygusti
@theonlygusti 如果在编译时已知值,才能使用注解。如果想要使用 latest(),我认为除了重写 getSupportedSourceVersion 没有其他办法。 - kapex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接