Bootstrap

java.lang unsupported classversion解决方法

现象

经过一个月的当当对接,总算是可以上线了,昨天晚上把项目打包发布到正式环境后,配置后各种参数后,执行考拉抓单任务,发现了一个奇怪的现象,任务一直卡住,此时觉得奇怪,点开任务日志看到下面的情况

 

原来是报 java.lang unsupported classversion 异常。

原因分析&解决方法

 

凭借自己的经验,一眼就看出是jdk版本问题,应该是高版本编译的class文件不能被低版本的jdk进行加载。

原来我本地的jdk是1.8版本,而生产环境的是1.6版本。因此我停掉服务器后,重新将本地的项目用1.6进行编译,再一次打包发布到服务器上,本以为应该就能解决问题。同样执行抓单任务后,查看日志依然报这个异常,当时有点不解。

已经把本地jdk改成1.6重新编译后,为什么还是不行?

后来就是继续分析异常的日志,找出关键点;貌似是调用trendy-system-client.jar 包中的方法时就会出现这个报错,难道是jar包 的版本过高原因? 起初觉得不可能呀,因为jar是通过ivy 从基础库中检出来的

 

将这个jar包复制出来进行反编译,如下图所示,编译版本依然是1.6

 

此时更加疑惑了,jar包版本分明是1.6跟生产环境一致,为何执行这个jar包中的方法时,就会包版本不对的异常?

后来冷静思考,一步一步排查,后来我查看本地的jar包,反编译看到jar包竟然是1.8版本,原来是跟猜想中的是一样的,是我本地jar包版本过高导致。虽然问题原因找到了?

但是依然有一个疑惑,就是为什么Base项目仓库的jar包是1.6版本,而我从项目仓库中检出就编程了1.8版本?

仔细琢磨推敲,我找到了Base仓库中的缓存目录,发现ivy缓存目录中的jar包版本也是1.8。

这样也就解释了 为什么我本地是1.8的原因了,是因为我检出jar包的时候会优先从缓存目录中检出。

但是又引出了另外一个问题,为什么缓存的版本是1.8 而仓库中原始的jar包是1.6,这又是什么原因?

 

测试步骤

  1. 将缓存中的jar包删除
  2. 删除本项目ivy对trendy-system-client的依赖     

    <dependencyorg="trendy"name="trendy-system-client"rev="0.2.0"transitive="false"/>

  3. 加入对trendy-system-client 依赖

     此时jar包会从基础仓库中拷贝一份到缓存目录下,然后取出缓存目录中的jar包引入到我的项目lib下

  4. 查看最新获取的trendy-system-client的编译版本,此时依然是1.8。

     

  为什么?为什么?为什么? 怎么会出现如此神奇之事。

  此时有一个想法? 难道是因为仓库中的jar包放到缓存目录下这个过程中会经过编译?

  按照以往的经验觉得不应该呀,本身jar包已经是经过编译的字节码文件,怎么存在重新编译的情况。

  猜想归猜想,还是模拟进行测试就一清二楚了。

 下面继续测试。

  把base项目的jdk版本改成1.6 ,然后重复上面的测试步骤 ,见证奇迹的时刻发生了,果真是trendy-system-client 编程了1.6版本 ;此时心中无比兴奋,忙活了一个多小时,总算    是找到解决方法了。可能大家用maven管理项目比较多,我公司用的ivy进行jar包管理。

大家如果有兴趣可以看我的另外一篇ivy配置仓库的入门博客。

http://blog.csdn.net/xiongyouqiang/article/details/78228447

 

总结

一个简单的版本报错,竟然引申出了是ivy机制的问题。技术领域真的是很多未知的东西,需要我们去思考,去总结。通过这个错误的解决过程,也让我学到了不少,我非常享受这种推理并动手去做的这个过程,唯有如此,才能进步,什么事情都要多问为什么,直至找到最根本的的源于,这样你才能进步。这个问题大部分人应该发现了确实jar包版本问题,然后把1.6版本的jar包替换到生产环境上就算了事。其实这种形态就是一种偷懒的心态,你知道是问题,但是并没有找到最根本的的原因,这样对于你个人技术的成长是不好的。

学技术的人总要多要想着为什么? 希望大家在技术的路上越走越远。 新的一年,继续加油!

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;