深入理解java 版本兼容问题

我们在做dubbo接口开发是,要考虑jdk版本兼容的问题。如果是高版本的jre运行低版本jdk compile 的jar,根据java的向下兼容性,这个没有问题。但如果是低版本jre运行高版本的jdk compile的jar,会怎么样呢?

问题的背景

最近在做项目时,由于要用到elastichsearch 做开发,elastichsearch 的jdk版本是java7,而公司要求的java版本一般来说是java6,当时想java7 的jre可以运行java6 compile的jar包,应该没有什么问题。后来在发布duboo接口到maven私库上时,发现问题了,如果用java7 compile jar 包到maven私库上,调用方如果使用的是java6,能正常运行吗?在和同事讨论时,大体上有两种观点

* 如果没有使用java7 的 feature,则java1.6的jre可以运行jdk1.7 compile 的jar包
* java1.6不能运行java7 compile 的jar包 

到底哪种说法是正确的呢?

看看官方文档怎么说

我从oracle 找到了一份java8 compatible document

Binary Compatibility

Java SE 8 is binary-compatible with Java SE 7 except for the incompatibilities listed below. Except for the noted incompatibilities, class files built with the Java SE 7 compiler will run correctly in Java SE 8. Class files built with the Java SE 8 compiler will not run on earlier releases of Java SE.

官方文档的意思是:同一份代码,用java8打包的jar,不能在java7上运行,反之可以。

那我们来试一试吧,看java7打包jar, mvn clean install 到本地 ,然后,用另外一个项目来调用,会怎么样?

我们启动一个调用方的项目
StagePayBusinessTO : Unsupported major.minor version 51.0
程序在运行时报错了

所以,我们得出一个结论,高版本编译的java代码,在低版本无法运行.那么,现在另外一个问题来了,如果项目的jdk是java7的,但jsf接口的API必须是java6的,如果哪天不小心,mvn deploy时用java7的编译打包后传到了maven私库上,调用方如果使用的是jre1.6的版本,当下载你的高版本编译的依赖jar包后,直接导致程序无法启动,这个怎么办呢?

重新认识maven-compiler-plugin 插件

笔者之前,一直认为configuration的source,target中的数值是约束jdk版本的,只要本地jdk版本大于等于这个数值就行。比如,这个数值是1.6,那么只要jdk版本大于等于1.6,就可以编译,如果jdk版本是1.7,则是生成的是jdk1.7规范的class文件,如果jdk是1.6,则生成的是jdk1.6规范的class文件。笔者认真看了一下这个插件的文档,发现source和target是javac 在编译时要传的参数。我在官方网站上找到了关于source和target的说明,source不用介绍了,我们重点看一下target的说明。

-target version Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7).

The default for -target depends on the value of -source:

If -source is not specified, the value of -target is 1.7
If -source is 1.2, the value of -target is 1.4
If -source is 1.3, the value of -target is 1.4
If -source is 1.5, the value of -target is 1.7
If -source is 1.6, the value of -target is 1.7
For all other values of -source, the value of -target is the value of -source.

从以上说明中我们可以看出,target配置多少,就用哪个jdk版本的规范文件。比如,你是java7的编译器,如果target是1.6,则生成java1.6规范的class文件。 有了这个插件,我们在jsf 接口发布的时候,只需要在API 子项目的pm.xml中配置好1.6,就可以了,再也不用担心因为是java1.7的编译器而把JSF接口的jar 编译成java1.7规范的class了。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java应用程序在运行过程中遇到JVM闪退问题时,你可以尝试以下一些方法来解决: 1. 检查错误日志:查看JVM生成的错误日志,通常称为堆栈跟踪或崩溃报告。错误日志中可能包含有关引发闪退的异常信息,以及相关的线程信息。通过分析错误日志,你可以获得对问题的更深入理解。 2. 升级JVM:如果你的Java应用程序使用较旧版本的JVM,尝试升级到最新版本。新版本的JVM通常会修复一些已知的问题和漏洞,并提供更好的稳定性和性能。 3. 检查内存使用:JVM闪退可能是由于内存不足或内存泄漏导致的。确保你的应用程序正确地管理和释放内存资源。可以使用Java内存分析工具如VisualVM或MAT来检测内存泄漏并进行调试。 4. 优化代码:一些闪退问题可能与代码逻辑、并发问题或资源管理有关。仔细检查代码,确保没有潜在的问题。使用合适的同步机制和资源释放方式,确保代码的正确性和稳定性。 5. 检查依赖项:某些闪退问题可能与应用程序使用的第三方库或框架有关。确保你的依赖项是最新的,并且与你使用的JVM版本兼容。如果可能,尝试更新或更换依赖项,以解决可能存在的兼容性问题。 6. 调整JVM参数:根据应用程序的需求,适当地调整JVM参数,例如内存大小(-Xmx和-Xms参数)、垃圾回收器类型(-XX:+UseParallelGC或-XX:+UseG1GC等)等。不同的应用程序可能需要不同的JVM参数配置,通过调整这些参数可能有助于解决闪退问题。 7. 与社区寻求帮助:如果上述方法都无法解决问题,你可以向Java开发社区或论坛提问,寻求其他开发者的帮助。他们可能会提供更具体的建议和解决方案。 请注意,JVM闪退问题可能由于多种原因引起,上述方法仅提供了一些常见的解决途径。对于特定的问题,可能需要更详细的调查和分析才能找到准确的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值