教你編譯調試Elasticsearch 6.3.2源碼

前言

想深入理解 Elasticsearch,閱讀它的源碼是很有必要的,一來可以了解它內部的具體實現,有助于調優,二來可以了解優秀開源項目的代碼架構,提高我們的代碼架構能力等

閱讀Elasticsearch源碼的第一步是搭建調試環境,然后作者在這個過程中遇到很多麻煩,在網上找不到想要的答案,歷經千辛最后一一解決,所以記錄下,幫助有需要的童鞋

軟件環境

  • 操作系統:win7
  • Elasticsearch 源碼版本: 6.3.2
  • JDK版本: 10.0.2
  • Gradle版本: 4.7
  • Intellij Idea版本: 2018.2

環境準備及工程導入

1.安裝JDK

Elasticsearch 6.3.2需要JDK1.9編譯,否則后面步驟會報錯。

Java SE Downloads 地址:
http://www.oracle.com/technetwork/java/javase/downloads/index.html

作者裝的是 JDK 10.0.2

2.下載Elasticsearch源碼,并且切換到6.3.2分支

Elasticsearch github源碼托管地址:
https://github.com/elastic/elasticsearch.git

git checkout v6.3.2

也可直接下載源碼包,地址在 https://github.com/elastic/elasticsearch/releases

3.下載gradle的安裝包

查看 elasticsearch\gradle\wrapper\gradle-wrapper.properties 發現如下配置:

distributionUrl=https://services.gradle.org/distributions/gradle-4.5-all.zip

Elasticsearch 6.3.2需要安裝gradle-4.5,官方下載地址:
https://services.gradle.org/distributions/gradle-4.5-all.zip

注意:由于國內網速問題,為了加快速度,進行第4步操作

4.拷貝文件

將下載的gradle-4.5-all.zip包放到 elasticsearch\gradle\wrapper 目錄下,
確保和 elasticsearch\gradle\wrapper\gradle-wrapper.properties 在同級目錄,
然后修改 elasticsearch\gradle\wrapper\gradle-wrapper.properties 配置如下:

distributionUrl=gradle-4.5-all.zip

5.修改源碼Maven倉庫地址

國內下載國外倉庫的jar包速度慢,需要替換Maven地址,設置為本地或者國內可用的Maven倉庫。

需要修改下列文件的 maven URL 配置:

  • elasticsearch\benchmarks\build.gradle
  • elasticsearch\client\benchmark\build.gradle

修改源碼中上面build.gradle文件里面的repositories-maven-url的值,
配置為可用的倉庫地址,譬如修改為阿里云maven地址 http://maven.aliyun.com/nexus/content/groups/public/,修改示例如下:

buildscript {
    repositories {
        maven {
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
    }
    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.2'
    }
}

6.修改全局Maven倉庫地址

USER_HOME/.gradle/下面創建新文件 init.gradle,輸入下面的內容并保存。

allprojects{
    repositories {
        def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'
        all {
            ArtifactRepository repo ->
    if (repo instanceof MavenArtifactRepository) {
                def url = repo.url.toString()
                if (url.startsWith('https://repo.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
                    remove repo
                }
            }
        }
        maven {
            url REPOSITORY_URL
        }
    }
}

其中USER_HOME/.gradle/是自己的gradle安裝目錄,示例值:C:\Users\Administrator\.gradle
如果沒有.gradle目錄,可用自己創建,或者先執行第7步,等gradle安裝后再回來修改。
上面腳本把url匹配到的倉庫都替換成了阿里云的倉庫,
如果有未匹配到的導致編譯失敗,可用自己仿照著添加匹配條件。

7.gradle編譯源碼

windows運行cmd,進入DOS命令行,然后切換到elasticsearch源碼的根目錄,執行如下命令,把elasticsearch編譯為 idea 工程:

gradlew idea

編譯失敗則按照錯誤信息解決問題,可用使用如下命令幫助定位問題:

gradlew idea -info
gradlew idea -debug

一般是Maven倉庫地址不可用導致jar包無法下載,從而編譯失敗,此時請參考步驟5和6修改相關的倉庫地址。

編譯成功后打印日志:

BUILD SUCCESSFUL in 1m 23s

8. idea 導入elasticsearch工程

idea 中 File -> New Project From Existing Sources 選擇你下載的 Elasticsearch 根目錄,然后點 open ,之后 Import project from external model -> Gradle , 選中 Use auto-import, 然后就可以了

導入進去后,gradle 又會編譯一遍,需要等一會,好了之后如下:

IDEA導入Elasticsearch6.3.2之后

運行,開始 solve error 模式

前面的步驟都挺順利,接下來遇到的 ERROR & EXCEPTION 讓作者耗費了好幾天,心力交瘁,好在最終運行成功

elasticsearch/server/src/main/org/elasticsearch/bootstrap 下找到Elasticsearch的啟動類 Elasticsearch.java,打開文件,右鍵 Run Elasticsearch.main(),運行main方法

1、 報錯如下:

ERROR: the system property [es.path.conf] must be set

這是需要配置 es.path.conf 參數,我們先在 elasticsearch 源碼目錄下新建一個 home 目錄,然后在 https://www.elastic.co/downloads/elasticsearch 下載一個同版本號的 Elasticsearch6.3.2 發行版,解壓,將 config 目錄拷貝到 home 目錄中

然后打開 Edit Configurations,在 VM options 加入如下配置:

Edit Configurations
-Des.path.conf=D:\elasticsearch-6.3.2\home\config

再次運行 Run Elasticsearch.main()

2、報錯如下:

Exception in thread "main" java.lang.IllegalStateException: path.home is not configured
    at org.elasticsearch.env.Environment.<init>(Environment.java:103)
...

需要配置 path.home 這個參數,在 VM options 中添加如下配置:

-Des.path.home=D:\elasticsearch-6.3.2

再次RUN

3、報錯如下:

2018-08-22 15:07:17,094 main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")
...

Caused by: java.nio.file.NoSuchFileException: D:\elasticsearch-6.3.2\modules\aggs-matrix-stats\plugin-descriptor.properties
...

VM options 中把 path.home 的值修改為如下:

-Des.path.home=D:\elasticsearch-6.3.2\home

然后把 ES6.3.2 發行版中的 modules 文件夾復制到 home 目錄下,然后再次RUN

4、報錯如下:

2018-08-22 15:12:29,876 main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")
...

VM options 中加入

-Dlog4j2.disable.jmx=true

1、2、3、4 的配置最終如下:

image

再次RUN

5、報錯如下:

[2018-08-23T00:53:17,003][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [] fatal error in thread [main], exiting
java.lang.NoClassDefFoundError: org/elasticsearch/plugins/ExtendedPluginsClassLoader
    at org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:632) ~[main/:?]
    at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:557) ~[main/:?]
    at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:162) ~[main/:?]
    at org.elasticsearch.node.Node.<init>(Node.java:311) ~[main/:?]
    at org.elasticsearch.node.Node.<init>(Node.java:252) ~[main/:?]
    at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:213) ~[main/:?]
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:213) ~[main/:?]
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:326) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:136) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:127) ~[main/:?]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[main/:?]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[main/:?]
    at org.elasticsearch.cli.Command.main(Command.java:90) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) ~[main/:?]
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.plugins.ExtendedPluginsClassLoader
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) ~[?:?]
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[?:?]
    ... 15 more

這個問題其實不算真正的問題,但是說起來挺好笑,為了解決這個問題耗費了作者好幾天,當最后發現問題所在的時候,哭笑不得 ~_~ 正是所謂的 踏破鐵鞋無覓處,得來全不費工夫

解決方法: 打開 IDEA Edit Configurations ,給 Include dependencies with Provided scope 打上勾即可解決,很簡單吧!!

image

繼續RUN,又來一個 Exception

6、報錯如下:

[2018-08-23T01:13:38,551][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:140) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:127) ~[main/:?]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[main/:?]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[main/:?]
    at org.elasticsearch.cli.Command.main(Command.java:90) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[main/:?]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) ~[main/:?]
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "createClassLoader")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[?:?]
    at java.security.AccessController.checkPermission(AccessController.java:895) ~[?:?]
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:335) ~[?:?]
    at java.lang.SecurityManager.checkCreateClassLoader(SecurityManager.java:397) ~[?:?]
...

Exception: java.security.AccessControlException thrown from the UncaughtExceptionHandler in thread "Thread-2"

這個問題也找了挺久,最終才發現解決方法(兩種):

第一種:home/config 目錄下新建 java.policy 文件,填入下面內容

grant {
    permission java.lang.RuntimePermission "createClassLoader";
};

然后在 VM options 加入 java.security.policy 的設置,指向該文件即可

-Djava.security.policy=D:\elasticsearch-6.3.2\home\config\java.policy

第二種: 就是在 %JAVA_HOME%/conf/security 目錄下(JDK10是這個路徑,之前的版本不確定),我的目錄是 C:\Program Files\Java\jdk-10.0.2\conf\security,打開 java.policy 文件,在 grant 中加入下面這句,賦予權限

permission java.lang.RuntimePermission "createClassLoader";

效果如下:

java.policy

createClassLoader

再RUN,這次可終于運行起來了!!!

來看一下效果,瀏覽器訪問 http://localhost:9200/

image1

瀏覽器訪問 http://localhost:9200/_cat/health?v

image

一切正常,終于可以愉快的 DEBUG 源碼啦!!!

另一種源碼調試方式:遠程調試

如果上面第五個報錯之后解決不了無法繼續進行,可以選擇這種方式:

在 Elasticsearch 源碼目錄下打開 CMD,輸入下面的命令啟動一個 debug 實例

gradlew run --debug-jvm

如果啟動失敗可能需要先執行 gradlew cleangradlew run --debug-jvm 或者 先退出 IDEA

image

在 IDEA 中打開 Edit Configurations,添加 remote

image

配置 host 和 port

image

點擊 debug,瀏覽器訪問 http://localhost:9200/,即可看到ES返回的信息

隨機調試一下, 打開 elasticsearch/server/src/main/org/elasticsearch/rest/action/cat 下的 RestHealthAction 類,在第 54 行出設置一個斷點,然后瀏覽器訪問 http://localhost:9200/_cat/health,可以看到斷點已經捕獲到該請求了

image

運行成功,可以開始設置斷點進行其他調試

其他可能遇到的問題

1. 錯誤信息如下

JAVA8_HOME required to run tasks gradle

配置環境變量 JAVA8_HOME,值為 JDK8 的安裝目錄

2. 錯誤信息如下

[2018-08-22T13:07:23,197][INFO ][o.e.t.TransportService   ] [EFQliuV] publish_address {10.100.99.118:9300}, bound_addresses {[::]:9300}
[2018-08-22T13:07:23,211][INFO ][o.e.b.BootstrapChecks    ] [EFQliuV] bound or publishing to a non-loopback address, enforcing bootstrap checks
ERROR: [1] bootstrap checks failed
[1]: initial heap size [268435456] not equal to maximum heap size [4273995776]; this can cause resize pauses and prevents mlockall from locking the entire heap
[2018-08-22T13:07:23,219][INFO ][o.e.n.Node               ] [EFQliuV] stopping ...
2018-08-22 13:07:23,269 Thread-2 ERROR No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
Disconnected from the target VM, address: '127.0.0.1:5272', transport: 'socket'

Edit ConfigurationsVM options 加入下面配置

-Xms2g 
-Xmx2g 

參考文檔:

  1. Eclipse導入Elasticsearch源碼
  2. Elasticsearch源碼分析—環境準備(一)
  3. 渣渣菜雞的 ElasticSearch 源碼解析 —— 環境搭建
  4. 教你如何在 IDEA 遠程 Debug ElasticSearch

歡迎訪問我的個人博客:http://laijianfeng.org

打開微信掃一掃,關注【小旋鋒】微信公眾號,及時接收博文推送

[圖片上傳失敗...(image-67e56b-1535000041882)]

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,889評論 6 342
  • 說明 本文主要介紹和Gradle關系密切、相對不容易理解的配置,偏重概念介紹。部分內容是Android特有的(例如...
    jzj1993閱讀 15,679評論 1 62
  • Eclipse導入Elasticsearch源碼的步驟,基于Elasticsearch 6.2.2的源碼版本。 1...
    木木與呆呆閱讀 2,477評論 0 6
  • 又是那陣熟悉的微風, 把時光吹的好慢好慢。 我翩翩的長裙掠過街角, 留下一抹淡淡的綠。 車窗外的那片湖泊, 是一如...
    南歌xys閱讀 295評論 1 2
  • 1、“很羨慕你一個人說走就走的旅行,沒時間,我不太敢,一個人不覺得孤獨嗎?”我聽過很多人這樣跟我說。其實我并不是說...
    半個側臉閱讀 198評論 0 0