Apache HadoopとJava 9 (その1)


## 概要

2017年5月にApache: Big Data North Americaで、Apache HadoopはJava 9に現状対応してないよー、あれもこれも大変、っていう話をしたときからどれだけ状況が変わったか紹介します。

[Apache: Big Dataの発表資料](http://events.linuxfoundation.org/sites/events/files/slides/Java9SupportInApacheHadoop.pdf)

[2017年3月のHadoopソースコードリーディングでの発表資料(日本語)](https://www.slideshare.net/hadoopxnttdata/20170303-java9-hadoop-72688327)

## Java 9でHadoopのコンパイルを通す

手元のMacBook Pro(High Sierra)でさっそくコンパイルしましょう。以下のバージョンで試します。

```
mbpaa:hadoop$ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
```

何気に、正式リリース後のJava 9を触るのは初めてです。

### Revert HADOOP-14986

がーん、今までに見たことのない落ち方をしていた...

```
mbpaa:hadoop$ mvn install -DskipTests
[INFO] Scanning for projects...

(snip)

[INFO] --- animal-sniffer-maven-plugin:1.16:check (signature-check) @ hadoop-annotations ---
[INFO] Checking unresolved references to org.codehaus.mojo.signature:java18:1.0
[ERROR] /Users/ajisaka/git/hadoop/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java:56: Undefined reference: com.sun.javadoc.RootDoc
[ERROR] /Users/ajisaka/git/hadoop/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java:104: Undefined reference: com.sun.javadoc.Doc
[ERROR] /Users/ajisaka/git/hadoop/hadoop-common-project/hadoop-annotations/src/main/java/org/apache/hadoop/classification/tools/RootDocProcessor.java:106: Undefined reference: com.sun.javadoc.Doc
```

どうやら、[HADOOP-14986. Enforce JDK limitations](https://issues.apache.org/jira/browse/HADOOP-14986)で追加されたanimal-sniffer-maven-pluginがJava 9で動作しないらしい。とりあえず手元でrevertしてみます。

```
mbpaa:hadoop$ git revert b50def36970e0afa65bd3fd3f40d8c4f81119200
```

* 参考: Animal Sniffer Signature Error https://github.com/mojohaus/animal-sniffer/issues/29

### Apply HADOOP-12760

次のエラーはこちらです。

```
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project hadoop-common: Compilation failure: Compilation failure:
[ERROR] /Users/ajisaka/git/hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java:[333,17] cannot find symbol
[ERROR] symbol:   class Cleaner
[ERROR] location: package sun.misc
[ERROR] /Users/ajisaka/git/hadoop/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoStreamUtils.java:[40,21] cannot find symbol
[ERROR] symbol:   class Cleaner
[ERROR] location: package sun.misc
```

これは見覚えがあるエラーです。[HADOOP-12760. sun.misc.Cleaner has moved to a new location in OpenJDK 9](https://issues.apache.org/jira/browse/HADOOP-12760)のパッチを当てれば解決するので、当てましょう。`dev-support/bin/smart-apply-patch`が便利です。私は`dev-support/bin`を`PATH`に追加しています。

* 参考のために、[HADOOP-12760の日本語版解説記事を公開しました](https://qiita.com/ajis_ka/items/e89cd2472e961bac69bc)

```
mbpaa:hadoop$ smart-apply-patch HADOOP-12760
Processing: HADOOP-12760
HADOOP-12760 patch is being downloaded at Sat Dec  2 23:19:19 JST 2017 from
  https://issues.apache.org/jira/secure/attachment/12850964/HADOOP-12760.03.patch -> Downloaded
Applying the patch:
Sat Dec  2 23:19:20 JST 2017
cd /Users/ajisaka/git/hadoop
patch -p1 -E
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoStreamUtils.java
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/nativeio/NativeIO.java
Hunk #1 succeeded at 38 with fuzz 1 (offset 1 line).
Hunk #2 succeeded at 316 (offset 3 lines).
Hunk #3 succeeded at 330 (offset 3 lines).
patching file hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/CleanerUtil.java
```

### Apply HDFS-11610

次のエラーはこちらです。

```
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project hadoop-hdfs: Compilation failure: Compilation failure:
[ERROR] /Users/ajisaka/git/hadoop/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSClientFailover.java:[66,31] package sun.net.spi.nameservice does not exist
```

これも見覚えのあるエラーです。[HDFS-11610. sun.net.spi.nameservice.NameService has moved to a new location](https://issues.apache.org/jira/browse/HDFS-11610)のパッチを当てましょう。

```
mbpaa:hadoop$ smart-apply-patch HDFS-11610
Processing: HDFS-11610
HDFS-11610 patch is being downloaded at Sat Dec  2 23:27:05 JST 2017 from
  https://issues.apache.org/jira/secure/attachment/12879343/HDFS-11610.001.patch -> Downloaded
Applying the patch:
Sat Dec  2 23:27:06 JST 2017
cd /Users/ajisaka/git/hadoop
git apply --binary -v --stat --apply -p1 /tmp/yetus-30092.22999/patch
Hunk #1 succeeded at 600 (offset 5 lines).
Applied patch hadoop-hdfs-project/hadoop-hdfs/pom.xml cleanly.
 hadoop-hdfs-project/hadoop-hdfs/pom.xml |   19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
```

無事コンパイルできました。

```
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 08:05 min
[INFO] Finished at: 2017-12-02T23:35:42+09:00
[INFO] Final Memory: 185M/616M
[INFO] ------------------------------------------------------------------------
```

## 以前との差分

[HADOOP-11875. Add a second copy of Hamlet without _ as a one-character identifier](https://issues.apache.org/jira/browse/HADOOP-11875)をマージしたり、いくつかのMaven pluginのバージョンを上げたおかげで、コンパイルするための手順は減りました。

また、Java側のアップデートのおかげで、コンパイルオプション`--add-opens`をつけなくてもよくなりました。

## 今後の展望

上記3つの修正も早いうちにコミュニティにマージしたいです。あとはライブラリのアップデートも。Log4JとJUnitが特に大変。最近はApache Hadoopコミュニティでの活動以外の仕事が忙しく時間がとれてない。。。

* [HADOOP-12956. Inevitable Log4j2 migration via slf4j](https://issues.apache.org/jira/browse/HADOOP-12956)
* [HADOOP-14693. Upgrade JUnit from 4 to 5](https://issues.apache.org/jira/browse/HADOOP-14693)

## 最後に

忙しい人のために、この3つをまとめたパッチをgistに貼っておきました。

* https://gist.github.com/aajisaka/26049b1ddaf0b092b8b08cf8a13b4844

次はApache Hadoopを動かしてみたいと思います。