Cent OSでのOpenJDKのビルド方法


OpenJDKとは
==========

OpenJDKとはOracleのJavaのオープンソース版です．すべての機能が含まれているわけではないようですが，ほとんどのJavaの機能が使えます．ライセンス上GPL2に限定して再頒布したいときや，Cent OS 7のようにJava 8のパッケージが提供されていないような場合やJavaFXが含まれていない場合に使えます．他には共有するコンピュータでroot権限がないときにJavaを使いたい場合に手元でビルドして持っていくことも出来ます．

OpenJDKのビルド
=====

まずは，ビルドに必要なパッケージをインストールします．この例ではCent OS 7を前提にしていますが，Cent OS 6でもほぼ同様です．JavaのビルドにはJavaが必要ですので，Java 7もインストールしています．

```bash
sudo yum install -y autoconf automake bison flex gcc gcc-c++ gcc-gfortran kernel-devel make m4 patch tar bzip2 gzip xz file gmp-devel mpfr-devel wget rsync unzip zip java-1.7.0-openjdk-devel libXtst-devel libXt-devel libXrender-devel cups-devel alsa-lib-devel freetype-devel which ccache
```

JavaFXを使いたい場合には以下もインストールします．

```bash
yum install -y mercurial bison flex gperf ksh pkgconfig libpng-devel libjpeg-devel libxml2-devel libxslt-devel systemd-devel glib2-devel  gtk2-devel libXtst-devel pango-devel freetype-devel libXxf86vm-devel mesa-libGL-devel mesa-libGLU-devel mesa-libGLw-devel
```

次に，必要なファイルをダウンロードしてきます．公式サイトではMercurialのリポジトリをcloneしてくるように書いてありますが，そこまでは必要ないので今回はtar.gzで固められたファイルをダウンロードしてきます．ビルド番号などは適切なものに修正してください．また，ファイル名が同じになってしまうので，区別がつくようにしてください．

```bash
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/corba/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/jaxp/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/archive/jdk8u71-b15.tar.gz
curl -OL http://hg.openjdk.java.net/jdk8u/jdk8u/nashorn/archive/jdk8u71-b15.tar.gz
```

次に，これらのファイルを展開します．まず，`http://hg.openjdk.java.net/jdk8u/jdk8u/jdk8u71-b15.tar.gz`からダウンロードしたものを展開します．その後，`http://hg.openjdk.java.net/jdk8u/jdk8u/corba/archive/jdk8u71-b15.tar.gz`からダウンロードしたものを，先ほど展開したディレクトリの中に`corba`として展開します．これを，先ほどダウンロードした各ファイルについて行います．

圧縮ファイルの展開が終わったら，最初に展開したディレクトリに`cd`で移動し，

```bash
bash configure --prefix=/usr/local --with-milestone=fcs --with-update-version=71 --with-build-number=15
make all
sudo make install
```

を実行します．こすることで，`/usr/local/jvm`の中にビルドされたJavaがインストールされているはずです．

ビルドスクリプト
------------

上で説明した手順を実行するためのスクリプトを置いておきます．すべて，同じフォルダに配置してください．その上で，`get-openjdk.sh`を実行し，次に`build-openjdk.sh`を実行するとできあがります．依存パッケージのインストールは行いませんので，それらは別にインストールしてください．

### openjdk-common.sh

`ARCHIVE_DIR`, `BUILD_DIR`, `JAVA_UPDATE`, `JAVA_BUILDNUM`は適宜修正してください．

```bash
ARCHIVE_DIR=/build/openjdk-archives
BUILD_DIR=/build/openjdk-build

JAVA_UPDATE=71
JAVA_BUILDNUM=15
JAVAFX_BUILDNUM=${JAVA_BUILDNUM}

REPOSITORY_NAME=jdk8u
BASE_URL=http://hg.openjdk.java.net/jdk8u/${REPOSITORY_NAME}
BASE_FILENAME=jdk8u${JAVA_UPDATE}-b${JAVA_BUILDNUM}.tar.gz

URL=$BASE_URL/archive/$BASE_FILENAME
SUB_PROJECTS="corba hotspot jdk jaxws jaxp langtools nashorn"

JAVA_BUILD_DIR=$BUILD_DIR/openjdk8u${JAVA_UPDATE}

function run() {
    echo "$@"
    "$@" || exit 1
}
```

### get-openjdk.sh

```bash
#!/bin/sh

source openjdk-common.sh

mkdir $ARCHIVE_DIR
pushd $ARCHIVE_DIR

curl -O ${URL} || exit 1

for i in $SUB_PROJECTS; do
  SUB_URL=$BASE_URL/$i/archive/$BASE_FILENAME
  echo "Downloading $SUB_URL"
  if [ ! -f "${i}-$BASE_FILENAME" ];then
    curl -o ${i}-$BASE_FILENAME -L "$SUB_URL" || (rm "$FILENAME"; exit 1)
  fi
done

popd
```

### build-openjdk.sh


```bash
#!/bin/bash

source openjdk-common.sh

run mkdir -p $JAVA_BUILD_DIR

pushd $JAVA_BUILD_DIR

run tar xzf $ARCHIVE_DIR/$BASE_FILENAME
for i in $SUB_PROJECTS; do
  if [ ! -d ${REPOSITORY_NAME}-${BASE_FILENAME%.tar.gz}/$i ];then
    if [ ! -d ${i}-${BASE_FILENAME%.tar.gz} ];then
      run tar xzf $ARCHIVE_DIR/${i}-$BASE_FILENAME
    fi
    run mv ${i}-${BASE_FILENAME%.tar.gz} ${REPOSITORY_NAME}-${BASE_FILENAME%.tar.gz}/$i
  fi
done

pushd ${REPOSITORY_NAME}-${BASE_FILENAME%.tar.gz}

run bash configure --prefix=/usr/local --with-milestone=fcs --with-update-version=$JAVA_UPDATE --with-build-number=$JAVA_BUILDNUM
run make all
run sudo make install

popd
popd

run sudo rm -rf $JAVA_BUILD_DIR

```


JavaFXのビルド
=======

JavaFXはJava本体とは別にビルドする必要があります．こちらはダウンロードするものが2つだけなので簡単です．ビルドにGradleが必要ですが，これは1.8である必要があります．

```bash
curl -OL http://hg.openjdk.java.net/openjfx/8u/rt/archive/8u71-b15.tar.gz
curl -OL https://downloads.gradle.org/distributions/gradle-1.8-bin.zip
```

次に，ビルドを行います．先ほどダウンロードした二つのファイルを展開して，適当なディレクトリに配置します．また，Gradle 1.8にパスを通しておきます．そうしたら，上の二つのうちの上の方のURLでダウンロードしたファイルを展開したディレクトリに移動し，次のコマンドを実行します．

```bash
gradle tasks
gradle projects
gradle
```

これが最後まで実行できればビルド完了です．次にインストールします．環境変数`JAVA_HOME`を設定しておいてください．今回の例だと`/usr/local/jvm/openjdk-1.8.0_71`にしておくのがよいでしょう．

```bash
sudo cp -R ./build/sdk/* $JAVA_HOME/
sudo cp -R ./build/sdk/rt/* $JAVA_HOME/jre/
sudo rm -r $JAVA_HOME/rt
```

これにて，JavaFXのビルド＆インストールが完了です．


ビルドスクリプト
-----------

OpenJDKのビルドに示したディレクトリと同じディレクトリに配置してください．また，`get-javafx.sh`の次に`build-javafx.sh`の順で実行してください．

### get-javafx.sh

```bash
#!/bin/bash

source openjdk-common.sh

JAVAFX_URL=http://hg.openjdk.java.net/openjfx/8u/rt/archive/8u${JAVA_UPDATE}-b${JAVAFX_BUILDNUM}.tar.gz
GRADLE_URL=https://downloads.gradle.org/distributions/gradle-1.8-bin.zip

mkdir -p $ARCHIVE_DIR
pushd $ARCHIVE_DIR

run curl -L -O ${JAVAFX_URL}
run curl -L -O ${GRADLE_URL}

popd
```


### build-javafx.sh

```bash
#!/bin/bash

source openjdk-common.sh
run mkdir -p $JAVA_BUILD_DIR
export JAVA_HOME=/usr/local/jvm/openjdk-1.8.0_${JAVA_UPDATE}

pushd $JAVA_BUILD_DIR
if [ ! -d rt-8u${JAVA_UPDATE}-b${JAVAFX_BUILDNUM} ]; then
    run tar xzf $ARCHIVE_DIR/8u${JAVA_UPDATE}-b${JAVAFX_BUILDNUM}.tar.gz
fi

if [ ! -d gradle-1.8 ];then
    run unzip $ARCHIVE_DIR/gradle-1.8-bin.zip
fi

export PATH=$JAVA_HOME/bin:$JAVA_BUILD_DIR/gradle-1.8/bin:$PATH

pushd rt-8u${JAVA_UPDATE}-b${JAVAFX_BUILDNUM}

sudo rm $JAVA_HOME/jre/lib/ext/jfxrt.jar

run gradle tasks
run gradle projects
run gradle

run sudo cp -R ./build/sdk/* $JAVA_HOME/
run sudo cp -R ./build/sdk/rt/* $JAVA_HOME/jre/
run sudo rm -r $JAVA_HOME/rt

popd
popd
```

やり残したこと
============

* このビルドでは証明書の問題でHTTPSの通信が失敗するかもしれません．
* JavaFXのビルドが公式ドキュメント通りではないので，もしかしたら何か足らないかもしれません
* SceneBuilderもきちんとビルドして入れておきたいところですが，入っていません．