【hello,world 也打脸】记storm-starter在某知名IDE下的悲催调试经历

原创 2015年07月07日 02:37:22

背景

最近收到这样一个问题:

Storm处理消息时会根据Topology生成一棵消息树,Storm如何跟踪每个消息、如何保证消息不丢失以及如何实现重发消息机制?

虽已回复,但心想还是看下storm这块的源码吧.那看静态多不爽啊,那总得调试吧,好吧,造个本地环境来调吧。

先看看maven的build过不过:

mvn -f pom.xml clean install

搞定storm的编译打包,接着是storm-starter的编译打包,一切很顺利啊,跑一下看看:

${STORM_HOME}/bin/storm jar ${STORM_JAR} ${STORM_STARTER_JAR} storm.starter.WordCountTopology

顺利出结果了,不就是个hello world嘛!

接着造本地环境吧,将storm-starter的源码按maven方式导入Intellij IDEA,注意,从这时候悲催就开始了。


hello,world 打脸了

导入IDE后,兴致勃勃的点了F5,然后:

这里写图片描述

这尼玛,说好不打脸的!

看了又看依赖“都合适”啊,ClassPath“都合适”啊,否则编译不通过啊,为毛跑!不!起!来!

这同样的操作,在eclipse里妥妥的啊,各种能跑啊,为毛在Intellij IDEA里出错了呢?


异常是如何产生的

好吧,既然打脸了,又是知名IDE的粉丝,坚决要知耻而后勇的。
那么,看下异常如何产生的吧。

这里写图片描述

上面的图,基本概括了异常NoClassDefFound产生的路径。

更细节的异常产生情况如下:

这里写图片描述

注意看调用栈:

  • JVM_GetClassDelaredMethods是JVM内方法,在找入口函数main的过程中,此方法被调用。
  • 接着,此方法会调用验证字节码的过程:verify_code
  • 发现有用到backtype.storm.topology.IRichBolt接口,那么找找这个接口所在的.class文件吧:
    如果我们运行java -cp . xxx,通过-cp或者-classpath参数指定了classpath,那么这个.class就会被找到。然后进入parse的过程。

  • 悲催的是,IDEA的运行或者调试命令f5->run,没有将backtype.storm.topology.IRichBolt.class所在的jar包storm-core.jar加入classpath,这都是后话了…

那么,既然有个找*.class的过程,这个过程如下:

这里写图片描述

对上图做一点简要说明:

  1. 执行java -cp . $mainClass .
  2. java程序(这里指java这个程序本身)的入口函数main,会创建虚拟机JVM实例,过程中会初始化JVM本地ClassLoader.
  3. JVM寻找.class文件时,调用ClassLoader::load_classfile方法,从jar包、zip包、目录中寻找指定的.class文件 .
  4. 本文中,木有找到backtype.storm.topology.IRichBolt.class,所以会置一个延时异常__pending_exception,这个异常关联了这个类(接口)、文件名、异常的类型(NoClassDefFound),那这个异常什么时候处理呢?后文再说.


    看下这个异常的内容:
    这里写图片描述

异常是如何处理的

好了,异常的产生清楚了,还有个问题,那个__pending_exception是何时被处理呢?
看下图:

这里写图片描述

对上图做下简要说明:

  1. 执行java -cp . $mainClass .
  2. java程序的入口函数main,在层层初始化的过程中,会调用到LoadMainClass函数, 结合本文的第一幅图就可以知道,这个函数最终会制造那个NoClassDefFound的异常__pending_exception,然后返回的是一个空的mainClass.
  3. 紧跟着LoadMainClass函数,是一个CHECK_EXCEPTION_NULL_LEAVE的宏,这个宏展开后,会处理上面制造的那个异常,然后,打印异常信息。这里就是那个被打脸的异常了。

为什么被打了脸

这里,异常产生的本质和异常处理,清楚了。
简单的概括下就是:

   /* 伪代码 */
   main /* java这个程序的main */
   -> createJVM() /* 创建JVM */
   -> loadMainClass() /* 加载我们指定的$mainClass文件,这是个class文件 */
   -> findMethod("main") /* 在$mainClass中找main方法,java写的程序的main */
   -> getMethodFromJVM() /* 没缓存,问JVM要 */
   -> classLoader.loadFromFile() /* 在classpath中找.class文件 */
   -> 没找到,置异常NoClassDefFound.

但是,Intellij IDEA为何在运行时不将storm-core.jar包含进classpath呢?

换句话说:为啥被打脸??

这里写图片描述

打脸的理由很简单:
1. F5->run,先make/compile/build,再运行.
2. 依赖的scope设为了provided,此设置仅在编译阶段将依赖的jar包加入classpath,在运行阶段,不会将jar包加入classpath.

解决的方法也非常简单:

如果不是通过mvn来运行,而是在IDE下调试/运行,赶紧将依赖的jar包的scope选为compile吧,妥妥的不会被打脸!

看下是不是妥妥的呢?

这里写图片描述


后记

这里写图片描述

终.

02-Storm之Hello World:单词统计

1、说明设计一个topology,来实现对一个句子里面的单词出现的频率进行统计。整个topology分为三个部分: RandomSentenceSpout:数据源,在已知的英文句子中,随机发送一条句...
  • xjtuse2014
  • xjtuse2014
  • 2016年10月14日 14:59
  • 1799

Storm实时流处理Hello World

近来在看Storm的相关资料,以下总结一下配置过程和Hello World例子。 Storm是分布式的实时计算系统。详细文档可参考Storm网站,也可以参阅《Getting started with ...
  • hanhuili
  • hanhuili
  • 2014年03月09日 15:42
  • 5325

Storm实战之HelloWorld

官网建议首先是Wordcount,个人觉得,如果参考
  • myemail_sl
  • myemail_sl
  • 2014年09月12日 10:20
  • 787

storm-hello-world可执行版本

  • 2014年09月24日 17:15
  • 15.69MB
  • 下载

php学习笔记二:第一个php程序 hello world!

第一个php程序 hello world! 前提条件:已经安装 xampp 和 phpstorm  xampp 安装到了 D:\xampp 1 打开 phpstorm 2 ...
  • xxj_jing
  • xxj_jing
  • 2015年11月05日 16:03
  • 4970

Java经典编程300例之实例001 输出"Hello World!"

源代码: public class Test {         public static void main(String[] args) {                 System.ou...
  • HanTangSongMing
  • HanTangSongMing
  • 2014年06月06日 17:28
  • 4162

java学习之用记事本写简单的HelloWorld程序

//public :表示这个类是公共的,一个java文件中只能有一个public类 //class:表示这是一个类 //HelloWorld:类名(公共类的类名必须和文件名一致) public cla...
  • geekday
  • geekday
  • 2014年07月09日 21:28
  • 1850

Java环境配置及Hello World!程序运行与调试。

Java开发环境配置 Hello World!程序运行与调试
  • cai2016
  • cai2016
  • 2016年06月12日 22:56
  • 1808

storm之hello world

前言:现在写博客主要是总结与以后从忘记中快速回温,人老了,脑子越来越不好使了,很多东西刚看的就忘了 集群搭建方法 参考:搭建storm集群(apache-storm-0.9.5.tar.gz) 注意:...
  • you1314520me
  • you1314520me
  • 2016年06月10日 14:17
  • 414

Storm实时流处理Hello World

近来在看Storm的相关资料,以下总结一下配置过程和Hello World例子。 Storm是分布式的实时计算系统。详细文档可参考Storm网站,也可以参阅《Getting started with ...
  • hanhuili
  • hanhuili
  • 2014年03月09日 15:42
  • 5325
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【hello,world 也打脸】记storm-starter在某知名IDE下的悲催调试经历
举报原因:
原因补充:

(最多只允许输入30个字)