背景:
我们有一个基于maven
的Java项目,目标是JRE 1.7,但源代码使用了lambda表达式,因此我们使用retrolambda
将Java 8
的源代码转换为Java 7
。在需要使用streams、function.*、Optional等时,我们还使用StreamSupport backport库。
使用retrolambda
需要将项目的源代码和目标语言级别均配置为1.8。
如果没有依赖于java8类或方法(例如java.util.stream.*
、java.util.Optional
或在java8
中引入的Collection.forEach
之类的方法),则一切正常。如果存在这样的用法,则构建通过,但在运行时,在Java 8的JVM下运行时会失败。
问题:
我的目标是在存在这种依赖关系的情况下使构建失败。是否有一种方法可以在构建时检测对新的Java 8
类/方法的依赖关系?
我考虑了两个可能的选项,但我不确定是否可行:
- 某种字节码分析器,用于检测预定义类和方法的依赖关系。是否有这样的工具/maven插件?
- Lint (
lint4j
)规则。不确定是否可以使用lint
检测到对类/方法的依赖关系
rt.jar
即可。为了让编译器能够使用Lambda表达式,您可能需要将一个虚拟的JAR文件添加到路径中,其中包含一个LambdaMetaFactory
类及其两个方法的声明,以防编译器进行验证。这些方法不必起作用,因为您最终会使用retrolambda处理已编译的代码(然后使用实际的JRE8)。 - HolgerLambdaConversionException
、LambdaMetafactory
和SerializedLambda
的桩代码(在我的情况下,使用额外的虚拟包并没有奏效。我收到了“致命错误:无法在类路径或引导类路径中找到java.lang包”的消息)。然后通过“<bootclasspath>`”标签将maven-compiler-plugin指向增强版的“rt.jar”。作为测试,我编译了streamsupport源文件(sans j8.u.DelegatingSpliterator,它使用Java 8 API,因此不能用Java 7的“rt.jar”进行编译)。 - Stefan Zobel