基於公司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便可。單元測試