实现了一个功能FeatureA,该功能是注入到webappB中执行的。
FeatureA实现的时候使用了elasticsearch client,该版本的client所依赖的log类库版本跟webappB使用的log类库冲突。于是自定义ClassLoader加载FeatureA的class进行隔离。
之前好好的,直到前不久webappB新版本引入了esclient jar,版本跟FeatureA所使用的不一样。
然后FeatureA加载的时候就出错了,错误关键堆栈信息如下:
Caused by: java.lang.IllegalStateException: Method [isLoopbackAddress] was discovered in the .class file but cannot be resolved in the class object
at org.springframework.core.LocalVariableTableParameterNameDiscoverer$LocalVariableTableVisitor.resolveMember(LocalVariableTableParameterNameDiscoverer.java:251)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer$LocalVariableTableVisitor.visitEnd(LocalVariableTableParameterNameDiscoverer.java:234)
at org.springframework.asm.ClassReader.readMethod(ClassReader.java:1172)
at org.springframework.asm.ClassReader.accept(ClassReader.java:729)
at org.springframework.asm.ClassReader.accept(ClassReader.java:527)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass(LocalVariableTableParameterNameDiscoverer.java:116)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:89)
at org.springframework.core.PrioritizedParameterNameDiscoverer.getParameterNames(PrioritizedParameterNameDiscoverer.java:67)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1274)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1131)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
... 53 more
这一看就是类冲突了,不过明明使用ClassLoader隔离了啊,应该是自定义ClassLoader实现有问题吧导致类加载优先级不符合预期吧。
沿着这个思路想当然的去看loadclass相关的方法调用,排查……一无所获。
再次仔细看错误堆栈
asm?
这个显然是读取class字节码的。
spring装配的时候读取字节码干啥了?
应该是为了做代理实现aop,spring是通过修改字节码实现aop的。
等等……那spring是怎么获取到字节码的了,应该是通过ClassLoader.getResource咯……我当时偷懒没重写getResource方法。
默认实现是parent优先,那就会获取到webappB里的esclient class字节码。
重写getResource,果然问题解决。
来源:oschina
链接:https://my.oschina.net/u/916948/blog/2995304