对于大多数模块/项目,我们使用的是java 8,但对于某些模块,我们使用的是java 6(客户需求)。
开发人员安装了java 8,我们使用以下标志编译java 6项目:
compileJava {
sourceCompatibility = 1.6
targetCompatibility = 1.6
}
在我们把番石榴从v20
升级到最新的- 28.1-jre
之前,我们都认为我们都很好。
令我们惊讶的是,构建是成功的,但在运行时失败了。
我们为使用JDK 6中的特定javac
构建java 6提供了一个解决方案。参见更多信息这里。这一解决方法在编译时使用错误class file has wrong version 52.0, should be 50.0
。缺点是开发人员需要JDK 6的download+config+usage。
是否有一种方法在编译时验证依赖项的java版本,当使用更高的java版本时?(没有安装更低版本的java)谢谢。
发布于 2019-09-08 16:43:19
将-source
和-target
值设置为1.6不足以确保结果输出与1.6兼容。程序本身不能对以后的版本有任何库API依赖,而-source
和-target
选项不能这样做。(GhostCat也是这么说的。)
例如,在Java8中,ConcurrentHashMap
为返回新类型ConcurrentHashMap.KeySetView
的keySet
方法添加了一个协变覆盖。这种类型在早期版本的Java中不存在。但是,在类二进制中,返回类型是在调用站点上编码的。因此,即使源代码是用-source 1.6 -target 1.6
编译的,生成的类文件也包含对Java8类库API的依赖。
唯一的解决方案是确保编译时只有Java1.6兼容的库在类路径中。这可以使用-Xbootclasspath
选项来指向JDK1.6类库,或者一开始使用JDK1.6安装可能更简单。
这适用于除了JDK之外的外部库,正如您在Guava中发现的那样。动物嗅探器项目为Ant和Maven提供了插件,用于检查库依赖项是否存在版本问题。我不知道格拉德尔是否有类似的东西。也许有办法让动物嗅探器和Gradle一起工作,但我没有这样做的经验。
发布于 2019-09-08 12:15:58
在使用更高的java版本时,是否有方法在编译时验证依赖项的java版本?(不安装较低版本的java)。
指定依赖项。当您告诉您所构建的系统显式使用Y版中的某个库X时,您就做了一个非常清楚的声明。
你看,这不仅仅是关于类文件版本号。如果有人不注意,用Java8编译一些东西.对于Java6目标,但是忘记了代码库使用的是仅Java8 8的API调用?!
换句话说:你找错地方了。
对构建描述进行更新并将库版本从Y更改为Y+8的人需要仔细评估该更改。例如,通过阅读新闻稿。
我同意,一个非常聪明的构建系统可以检查您正在使用的库是否带有匹配的类文件版本。但正如所说,这只是问题的一个方面。因此,与其研究技术解决方案,我认为真正的答案是:不要因为可以而换版本号,而是因为您必须这样做。以及手动更改版本号的步骤,这是需要尽职调查的(就人类而言)。
因此:我认为这里最明智的方法是在自己特定的构建设置中编译Java6可交付的内容。只有在仔细检查这些细节之后你才能接触到。当然:说服你的客户继续前进,放弃一个长期死气沉沉的Java版本。
https://stackoverflow.com/questions/57841823
复制相似问题