Java.lang.ClassFromatError

 

     工作的时候遇到的一个问题,一个老项目,是java工程,肯定有人问,都什么年代了,还用java工程;这个工程几十年了,很难改项目类型,虽然老,但是里头有很多值得学习的地方,多年前没有框架,一些现在根本不需要实现的底层功能,当初都是一个字一个字的敲出来的,那时候造的轮子虽然说时间上比较落后,但是非常稳定;

       问题来了,修改了十几个文件,在往Linux上部署的时候,采用了class替换的方法,用Xftp6上传的,我用的IDEA2019.1月的版本,算是新的了,java是1.8.0.201版本的(小版本都写出来了….)本地运行程序和前台的GUI(VB)交互是没问题的,然后我放到了服务器上,结果测试那边炸毛了,我改的最底层的,影响了一大片业务,饭都没吃赶紧去看了看日志,结果发现异常如下两类:

1.文件中存在未知的静态常量:

java.lang.ClassFormatError: Unknown constant tag 0 in class file;

2 文件中存在非法的UTF8的字符串

java.lang.ClassFormatError:.Illegal UTF8 string in constant pool in class file

  碰到问题先从自己找原因,我打开代码开始打断点,结果一切顺畅的很,什么问题都没有,我以为是我提交的版本的问题,重新编译后替换文件,结果还是报错;

   这就奇怪了,继续找吧,根据英文提示,在我的类中找静态变量,竟然没有…..然后我检查了文件的编码,也没啥问题,测试也在催,有点着急了,开始百度,百度到的有:

1. 类文件是以 ASCII 模式而不是二进制模式来上传的。
2. 网页服务器是以二进制而非 ASCII 来发送类文件的。
3. 可能有类路径错误阻止了代码找到类文件。
4. 如果类被加载了两次,第二次就会导致这个异常被抛出来。

5. 使用了一个老版本的 Java 运行时。

 

针对上面的问题,我去检查了我的Xftp的上传方式

发现就是二进制的;检查了代码,没有编译错误,检查了启动脚本,没有加载两次,检查了JDK版本,服务器上市1.8.0.141,我是1.8.0.201,终于看到不一样的了,不过根据常识来说,JDK小版本并不会影响代码的运行,但是没办法了,找了一个一样的版本,编译然后上传,竟然还是不行,顿时就疯了…

       后来我想,我要去研究这个error,看看是怎么被抛出来的:

       ClassFromatError:

类描述的意思大概是:

    Java虚拟机试图读取类文件时抛出,并确定该文件已经畸形,或者不能

被解析为一个类文件。1.0就有了

继承自LinkageError,再上一层就是Error了,所以主要看了本类和父类以及两个子类:

LinkageError的类描述是;

    {@code LinkageError}的子类表示一个类具有对另一个类的依赖;然而,后一个类在编译前一个类之后发生了不兼容的更改。

子类是两个细分扩展类:

      

UnsupportedClassVersionError:主要是设计一个类文件中的主版本和子版本不兼容;

GenericSignatureFormatError:主要是反射的时候解析类型,方法或者构造出问题才会有;

 

当时我用javap -verbose 去查看类编译后的文件,并没有发现什么不同,我甚至又找了一台虚拟机,但是还是不好使;最后启迪我的是LinkageError的类描述,因为我的类引用了其他没有改变的类,之前公司统一都是用的Eclipse去编译并上传的,后来随着人慢慢增多,就没有了要求,所以我觉得是因为引用了其他类,运行时解析的时候,解析器发现编译好的文件格式混乱,一部分是IDEA 一部分是Eclipse,所以出问题,于是我把代码移到Eclipse上编译完成上传,就没有问题了;

       我认为是:虽然java有自己的编译器,使用javac命令,但是各个IDE都实现了自己的编译器,做了一些适合编程的优化,使用IDEA和Eclipse编译出来的文件大小会有差别,以后必定谨记,可以使用多种编辑器,但是碰到问题,就知道怎么解决了..

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值