搭建storm框架遇到的問題

背景

基於公司storm 0.95 搭建topology,在本地集羣模式運行成功後,上傳到公司集羣后出現各類運行時錯誤,以至於花費了大量精力去研究,在測試的過程當中,流程也有了小幅度的提高。java

problem1: 兩個asm

<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
  • 兩個asm之間的關係 兩個asm groupId不一樣,artifactId相同,他們之間會不會僅僅是artifactId相同,只是一種巧合,沒有任何內在的關係呢?當將這兩種asm所有加入到maven的dependency中,發現仍是報一樣的錯誤。 打開 http://mvnrepository.com/search?q=asm 發現二者都爲"ASM CORE",再查看cglib 3.0以上版本的Compile Dependencies 再也不是第一個asm,所有都換成第二個asm,而第二個asm是storm-core的一個dependency,因爲咱們用了集羣的storm-core,因此默認用的asm是4.0的版本,那麼本地若是要和線上asm 4.0匹配的話,只可以升級cglib到3.0,可是運行單元測試的時候,仍是報錯:
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

problem2設置<scrop>provided</scrop> 的jar

在storm集羣中,lib目錄下已經包括了不少基礎jar,這些jar在storm集羣啓動時,優先被加載,若是用戶的dependency與lib中的jar存在版本不一致的問題,就會致使報錯,安全起見,能夠將這些可能存在版本問題的jar在 dependency 中設置scope爲provided。具體能夠進入storm集羣的nimbus節點,而後經過echo $PATH,可以找到storm的安裝路徑,進而進入lib目錄,就能夠查看具體集羣默認加載的jars。ide

  • store-core 因爲storm默認加載lib下的storm-core-0.9.5.jar,若是在編寫topology的時候,沒有設置store-core.jar爲provided,就會致使和系統的store-core中配置文件衝突,好比yaml中配置不同。
  • jcl-over-slf4j 它的版本要嚴格和slf4j-api的版本一致,不然程序沒法運行
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便可。單元測試

相關文章
相關標籤/搜索