Windows でも Clojure がしたい!

  • 13
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

Java 仮想マシン (JVM) 上で動く Lisp 系言語 Clojure の入門書を買って一年がたちました.最近ふと Clojure の環境構築だけでもしてみようと思ったのですが,手元にあるのは Windows のみ.ということで,インターネットで検索しつつ Windows 上で Clojure の開発環境を構築しよう……と思ったらいくつか嵌ったのでメモ.

私の環境: Windows 8.1 タブレット (32 ビット)
最終更新日: 2015/01/29

JDK

JDK とは

JDK (Java Development Kit) はその名の通り Java の開発キットです.とりあえずこれを入れないと話にならないようなのでインストールします.

Java での開発をしたことがある等で既に JDK を持っている場合はスキップしてください.

インストーラのダウンロード

まず Java SE - Downloads | Oracle Technology Network | Oracle に行きます.

"Java" と "NetBeans" の二つが見えますが,今回は NetBeans は入れないので左の "Java" を選択します.

すると Java SE Development Kit ダウンロードページへ飛びます.まず "Accept License Agreement" ボタンにチェックを入れ,32 ビット PC なら "jdk-XXX-windows-i586.exe", 64 ビット PC なら jdk-XXX-windows-x64.exe をダウンロードします.

※ JDK のダウンロードについては,以下の記事が詳しいです.
JDKのインストール(Windows)と Java 関連用語の説明 | プログラマーズ雑記帳

JDK のインストール

ダウンロードしたインストーラを実行します.デフォルトのインストール場所は "C:\Program Files\Java\jdkX.X.X_XX" ですが,"Program Files" に空白文字が含まれるのが問題となることがあるらしいので他の場所に変更しておくのが好ましいです.

私はとりあえずインストール先を "C:\Java\jdkX.X.X_XX" に変更しました.
その次に JRE のインストールも行われますが,こちらのインストール先も "C:\Java\jreX.X.X_XX" としました.

Leiningen

Leiningen とは

Leiningen は Clojure プロジェクトのビルド,プロジェクトやパッケージの管理を行ってくれるツールです (Haskell の Cabal みたいな感じ?).とりあえず,これさえ入れれば Clojure が使えるらしいです.

インストーラのダウンロード

leiningen-win-installer から Windows 用のインストーラ leiningen-win-installer が手に入ります.

環境変数 LEIN_HOME の設定

インストーラを起動するとまず最初にインストール先を変更できるのですが,ここでインストール先を変更してもなぜかきちんと反映されません.

インストール先を変更したい場合は環境変数 LEIN_HOME を作成してそこにインストール先フォルダのパスを設定しておく必要があるようです.

例えばインストール先を "C:\lein" にしたい場合は次のようします (新規で環境変数を作成し,値としてパスを設定します).

環境変数の設定

Leiningen のインストール

ダウンロードしたインストーラを実行します.

インストール先が LEIN_HOME で設定した値になっているのが確認できると思います.

次に JDK を選択します.先ほどインストールした JDK があると思うので,それを選択します.

Install を押すとインストールが開始されます.

終了したら,とりあえずついているチェックマークを外して終了してください.

self-install

インストーラを実行し終われば Clojure が使える……はずです.

試しにコマンドプロンプトを開いて lein repl と打ってみてください.これで REPL (Read-Eval-Print Loop, 対話環境のこと) が起動すると思います.起動したなら終了です.お疲れ様でした.

私は起動しませんでした.

C:\lein>lein repl

C:\lein\self-installs\leiningen-2.5.1-standalone.jar can not be found.
You can try running "lein self-install"
or change LEIN_JAR environment variable
or edit lein.bat to set appropriate LEIN_JAR path.

どうもインストーラが leiningen-X.X.X-standalone.jar というファイルを self-install してくれていない (失敗している?) ため,自分で self-install することにします.

コマンドプロンプトを開き,lein self-install と打ちます.その後,再び lein repl を試してみて起動したならば終了です.お疲れ様でした.

私は起動しませんでした.

C:\lein>lein self-install
Downloading Leiningen now...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   408    0   408    0     0    357      0 --:--:--  0:00:01 --:--:--   357
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

Failed to download https://github.com/technomancy/leiningen/releases/download/2.5.1/leiningen-2.5.1-standalone.zip

どうも lein self-install が SSL certificate problem で失敗しているようです.

この問題について調べたのですが解決方法がわかりませんでした コメントを頂いて,この問題の解決方法がわかりました.

※ そもそもエラーメッセージがなんか違う! 俺の環境だと次のようになった! という場合は,wget が使われている可能性があります.その場合は「エラーメッセージがなんか違うんだけど? というとき (Wget)」を見てください.

なんか違うエラーメッセージ
C:\lein>lein self-install
Downloading Leiningen now...
SYSTEM_WGETRC = c:/progra~1/wget/etc/wgetrc
syswgetrc = C:\Program Files\GnuWin32/etc/wgetrc
--2015-01-29 00:21:32--  https://github.com/technomancy/leiningen/releases/download/2.5.1/leiningen-2.5.1-standalone.zip
github.com をDNSに問いあわせています... 192.30.252.129
github.com|192.30.252.129|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 302 Found
場所: https://s3.amazonaws.com/github-cloud/releases/356756/bb5f7a62-97e4-11e4-9bf2-cae89695df6a.zip?response-content-disposition=attachment%3B%20filename%3Dleiningen-2.5.1-standalone.zip&response-content-type=application/octet-stream&AWSAccessKeyId=AKIAISTNZFOVBIJMK3TQ&Expires=1422458554&Signature=45RtXM11Hn4UlSLVlj86oxLWKMc%3D [続く]
--2015-01-29 00:21:34--  https://s3.amazonaws.com/github-cloud/releases/356756/bb5f7a62-97e4-11e4-9bf2-cae89695df6a.zip?response-content-disposition=attachment%3B%20filename%3Dleiningen-2.5.1-standalone.zip&response-content-type=application/octet-stream&AWSAccessKeyId=AKIAISTNZFOVBIJMK3TQ&Expires=1422458554&Signature=45RtXM11Hn4UlSLVlj86oxLWKMc%3D
s3.amazonaws.com をDNSに問いあわせています... 54.231.244.4
s3.amazonaws.com|54.231.244.4|:443 に接続しています... 接続しました。
エラー: s3.amazonaws.com の証明書(発行者: /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA - G3)の検証に失敗しました:
  発行者の権限を検証できませんでした。
s3.amazonaws.com に安全の確認をしないで接続するには、`--no-check-certificate' を使ってください。
SSL による接続が確立できません。

Failed to download https://github.com/technomancy/leiningen/releases/download/2.5.1/leiningen-2.5.1-standalone.zip

SSL certificate problem の解決法 (cURL)

上のエラーは SSL という通信プロトコルの証明書がみつからない (unable to get local issuer certificate)! というエラーでした.

しかし Leiningen をインストールしたフォルダ内の bin フォルダを除くと,curl-ca-bundle.crt という証明書がちゃんと用意されています.よってこれを指定してあげることでエラーを回避することができます.

curl-ca-bundle.crt

証明書の指定方法ですが,まず bin フォルダ内に _curlrc という設定ファイルを作成します.

_curlrc

そして,_curlrc の中に次のように記述し保存します.

_curlrc
--cacert curl-ca-bundle.crt

これで証明書の指定ができたので,うまくいくはずです!

_curlrc の設定を反映させるため,コマンドプロンプトを開き bin フォルダまで移動します.上の例だと C:\lein\bin ですね.ここで lein self-install を実行します.

C:\lein\bin>lein self-install
Downloading Leiningen now...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   408    0   408    0     0    357      0 --:--:--  0:00:01 --:--:--   457
100 14.5M  100 14.5M    0     0  34521      0  0:07:22  0:07:22 --:--:-- 38828
        1 個のファイルを移動しました。

このように表示されれば成功です! 
ダウンロード終了まで結構時間かかりますので,その間にお茶でもどうぞ.完了したら lein repl と打って REPL を起動してみましょう.

C:\lein\bin>lein repl
nREPL server started on port 56171 on host 127.0.0.1 - nrepl://127.0.0.1:56171
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) Client VM 1.8.0_31-b13
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=>

やったー REPL が起動した!……遅い! REPL が立ち上がるまで 15 秒もかかっている! タブレット PC だからかな?

それでもうまくいかないとき 1

上記の方法でもうまくいかない場合は bin フォルダ内にある lein.bat ファイルを直接書き換えてみます.

まず適当なエディタで lein.bat を開き,次の部分を探してください.

lein.batの一部
call curl --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    rem We set CURL_PROXY to a space character below to pose as a no-op argument
    set CURL_PROXY= 
    if NOT "x%HTTPS_PROXY%" == "x" set CURL_PROXY="-x %HTTPS_PROXY%"
    call curl %CURL_PROXY% -f -L -o  %1 %2
    goto EOF
)

ここの六行目を次のように書き換えてください.

lein.batの一部
call curl --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    rem We set CURL_PROXY to a space character below to pose as a no-op argument
    set CURL_PROXY= 
    if NOT "x%HTTPS_PROXY%" == "x" set CURL_PROXY="-x %HTTPS_PROXY%"
    call curl %CURL_PROXY% -f -L -o  %1 %2 --cacert curl-ca-bundle.crt
    goto EOF
)

あとは同様に lein self-install を試してみてください.だいたいこれでなんとかなります.

それでもうまくいかないとき 2

もしこれでもだめならば,さらに次のように書き換えてみてください.

lein.batの一部
call curl --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    rem We set CURL_PROXY to a space character below to pose as a no-op argument
    set CURL_PROXY= 
    if NOT "x%HTTPS_PROXY%" == "x" set CURL_PROXY="-x %HTTPS_PROXY%"
    call curl %CURL_PROXY% -f -L -o  %1 %2 --insecure
    goto EOF
)

ただし,--insecure フラグは insecure (安全でない) の名の通り,証明書を使わないで通信を行うのであまり好ましくありません……たぶん.

エラーメッセージがなんか違うんだけど? というとき (Wget)

lein self-install を行ったとき,デフォルトでは cURL というツールを用いてファイルをダウンロードしてきます.しかし,PC に Wget という別のツールが入っているとそちらを使ってダウンロードしようとすることがあります.

Wget を使う場合でも同様に証明書を用意するか insecure 指定することでダウンロードできますが,今回は cURL を使ってダウンロードすることにするので,lein.bat から wget の部分を削除します.

具体的には,まず適当なエディタで lein.bat を開き,次の部分を探してください.

lein.batの一部
:DownloadFile
rem parameters: TargetFileName Address
if NOT "x%HTTP_CLIENT%" == "x" (
    %HTTP_CLIENT% %1 %2
    goto EOF
)
call wget --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    call wget -O %1 %2
    goto EOF
)
call curl --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    rem We set CURL_PROXY to a space character below to pose as a no-op argument
    set CURL_PROXY= 
    if NOT "x%HTTPS_PROXY%" == "x" set CURL_PROXY="-x %HTTPS_PROXY%"
    call curl %CURL_PROXY% -f -L -o  %1 %2
    goto EOF
)

ここの真ん中 5 行をまるまる削除し,次のようにして保存してください.

lein.batの一部
:DownloadFile
rem parameters: TargetFileName Address
if NOT "x%HTTP_CLIENT%" == "x" (
    %HTTP_CLIENT% %1 %2
    goto EOF
)
call curl --help >nul 2>&1
if NOT ERRORLEVEL 1 (
    rem We set CURL_PROXY to a space character below to pose as a no-op argument
    set CURL_PROXY= 
    if NOT "x%HTTPS_PROXY%" == "x" set CURL_PROXY="-x %HTTPS_PROXY%"
    call curl %CURL_PROXY% -f -L -o  %1 %2
    goto EOF
)

この後の処理は「SSL certificate problem の解決法 (cURL)」と一緒で,_curlrc ファイルを作るか lein.bat をさらに書き換えます.

最終手段

どうしてもうまくいかない場合,ブラウザから直接ファイルをダウンロードしてくるという手があります.エラーメッセージの最後に

Failed to download https://github.com/technomancy/leiningen/releases/download/2.5.1/leiningen-2.5.1-standalone.zip

とダウンロード先の URL があるので,ブラウザから https://github.com/technomancy/leiningen/releases/download/2.5.1/leiningen-2.5.1-standalone.zip にアクセスして直接ダウンロードします.

ブラウザ経由でダウンロードしたファイルを,Leiningen をインストールしたフォルダ内の self-installs の中に置きます.

この段階ではダウンロードしたファイルは ZIP ファイルになっていると思いますが,拡張子を .zip から .jar に変更します (JAR ファイルの正体は,ZIP だったんだよ!!).

self-installs

ここまで終わったらもう一度 lein repl してみて下さい.
これでもダメだったならば……僕より詳しい人に聞いてください……

REPL で遊ぶ

Hello, World!

REPL
user=> (println "Hello, World!")
Hello, World!
nil
user=> (+ 10 (* 20 3))
70

ファイルのロード

test.clj
(defn sayHello [name]
  (println "Hello," name))
REPL
user=> (load-file "test.clj")
#'user/sayHello
user=> (sayHello "Tom")
Hello, Tom
nil

コラッツ数列

collatz.clj
(defn make-collatz [result n]
  (let [nres (conj result n)]
    (cond (= n 1) nres
          (even? n) (recur nres (/ n 2))
          :else (recur nres (inc (* n 3))))))

(defn collatz [n]
  (make-collatz [] n))
REPL
user=> (load-file "collatz.clj")
#'user/collatz
user=> (collatz 7)
[7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1]
user=> (collatz 27)
[27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 4623 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1]

REPL の終了

REPL
user=> (quit)
Bye for now!

参考

WindowsでClojure環境構築した - Qiita
JDKのインストール(Windows)と Java 関連用語の説明 | プログラマーズ雑記帳
Clojure, Leiningen の Windows へのインストールと使い方 | プログラマーズ雑記帳
Clojure: LeiningenのWindowsインストール - from The Edge of the (Java) World