国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【hello,world 也打臉】記storm-starter在某知名IDE下的悲催調試經歷

2019-11-15 00:46:28
字體:
來源:轉載
供稿:網友
【hello,world 也打臉】記storm-starter在某知名IDE下的悲催調試經歷背景

最近收到這樣一個問題:

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所在的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吧,妥妥的不會被打臉!

看下是不是妥妥的呢?

這里寫圖片描述


后記

這里寫圖片描述

.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阜新| 龙里县| 安丘市| 登封市| 邳州市| 德化县| 桐庐县| 崇州市| 天台县| 台中市| 平顶山市| 满洲里市| 宁南县| 元江| 汤原县| 武隆县| 葫芦岛市| 德庆县| 芒康县| 都兰县| 都匀市| 宣汉县| 内江市| 彭州市| 抚顺市| 南充市| 商城县| 桓台县| 武邑县| 大竹县| 吴桥县| 仁化县| 五峰| 阿鲁科尔沁旗| 云和县| 高邮市| 潍坊市| 土默特右旗| 永川市| 江北区| 湘潭市|