官术网_书友最值得收藏!

1.3.1 單元測試

在源碼的根目錄中有個BUILDING.txt文件,其中記錄了編譯Hadoop所需的軟件及一些步驟。由于只是為了進行單元測試和通過斷點的方式調試代碼,因此這里只編譯Hadoop,并沒有生成對應的二進制文件,編譯命令為mvn package -Psrc -DskipTests。如果要部署Hadoop,還需要將源碼編譯成二進制文件。編譯二進制文件時,需要先安裝一些依賴軟件,具體如下(這里只關注Linux/Mac環境下的編譯步驟,Windows環境下大同小異)。

  • JDK 1.8
  • Maven 3.3及以上版本
  • Protocol Buffer 2.5.0
  • CMake 3.1及以上版本
  • zlib-devel
  • cyrus–sasl-devel
  • GCC 4.8.1及以上版本
  • openssl-devel
  • Linux FUSE 2.6及以上版本
  • Jansson
  • Doxygen
  • Python
  • bats
  • Node.js

關于它們的具體安裝方式,網上有很多教程,并且較為簡單,故不在此展開。

成功安裝上述依賴軟件之后,執行編譯命令mvn clean package -DskipTests -Pdist, native -Dtar,正常情況下會在hadoop-dist/target下生成一個Hadoop的二進制tar包。如果沒有成功,也不要慌,執行mvn clean package -DskipTests -Pdist,native -Dtar -X查看具體是哪兒出錯了,然后再針對性地去解決。我是在Mac環境下編譯的,如果在編譯過程中遇到問題,可以參考我的博客。在Linux環境下,如果依賴軟件都安裝正確,則出錯的概率較小。

將編譯成功的Hadoop代碼按照本節開頭介紹的方式導入IDEA,然后隨便找個測試類執行單元測試,看看是否有異常信息。這里執行TestJob類,如果成功,則表示源碼閱讀環境已基本部署成功(如果出現有些模塊未識別成Maven項目的情況,可以參考圖1-6進行修改)。

之所以說基本部署成功,是因為還可能會遇到webapps/datanode或者webapps/hdfs的異常,錯誤信息為java.io.FileNotFoundException: webapps/datanode not found in CLASSPATH。如果上述步驟都正常,解決這個問題將非常容易。根據報錯信息可以發現,這是HttpServer2類拋出的異常,此時只要在代碼處加入一些代碼進行調試即可解決,具體代碼如下:

protected String getWebAppsPath(String appName) throws FileNotFoundException {
  URL resourceUrl = null;
  // 將webResourceDevLocation賦值為src/main/webapps目錄
  File webResourceDevLocation = new File("src/main/webapps", appName);
  // 在此處加入代碼,打印出具體的目錄信息
  System.out.println(webResourceDevLocation.getAbsolutePath());
  // 判斷Web服務器的運行方式
  // 當webResourceDevLocation不存在時,運行模式為開發模式
  if (webResourceDevLocation.exists()) {
    LOG.info("Web server is in development mode. Resources "
      + "will be read from the source tree.");
    try {
      resourceUrl =
        webResourceDevLocation.getParentFile().toURI().toURL();
    } catch (MalformedURLException e) {
      throw new FileNotFoundException("Mailformed URL whilefinding the
        " + "web resource dir:" + e.getMessage());
    }
  } else {
    resourceUrl =
      getClass().getClassLoader().getResource("webapps/" + appName);
    // 具體的報錯信息是從這里報出的
    if (resourceUrl == null) {
      throw new FileNotFoundException("webapps/" + appName +
        " not found in CLASSPATH");
    }
  }
  String urlString = resourceUrl.toString();
  return urlString.substring(0, urlString.lastIndexOf('/'));
}

查看代碼,會發現報錯信息在else語句塊中。這段代碼的功能是得到Web服務器的路徑,其中有一個if/else語句塊,用于判斷Web服務器的運行模式。當webResourceDevLocation.exists()為真,即webResourceDevLocation對應的目錄存在時,代表運行的是開發模式,進入if語句塊;不為真時進入else語句塊,報錯的原因是webResourceDevLocation對應的目錄不存在。進入else語句塊后,resourceUrl未獲取到對應的值,為null,即判斷條件resourceUrl == null為真,然后拋出異常。由于這里是在IDEA中運行開發模式,因此只創建webResourceDevLocation對應的目錄即可。至于具體在哪里創建目錄,只需在if語句之前加入println語句,查看Web服務器使用的相對目錄是什么,然后在相對目錄中創建src/main/webapps目錄即可。在實際操作過程中,可能還會報其他異常,也可按照此思路一一解決。

注意:如果導入IDEA的源碼不是通過mvn package -Psrc -DskipTests進行編譯的,那么執行單元測試時就沒有上面這么順利了。比如會出現找不到proto類,或者找不到AvroRecord類的問題,但這些都容易解決,通過對序列化的文件進行編譯,自動生成對應的Java文件,然后將其復制到對應的包目錄即可。比較麻煩的是,有些模塊中找不到另一個模塊的類,這就需要更改當前模塊對其依賴的對應模塊的依賴范圍。例如,導入的代碼是未通過mvn clean package -DskipTests -Pdist,native -Dtar編譯成功的,運行單元測試時,有可能會報下面的異常信息:

/Users/xx/tmp/hadoop-3.2.0-src/hadoop-common-project/hadoop-auth/src/test/java/org
  /apache/hadoop/security/authentication/server/TestKerberosAuthenticationHandler.java
Error:(16, 33) java: 程序包org.apache.hadoop.minikdc不存在
Error:(48, 13) java: 找不到符號
  符號: 類 KerberosSecurityTestcase
Error:(81, 5) java: 找不到符號
  符號:   方法 getKdc()
  位置: 類 org.apache.hadoop.security.authentication.
    server.TestKerberosAuthenticationHandler
Error:(186, 5) java: 找不到符號
  符號:   方法 getKdc()
  位置: 類 org.apache.hadoop.security.authentication.server.
    TestKerberosAuthenticationHandler

此時就需要將auth模塊對minikdc模塊的依賴范圍改為Compile或者Provided,如圖1-7所示。

圖1-7 修改依賴模塊的范圍

主站蜘蛛池模板: 乃东县| 雷州市| 隆尧县| 洱源县| 白城市| 将乐县| 黑水县| 宜川县| 宜兰市| 虹口区| 哈尔滨市| 扶绥县| 台江县| 新津县| 谢通门县| 安塞县| 汉阴县| 册亨县| 安义县| 乌兰县| 灵山县| 新余市| 皮山县| 集贤县| 乐山市| 安徽省| 明星| 永福县| 吐鲁番市| 呼图壁县| 南陵县| 郯城县| 什邡市| 哈巴河县| 长治市| 博白县| 左贡县| 偏关县| 吉水县| 德保县| 桃江县|