2017/9/25にJava SE9がリリースされました。
そのオープンソース実装であるOpenJDKはソースコードがjava.netにホスティングされているMercurialで公開されていますが、JDK9のソースコードは、レポジトリーをクローンした後に、サブモジュールをget_source.shというシェルスクリプトを実行して取得するようになっているため、Windowsでは直接コードを取得することができません。*1
そこで本エントリーでは、先日リリースされたWindows 10 Fall Creatorsから正式版になったBash on Ubuntu on Windows改めWindows Subsystem for Linuxを使ってOpenJDKのソースコードをWindowsからチェックアウトしてみます。なお、macOSならクローンした後にget_source.shを直接実行すれば終わりじゃないのかということについては、ツッコミを入れないのが(IT)エンジニアしぐさというものです。
Windows Subsystem for Linuxの有効化
まず、Windows Subsystem for LinuxをWindowsの「Windowsの機能の有効化又は無効化」から有効にします。

この際にWindowsの再起動を求められるので、これに従います。
Ubuntuのインストール
続いて、Windowsの「ストア」から各OSのディストリビューションをインストールします。ここでは「Ubuntu」を選択します。

初回の起動時にLinux側のユーザーを作成すると、Windows上でLinuxのサブシステムが使用できるようになります。
Ubuntuの起動はスタートメニューもしくは、コマンドプロンプトからubuntuコマンドで起動します。Anniversary Updateで提供されていたベータ版では起動コマンドがbashだったため、Git for Windowsが提供するbash.exeとコマンド名が衝突するという悲しい仕様があったのですが、この問題も正式版では解消されています。

Mercurialのインストール
UbuntuにMercurialをインストールします。インストール直後だとパッケージリストが古くてapt installに軒並み失敗するため、apt updateをまず行います。
azusa@izumo:~$ sudo apt install mercurial [sudo] password for azusa: Reading package lists... Done Building dependency tree Reading state information... Done Package mercurial is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source azusa@izumo:~$ sudo apt-get update Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:4 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [370 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB] Get:6 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [7,532 kB] (略) Fetched 15.0 MB in 13s (1,145 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 29 packages can be upgraded. Run 'apt list --upgradable' to see them.
続いてMercurialをインストールします。
azusa@izumo:~$ sudo apt install mercurial Reading package lists... Done Building dependency tree Reading state information... Done The following package was automatically installed and is no longer required: libfreetype6 Use 'sudo apt autoremove' to remove it. Selecting previously unselected package libpython2.7-stdlib:amd64. (略)
OpenJDKのソースコードをチェックアウトする
hg cloneコマンドでOpenJDKのレポジトリーをクローンします。
azusa@izumo:~$ hg clone http://hg.openjdk.java.net/jdk9/jdk9/ destination directory: jdk9 requesting all changes adding changesets adding manifests adding file changes added 2628 changesets with 4461 changes to 468 files updating to branch default 322 files updated, 0 files merged, 0 files removed, 0 files unresolved
続いてクローンしたディレクトリー内のget_source.shを実行して、サブモジュールを取得します。
azusa@izumo:~/jdk9$ bash get_source.sh
# Repositories: corba jaxp jaxws langtools jdk hotspot nashorn
corba: hg clone http://hg.openjdk.java.net/jdk9/jdk9/corba corba
jaxp: hg clone http://hg.openjdk.java.net/jdk9/jdk9/jaxp jaxp
jaxp: requesting all changes
corba: requesting all changes
jaxp: adding changesets
corba: adding changesets
corba: adding manifests
jaxp: adding manifests
corba: adding file changes
jaxp: adding file changes
corba: added 876 changesets with 5451 changes to 2597 files
corba: updating to branch default
corba: 1201 files updated, 0 files merged, 0 files removed, 0 files unresolved
jaxws: hg clone http://hg.openjdk.java.net/jdk9/jdk9/jaxws jaxws
jaxws: requesting all changes
jaxws: adding changesets
jaxws: adding manifests
jaxws: adding file changes
jaxp: added 1153 changesets with 14751 changes to 8449 files
jaxp: updating to branch default
jaxp: 3352 files updated, 0 files merged, 0 files removed, 0 files unresolved
langtools: hg clone http://hg.openjdk.java.net/jdk9/jdk9/langtools langtools
langtools: requesting all changes
langtools: adding changesets
langtools: adding manifests
langtools: adding file changes
jaxws: added 801 changesets with 21839 changes to 10824 files
jaxws: updating to branch default
jaxws: 3760 files updated, 0 files merged, 0 files removed, 0 files unresolved
jdk: hg clone http://hg.openjdk.java.net/jdk9/jdk9/jdk jdk
jdk: requesting all changes
jdk: adding changesets
jdk: adding manifests
langtools: added 4174 changesets with 38097 changes to 11847 files
langtools: updating to branch default
langtools: 9464 files updated, 0 files merged, 0 files removed, 0 files unresolved
hotspot: hg clone http://hg.openjdk.java.net/jdk9/jdk9/hotspot hotspot
hotspot: requesting all changes
hotspot: adding changesets
hotspot: adding manifests
hotspot: adding file changes
jdk: adding file changes
hotspot: added 12824 changesets with 78616 changes to 15832 files
hotspot: updating to branch default
hotspot: 9078 files updated, 0 files merged, 0 files removed, 0 files unresolved
nashorn: hg clone http://hg.openjdk.java.net/jdk9/jdk9/nashorn nashorn
nashorn: requesting all changes
nashorn: adding changesets
nashorn: adding manifests
nashorn: adding file changes
nashorn: added 1928 changesets with 14563 changes to 4181 files
nashorn: updating to branch default
nashorn: 3293 files updated, 0 files merged, 0 files removed, 0 files unresolved
jdk: added 17287 changesets with 152446 changes to 50650 files
jdk: updating to branch default
jdk: 27295 files updated, 0 files merged, 0 files removed, 0 files unresolved
# Repositories: . corba jaxp jaxws langtools jdk hotspot nashorn
.: cd . && hg pull -u
corba: cd corba && hg pull -u
.: pulling from http://hg.openjdk.java.net/jdk9/jdk9/
jaxp: cd jaxp && hg pull -u
corba: pulling from http://hg.openjdk.java.net/jdk9/jdk9/corba
jaxws: cd jaxws && hg pull -u
jaxp: pulling from http://hg.openjdk.java.net/jdk9/jdk9/jaxp
langtools: cd langtools && hg pull -u
jaxws: pulling from http://hg.openjdk.java.net/jdk9/jdk9/jaxws
jdk: cd jdk && hg pull -u
langtools: pulling from http://hg.openjdk.java.net/jdk9/jdk9/langtools
.: searching for changes
.: no changes found
corba: searching for changes
corba: no changes found
hotspot: cd hotspot && hg pull -u
jdk: pulling from http://hg.openjdk.java.net/jdk9/jdk9/jdk
nashorn: cd nashorn && hg pull -u
jaxp: searching for changes
jaxp: no changes found
hotspot: pulling from http://hg.openjdk.java.net/jdk9/jdk9/hotspot
jaxws: searching for changes
jaxws: no changes found
nashorn: pulling from http://hg.openjdk.java.net/jdk9/jdk9/nashorn
langtools: searching for changes
langtools: no changes found
jdk: searching for changes
jdk: no changes found
hotspot: searching for changes
hotspot: no changes found
nashorn: searching for changes
nashorn: no changes found
例えばjdk/src/java.base/share/classes/java/lang/String.javaを見てみると、お馴染みのjava.lang.Stringのソースコードが確認できます。
azusa@LPC-2070:~/jdk9$ head -n 100 jdk/src/java.base/share/classes/java/lang/String.java /* * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; (略)
Windows上からコードを閲覧できるようにする。
Windows Subsystem for Linux上のファイルシステムからは、Windows上のファイルシステムは/mnt配下でアクセスすることができますが、その逆は不可です。 Windows上からコードを閲覧できるようにするには、
- Ubuntu上でチェックアウトしたソースコードを、Windowsのファイルシステムにコピーする
hg cloneコマンドでチェックアウトする際に、Windowsのファイルシステム配下でコマンドを実行する
のいずれかの手順を取ることになります。
後者の手順を取る場合の注意点は、チェックアウト語一般ユーザー権限でget_source.shを実行すると、Ubuntuからは/mnt以下の所有者はroot:tootとして見えるため、スクリプトがこれを想定しておらずエラーとなることです。
azusa@izumo:/mnt/c/temp/jdk9$ bash get_source.sh not trusting file /mnt/c/temp/jdk9/.hg/hgrc from untrusted user root, group root not trusting file /mnt/c/temp/jdk9/.hg/hgrc from untrusted user root, group root not found!
これを回避するためには、多少乱暴ですがsudo bash get_source.shというようにsudoをつけて、root権限でスクリプトを実行するようにします。
Windows側のファイルシステムにコピーした後は、Sourcetree等のGUIクライアントでもソースコードを閲覧することができます。

以上、OpenJDKのソースコードをWindowsでチェックアウトする手順についてまとめました。ソースコードをチェックアウトするのに随分たいそうな手順を踏んだ気がしますが、2/3くらいはLinux環境のセットアップですので、チェックアウトする手順自体はWindows Subsystem for Linux上でも通常のbashスクリプトが問題なく動いている点に着目いただければと思います。
*1:例えば http://hg.openjdk.java.net/jdk9/jdk9/jdk/ のようなサブモジュール単位であれば可能