sbtのインストール・プロキシ設定【Linux】

プロキシ環境下のLinuxでのsbtインストール方法


* 確認日: 2017/03/22
* OS: Amazon Linux
* sbt: 0.13.13

# 事前準備
1. プロキシサーバー情報を確認
    * host (FQDN or IP)
    * port
2. シェル変数に一時保存
    * 設定コードの `${proxy_host}:${proxy_port}` 部分を都度書き換えるなら不要
    * `logout` すると消えるので、設定完了前に `logout` したら再実行が必要

```bash:プロキシサーバー情報
# 各自の環境に合わせて変更
proxy_host=192.168.12.34
proxy_port=8080
```

# インストール
yumを使ったインストール方法

## yumへのプロキシ設定
まずyumにプロキシ設定が必要
yumの設定ファイル `/etc/yum.conf` にプロキシ設定 `proxy=http://<proxy_host>:<proxy_port>` を書き込み

```bash:yumプロキシ設定
echo "proxy=http://${proxy_host}:${proxy_port}" | sudo tee -a /etc/yum.conf
# [出力] proxy=http://192.168.12.34:8080
```

## curlへのプロキシ設定
リポジトリ情報の取得にcurlを使うためcurlにもプロキシ設定が必要
curlの設定ファイル `~/.curlrc` にプロキシ設定 `proxy=http://<proxy_host>:<proxy_port>` を書き込み

```bash:curlプロキシ設定
echo "proxy=http://${proxy_host}:${proxy_port}" | tee -a ~/.curlrc
# [出力] proxy=http://192.168.12.34:8080
```

## yumでインストール
yumのパッケージマネージャにBintrayのRPMリポジトリの追加が必要
詳細：[sbt Reference Manual — Linux への sbt のインストール](http://www.scala-sbt.org/release/docs/ja/Installing-sbt-on-Linux.html#Red+Hat+Enterprise+Linux+%E5%8F%8A%E3%81%B3%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE+RPM+%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3 "http://www.scala-sbt.org/release/docs/ja/Installing-sbt-on-Linux.html#Red+Hat+Enterprise+Linux+及びその他の+RPM+ベースのディストリビューション")

```bash:yumによるsbtインストール
# リポジトリ追加
curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo
# [出力] bintray--sbt-rpm - packages by  from Bintray
# [出力] (後略)

# インストール
sudo yum install -y sbt
```

```bash:sbtインストール確認
which sbt
# [出力] /usr/bin/sbt
```

# sbtプロキシ設定
sbtも起動時に依存jarを外部からダウンロードする必要があるためプロキシ設定が必要
プロキシ設定がされてない場合、`Getting org.scala-sbt sbt 0.13.13 ...` のメッセージで止まる

```bash:プロキシ設定をしていない場合、依存解決が終わらない
sbt
# [出力] Getting org.scala-sbt sbt 0.13.13 ...
# (このまま進まない)
```

## 設定ファイルに記載して常時反映させておく方法
sbtのインストールディレクトリに ある `sbtopts` ファイルにJavaシステムプロパティーオプション(`-Dkey=value`)を記述
`sbtopts` ファイルのpath計算(詳細は後述): `$(dirname $(readlink $(which sbt)))/../conf/sbtopts`

```bash:sbtプロキシ設定
cat <<- EOS | sudo tee -a $(dirname $(readlink $(which sbt)))/../conf/sbtopts
	# proxy options
	-Dhttp.proxyHost=${proxy_host}
	-Dhttp.proxyPort=${proxy_port}
	-Dhttps.proxyHost=${proxy_host}
	-Dhttps.proxyPort=${proxy_port}
EOS
```

## [参考] 実行の都度設定する方法
毎回プロキシ設定を書くのは手間なので設定ファイルに書く上記の方法をおすすめします

```bash:sbt実行時にプロキシ設定する方法
sbt \
    -Dhttp.proxyHost=${proxy_host} \
    -Dhttp.proxyPort=${proxy_port} \
    -Dhttps.proxyHost=${proxy_host} \
    -Dhttps.proxyPort=${proxy_port}
```

## 補足
### sbtの設定ファイルの場所について
`$(dirname $(readlink $(which sbt)))/../conf/sbtopts` で得られるパスの設定ファイルがどう呼ばれているか

1. `sbt` コマンド (`/usr/bin/sbt`)は `/usr/share/sbt/bin/sbt` のエイリアス
    * `$(readlink $(which sbt))` で取得可能

    ```bash:sbtのインストールディレクトリ確認
    which sbt
    # [出力] /usr/bin/sbt
    
    readlink /usr/bin/sbt
    # [出力] /usr/share/sbt/bin/sbt
    
    echo $(readlink $(which sbt))
    # [出力] /usr/share/sbt/bin/sbt

    ls -l /usr/share/sbt/bin
    # [出力] total 1200
    # [出力] -rwxr-xr-x 1 root root    5156 Jan  4 23:30 sbt
    # [出力] -rw-r--r-- 1 root root 1210231 Jan  4 23:53 sbt-launch.jar
    # [出力] -rwxr-xr-x 1 root root    6915 Sep 16  2016 sbt-launch-lib.bash
    ```
1. `${sbt_home}/conf/sbtopts` ファイルに書かれているオプションが自動で渡されて実行される
    * [sbtコマンドのソースコード@GitHub](https://github.com/sbt/sbt-launcher-package/blob/master/src/universal/bin/sbt "https://github.com/sbt/sbt-launcher-package/blob/master/src/universal/bin/sbt")

        ```bash:sbt
        # （前略）
          
        . "$(dirname "$(realpath "$0")")/sbt-launch-lib.bash"
          
        # （中略）
        
        declare -r sbt_opts_file=".sbtopts"
        declare -r etc_sbt_opts_file="${sbt_home}/conf/sbtopts"
        declare -r win_sbt_opts_file="${sbt_home}/conf/sbtconfig.txt"
          
        # （中略）
        
        # Here we pull in the global settings configuration.
        [[ -f "$etc_sbt_opts_file" ]] && set -- $(loadConfigFile "$etc_sbt_opts_file") "$@"
        
        #  Pull in the project-level config file, if it exists.
        [[ -f "$sbt_opts_file" ]] && set -- $(loadConfigFile "$sbt_opts_file") "$@"
        
        #  Pull in the project-level java config, if it exists.
        [[ -f ".jvmopts" ]] && export JAVA_OPTS="$JAVA_OPTS $(loadConfigFile .jvmopts)"
        
        run "$@"
        ```
    * ※ `.sbtopts` ファイルが存在すればそちらも使われる

1. `${sbt_home}` は [sbt-launch-lib.bash](https://github.com/sbt/sbt-launcher-package/blob/master/src/universal/bin/sbt-launch-lib.bash "https://github.com/sbt/sbt-launcher-package/blob/master/src/universal/bin/sbt-launch-lib.bash") で定義されている
    * `sbt-launch-lib.bash` は `sbt` コマンドと同一ディレクトリに存在
        * ※ `sbt`の中の `. "$(dirname "$(realpath "$0")")/sbt-launch-lib.bash"` で実行されている

    ```bash:sbt-launch-lib.bash
    # （前略）
      
    declare -r sbt_bin_dir="$(dirname "$(realpath "$0")")"
    declare -r sbt_home="$(dirname "$sbt_bin_dir")"
      
    # （後略）
    ```
    * `sbt` コマンドのあるディレクトリの1つ上が `${sbt_home}`
        * つまり `/usr/share/sbt/`
        * `$(dirname $(readlink $(which sbt)))/../` で取得可能

           ```bash:${sbt_home}確認
           realpath $(dirname $(readlink $(which sbt)))/../`
           # [出力] /usr/share/sbt
           ```


1. sbtの設定ファイル(`sbtopts`)は `conf` ディレクトリ内
    * つまり `/usr/share/sbt/conf/sbtopts`
    * `$(dirname $(readlink $(which sbt)))/../conf/sbtopts` で取得可能

    ```bash:confディレクトリの確認
    ls -l /usr/share/sbt/
    # [出力] total 8
    # [出力] drwxr-xr-x 2 root root 4096 Mar 22 05:05 bin
    # [出力] drwxr-xr-x 2 root root 4096 Mar 22 05:05 conf
    
    ls -l /usr/share/sbt/conf/
    # [出力] total 8
    # [出力] -rw-r--r-- 1 root root  147 Aug 11  2015 sbtconfig.txt
    # [出力] -rw-r--r-- 1 root root 1083 Mar 23 07:11 sbtopts
    

    realpath $(dirname $(readlink $(which sbt)))/../conf/sbtopts
    # [出力] /usr/share/sbt/conf/sbtopts
    ```


### プロキシ設定がちゃんと効いているかの確認方法

1. debugオプション有りで `sbt` 起動
    * `sbt -debug`
1. Javaオプションにシステムプロパティが含まれているか確認

    ```text:該当システムプロパティ
    -Dhttp.proxyHost=192.168.12.34
    -Dhttp.proxyPort=8080
    -Dhttps.proxyHost=192.168.12.34
    -Dhttps.proxyPort=8080
    ```


```text:debugオプション有りの場合の出力（プロキシ設定なし）
[process_args] java_version = '1.7.0_131'
# Executing command line:
java
-Xms1024m
-Xmx1024m
-XX:ReservedCodeCacheSize=128m
-XX:MaxPermSize=256m
-jar
/usr/share/sbt/bin/sbt-launch.jar

Getting org.scala-sbt sbt 0.13.13 ...

(後略)
```

```text:debugオプション有りの場合の出力（プロキシ設定あり）
[process_args] java_version = '1.7.0_131'
# Executing command line:
java
-Xms1024m
-Xmx1024m
-XX:ReservedCodeCacheSize=128m
-XX:MaxPermSize=256m
-Dhttp.proxyHost=192.168.12.34
-Dhttp.proxyPort=8080
-Dhttps.proxyHost=192.168.12.34
-Dhttps.proxyPort=8080
-jar
/usr/share/sbt/bin/sbt-launch.jar

Getting org.scala-sbt sbt 0.13.13 ...

(後略)
```