JDK 从老版本升级到 1.8的问题总结

Wesley13
• 阅读 954

JDK 从老版本升级到 1.8的问题总结

JDK8 升级常见问题


JDK8 发布很久了,它提供了许多吸引人的新特性,能够提高编程效率。

如果是新的项目,使用 JDK8 当然是最好的选择。但是,对于一些老的项目,升级到 JDK8 则存在一些兼容性问题,是否升级需要酌情考虑。

近期,我在工作中遇到一个任务,将部门所有项目的 JDK 版本升级到 1.8 (老版本大多是 1.6)。在这个过程中,遇到一些问题点,并结合在网上看到的坑,在这里总结一下。

Intellij 中的 JDK 环境设置

Settings

点击 File > Settings > Java Compiler

Project bytecode version 选择 1.8

点击 File > Settings > Build Tools > Maven > Importing

选择 JDK for importer 为 1.8

Projcet Settings

Project SDK 选择 1.8

Application

如果 web 应用的启动方式为 Application ,需要修改 JRE

点击 Run/Debug Configurations > Configuration

选择 JRE 为 1.8

Linux 环境修改

修改环境变量

修改 /etc/profile 中的 JAVA_HOME,设置 为 jdk8 所在路径。

修改后,执行 source /etc/profile 生效。

检查环境变量是否添加成功测试:

echo $JAVA_HOME

JDK 从老版本升级到 1.8的问题总结

编译、发布脚本中如果有 export JAVA_HOME ,需要注意,需要使用 jdk8 的路径。

修改 maven

settings.xml 中 profile 的激活条件如果是 jdk,需要修改一下 jdk 版本

<activation>  <jdk>1.8</jdk> <!-- 修改为 1.8 --></activation>

修改 server

修改 server 中的 javac 版本,以 resin 为例:

修改 resin 配置文件中的 javac 参数。

<javac compiler="internal" args="-source 1.8"/>

sun.* 包缺失问题

JDK8 不再提供 sun.* 包供开发者使用,因为这些接口不是公共接口,不能保证在所有 Java 兼容的平台上工作。

使用了这些 API 的程序如果要升级到 JDK 1.8 需要寻求替代方案。

虽然,也可以自己导入包含 sun.* 接口 jar 包到 classpath 目录,但这不是一个好的做法。

需要详细了解为什么不要使用 sun.* ,可以参考官方文档:Why Developers Should Not Write Programs That Call 'sun' Packages

默认安全策略修改

升级后估计有些小伙伴在使用不安全算法时可能会发生错误,so,支持不安全算法还是有必要的

找到\$JAVA_HOME 下 jre/lib/security/java.security ,将禁用的算法设置为空:jdk.certpath.disabledAlgorithms=

JVM 参数调整

在 jdk8 中,PermSize 相关的参数已经不被使用:

-XX:MaxPermSize=sizeSets the maximum permanent generation space size (in bytes). This option was deprecated in JDK 8, and superseded by the -XX:MaxMetaspaceSize option.-XX:PermSize=sizeSets the space (in bytes) allocated to the permanent generation that triggers a garbage collection if it is exceeded. This option was deprecated un JDK 8, and superseded by the -XX:MetaspaceSize option.

JDK8 中再也没有 PermGen 了。其中的某些部分,如被 intern 的字符串,在 JDK7 中已经移到了普通堆里。其余结构在 JDK8 中会被移到称作“Metaspace”的本机内存区中,该区域在默认情况下会自动生长,也会被垃圾回收。它有两个标记:MetaspaceSize 和 MaxMetaspaceSize。

-XX:MetaspaceSize=size

Sets the size of the allocated class metadata space that will trigger a garbage collection the first time it is exceeded. This threshold for a garbage collection is increased or decreased depending on the amount of metadata used. The default size depends on the platform.

-XX:MaxMetaspaceSize=size

Sets the maximum amount of native memory that can be allocated for class metadata. By default, the size is not limited. The amount of metadata for an application depends on the application itself, other running applications, and the amount of memory available on the system.

以下示例显示如何将类类元数据的上限设置为 256 MB:

XX:MaxMetaspaceSize=256m

字节码问题

ASM 5.0 beta 开始支持 JDK8

字节码错误

Caused by: java.io.IOException: invalid constant type: 15    at javassist.bytecode.ConstPool.readOne(ConstPool.java:1113)
  • 查找组件用到了 mvel,mvel 为了提高效率进行了字节码优化,正好碰上 JDK8 死穴,所以需要升级。

      org.mvel  mvel2  2.2.7.Final

  • javassist

      org.javassist  javassist  3.18.1-GA

注意

有些部署工具不会删除旧版本 jar 包,所以可以尝试手动删除老版本 jar 包。

http://asm.ow2.org/history.html

Java 连接 redis 启动报错 Error redis clients jedis HostAndPort cant resolve localhost address

错误环境:
本地 window 开发环境没有问题。上到 Linux 环境,启动出现问题。
错误信息:
Error redis clients jedis HostAndPort cant resolve localhost address

解决办法:

(1)查看 Linux 系统的主机名

# hostnametemplate

(2)查看/etc/hosts 文件中是否有 127.0.0.1 对应主机名,如果没有则添加

Resin 容器指定 JDK 1.8

如果 resin 容器原来版本低于 JDK1.8,运行 JDK 1.8 编译的 web app 时,可能会提示错误:

java.lang.UnsupportedClassVersionError: PR/Sort : Unsupported major.minor version 52.0

解决方法就是,使用 JDK 1.8 要重新编译一下。然后,我在部署时出现过编译后仍报错的情况,重启一下服务器后,问题解决

./configure --prefix=/usr/local/resin  --with-java=/usr/local/jdk1.8.0_121make & make install

参考资料

  • java8-tutorial

  • Compatibility Guide for JDK 8

  • Compatibility Guide for JDK 8 中文翻译

本文分享自微信公众号 - java宝典(java_bible)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
待兔 待兔
3年前
Java8 几个很好用的方法,真的很香
JDK8应该是Java中最坚挺一个版本,这个版本新增很多特性,让我们开发起来多了很多便利。不过最近Review项目代码的时候发现,虽然很多项目工程已经使用了JDK8,但是工程代码却很少使用到JDK8新特性、新方法。如果单从代码正确性上来说,老方式写法写当然没有什么问题,那唯一的缺点其实就是代码行数比较多,比较繁琐。那同样的需求,使
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
轻量灵动: 革新轻量级服务开发 | 京东云技术团队
从JDK8升级到JDK17可以让你的应用程序受益于新的功能、性能改进和安全增强。下面是一些JDK8升级到JDK17的最佳实战:
JDK 17 营销初体验 —— 亚毫秒停顿 ZGC 落地实践 | 京东云技术团队
自2014年发布以来,JDK8一直都是相当热门的JDK版本。其原因就是对底层数据结构、JVM性能以及开发体验做了重大升级,得到了开发人员的认可。但距离JDK8发布已经过去了9年,那么这9年的时间,JDK做了哪些升级?是否有新的重大特性值得我们尝试?能否解决一些我们现在苦恼的问题?带着这份疑问,我们进行了JDK版本的调研与尝试。
京东云开发者 京东云开发者
5个月前
JDK8升级JDK11最全实践干货来了
1、前言截至目前(2023年),Java8发布至今已有9年,2018年9月25日,Oracle发布了Java11,这是Java8之后的首个LTS版本。那么从JDK8到JDK11,到底带来了哪些特性呢?值得我们升级吗?而且升级过程会遇到哪些问题呢?带着这些问