网上进行google或者baidu时,以及在使用tomcat或者其它框架时,经常碰到以下的问题:
ava.lang.LinkageError: loader constraint violation: when resolving field XXXXXX have different Class objects for that type
这种问题在使用jbmp,或者websphere时经常会出现,一般的解决方法就是说有的包重复了,删除一些jar包就可以了。
问题是解决了,但问题产生的根源在哪,我们需要知道这个问题。在阅读了《深入JVM虚拟机》之后,中间有提到一段话,这段话揭示了问题产生的本质在于在一个方法体中同一个类被多个不同的classLoader所加载了,即在声明时的类与引用的类(同一个类)在加载时,却是由不同的classLoader所加载的:
如果引用的类型和被引用的类型并非由同一个初始装载器装载,虚拟机必须确保在字段或者方法描述符中所提及的类型 在不同的命名空间中保持一致。
这句话理解起来非常的困难,简单一点理解可以由下面的说明来理解:
- 类A中有一个字段a,它的类型为X
- 类B中有一个字段b,它的类型也为X
- 类A由classLoaderA所加载,类B由classLoaderB所加载
- 执行赋值语句A.a = B.b,由于这两个类型均为X,可以执行,但是有一个要求,这个要求就是在A中所装载类X的装载器必须和在B中装载类X的装载器相同,否则赋值语句失败
为什么会产生上面的输出,我们可以来看一个以下的代码