Debian提供のclojureパッケージを使ってみる

## 動機
Clojureで開発するときには、常々、boot-cljを使ってきて、Debianが提供しているclojureパッケージは使ったことはなかったが、ちょっとした小物をつくるときに、いちいちboot-cljでプロジェクトをつくったり、拾ってきたjarファイルや/usr/share/java内にあるライブラリを自分のmavenのリポジトリにインストールするのが面倒なので、Debianで提供のものを使ったやり方をまとめておく。

## 手順

##### インストール
```shell
$ sudo apt install clojure
```
適当にスクリプトっぽく書く。 (ここでいうスクリプトっぽくというのは 名前空間の設定をしないという意味)

#### test.clj

```clojure
(println "Hello")
```

実行する。

##### コマンド
```shell
$ clojure test.clj
Hello
```

他のライブラリを使いたいときは、"-cp"でクラスパスを追加してあげる。
JVMにプロパティを渡したい時は、System/setPropertyでコードの中で設定する。
(clojureアプリのコマンドラインとして一度受けとってからsetPropertyで渡すことはできるので、最悪そうする。/usr/bin/clojureの実装上、JVMに直接-Dオプションで渡せない)

試しに何の得にもならないが、ClojureからJythonを使ってPythonコードが実行できるようにしてみる。 事前にjythonをaptでインストールしておく。

```shell
$ sudo apt install jython
```
コードを以下のように書き変える。

##### test.clj rev. 2

```clojure
(import '[org.python.util jython])

(System/setProperty "python.home" "/usr/share/jython")
(System/setProperty "python.path" "/usr/share/jython/Lib")
(System/setProperty "python.executable" "/usr/bin/jython")
(System/setProperty "python.console" "org.python.util.JLineConsole")

(jython/main (into-array String *command-line-args*))
```

##### コマンド

```shell
$ clojure -cp /usr/share/java/jython.jar:$PWD test.clj
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper$ReflectiveAccess (file:/usr/share/java/jnr-posix.jar) to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper$ReflectiveAccess
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Jython 2.7.1 (, Oct 22 2017, 13:43:00) 
[OpenJDK 64-Bit Server VM (Oracle Corporation)] on java11
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello")
Hello
>>> 
```
WARNINGはjython由来なものなので無視するとして、コマンドの引数にpythonのコードを渡してみる。

##### hello.py
```python
print("Hello in a file")
```
##### コマンド
```shell
$ clojure -cp /usr/share/java/jython.jar:$PWD test.clj hello.py
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper$ReflectiveAccess (file:/usr/share/java/jnr-posix.jar) to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper$ReflectiveAccess
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Hello in a file
```

のちのち他のコードと混ぜて使いたい時があるかもしれない場合は、名前空間を付与しておく。

##### test.clj rev.3
```clojure
(ns test
  (:import [org.python.util jython]))

(defn launch-python [args]
  (System/setProperty "python.home" "/usr/share/jython")
  (System/setProperty "python.path" "/usr/share/jython/Lib")
  (System/setProperty "python.executable" "/usr/bin/jython")
  (System/setProperty "python.console" "org.python.util.JLineConsole")
  (jython/main (into-array String args)))

(defn -main [& args]
  (launch-python *command-line-args*))
```

##### コマンド
```shell
$ clojure -cp /usr/share/java/jython.jar:$PWD -m test hello.py
```
rev.2の時と違うのが、コマンドで "-m"オプションにて-main関数がある名前空間を渡しているところで、Javaのクラス探索規則に従ってクラスパスからtest.clj (もしくは該当の初期化クラス)を探索する。ここでは、カレントディレクトリをクラスパスに指定しているのでtest.cljが発見される。

最後に他の人に渡すときはcljファイルをjarでまとめる。

```shell
$ jar cf from-me.jar *.clj
```

作成したjarを渡してクラスパスに通して実行する。

```shell
$ clojure -cp /usr/share/java/jython.jar:from-me.jar -m test hello.py
```

## おわりに
JVMの起動時間の遅さも、昔に比べれば、まだ待てる範囲になったので、ちょっとした小物作成の時はこのやり方でやってみる。