基于公司storm 0.95 搭建topology,在本地集群模式运行成功后,上传到公司集群后出现各类运行时错误,以至于花费了大量精力去研究,在测试的过程当中,流程也有了小幅度的提高。java
<dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>4.0</version> </dependency>
在使用cglib实现动态代理时,须要引入asm,那么引入哪一种asm以及与哪一个版本的asm进行匹配呢?web
当版本不匹配时,报错以下:spring
invocation of init method failed; nested exception is java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:230) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:117) at
Caused by: java.lang.NoClassDefFoundError: org/objectweb/asm/util/TraceClassVisitor at net.sf.cglib.core.DebuggingClassWriter.toByteArray(DebuggingClassWriter.java:73) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144)
仔细排查后发现,这个类在第一个groupId为asm的util中apache
<dependency> <groupId>asm</groupId> <artifactId>asm-util</artifactId> <version>2.2</version> </dependency>
此时换成第二个groupId为org.ow2.asm的dependency了,有没有适配第二个asm的utils呢?经查看后发现:api
<dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm-util</artifactId> <version>4.0</version> </dependency>
其实若是细心的话,在 http://mvnrepository.com/artifact/asm/asm-util 查看第一个asm-util的时候,网站上就有提醒: 安全
至此,cglib和asm版本问题顺利解决。maven
在storm集群中,lib目录下已经包括了不少基础jar,这些jar在storm集群启动时,优先被加载,若是用户的dependency与lib中的jar存在版本不一致的问题,就会致使报错,安全起见,能够将这些可能存在版本问题的jar在 dependency 中设置scope为provided。具体能够进入storm集群的nimbus节点,而后经过echo $PATH,可以找到storm的安装路径,进而进入lib目录,就能够查看具体集群默认加载的jars。ide
exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;Ljava/lang/Throwable;)V at org.apache.commons.logging.impl.SLF4JLocationAwareLog.info(SLF4JLocationAwareLog.java:159) at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:411)
鉴于集群中已经包含了:slf4j-api-1.7.5.jar,此时须要将slf4j-api设置为provided,此时要么将jcl-over-slf4j设置为1.7.5,或者干脆exclude掉这个jar,可以fix这个问题,为了解决这些同名不一样版本jar问题,一个解决思路是:将可能冲突的jar先所有exclude掉,而后从新引入一份统一的jar,使编译成功,发布到storm集群前,将这些jar设置为provided,使用集群自带jar便可。单元测试