搭建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便可。单元测试

相关文章
相关标签/搜索