2011年11月8日火曜日

WindowsでLeiningen behind a proxy


JavaEE勉強会でProgramming Clojureを読んではいるものの、途中不参加だった時期もあり、いまいち身についている感がない。このまま終わってしまうのもアレなので、Webアプリでも作ってもう少し慣れようなどと思い立つ。仕事で時間ができた時に少しずつさわることを想定して、Windows上で環境構築をはじめることにした。

まずはNoirフレームワークで
Webで調べてみたところ、Clojure用フレームワークとしてはCompojureが有名っぽい。そういえば、JavaEE勉強会の角田さんによる発表で、Heroku+CompojureでWebアプリを作っていたような気がする。しかし、社内からはProxyの問題でHerokuが使えないことは確認済み。同じ構成だとHerokuに上げたくなって悔しくなりそう。違うフレームワークを探してみたところ、Noirというものを見つけた。シンプルなWebフレームワークらしいので、まずはNoir向けに環境を作って動かしてみよう。
# と思ったら、NoirはCompojure+Ring上に構築されてるらしいです

Leiningenインストール
lein-noirというプラグインを使えばNoir関連の依存ライブラリをインストールしてくれるらしいので、Leiningenからインストールする。現在の最新バージョンは1.6.1.1。LeiningenのGithubからlein.batをダウンロードし、Pathの通った場所に置いてから
lein self-install
すればOK。ただし、Path上にWget.exeがない場合は leiningen-x.x.x.x-standalone.jar がダウンロードできずに怒られるので注意。この辺りは親切にも、lein self-install のエラーメッセージにダウンロード先を含めて書いてあるので問題ないとは思う。
Proxy環境の人なら、環境変数にhttp_proxyを設定すればOK。認証ありでも同じく環境変数を設定すれば問題なし。

lein-noirインストール
最新のバージョンは1.2.1。以下のコマンドでOK…のはずだった。
lein plugin install lein-noir 1.2.1
しかし、あえなくエラー発生。リポジトリ上にlein-noir-1.2.1.jarが見つからないらしい。ブラウザからclojars.org/repo に行って確認したところ、JARはきちんと存在している。
D:\>lein plugin install lein-noir 1.2.1
Exception in thread "main" org.apache.maven.artifact.resolver.ArtifactNotFoundEx
ception: Unable to download the artifact from any repository
Try downloading the file manually from the project website.
Then, install it using the command:
    mvn install:install-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversio
n=1.2.1 -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
    mvn deploy:deploy-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversion=
1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

  lein-noir:lein-noir:jar:1.2.1
from the specified remote repositories:
  clojars (http://clojars.org/repo/),
  central (http://repo1.maven.org/maven2)
 (NO_SOURCE_FILE:0)
        at clojure.lang.Compiler.eval(Compiler.java:5440)
        at clojure.lang.Compiler.eval(Compiler.java:5391)
        at clojure.core$eval.invoke(core.clj:2382)
        at clojure.main$eval_opt.invoke(main.clj:235)
        at clojure.main$initialize.invoke(main.clj:254)
        at clojure.main$script_opt.invoke(main.clj:270)
        at clojure.main$main.doInvoke(main.clj:354)
        at clojure.lang.RestFn.invoke(RestFn.java:551)
        at clojure.lang.Var.invoke(Var.java:390)
        at clojure.lang.AFn.applyToHelper(AFn.java:193)
        at clojure.lang.Var.applyTo(Var.java:482)
        at clojure.main.main(main.java:37)
Caused by: org.apache.maven.artifact.resolver.ArtifactNotFoundException: Unable
to download the artifact from any repository
Try downloading the file manually from the project website.
Then, install it using the command:
    mvn install:install-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversio
n=1.2.1 -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
    mvn deploy:deploy-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversion=
1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

  lein-noir:lein-noir:jar:1.2.1
from the specified remote repositories:
  clojars (http://clojars.org/repo/),
  central (http://repo1.maven.org/maven2)

        at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(De
faultArtifactResolver.java:212)
        at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolveAlw
ays(DefaultArtifactResolver.java:80)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:90)
        at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
        at leiningen.install$standalone_download.invoke(install.clj:39)
        at leiningen.install$install.invoke(install.clj:62)
        at leiningen.plugin$install.invoke(plugin.clj:32)
        at leiningen.plugin$plugin.invoke(plugin.clj:75)
        at clojure.lang.Var.invoke(Var.java:373)
        at clojure.lang.AFn.applyToHelper(AFn.java:167)
        at clojure.lang.Var.applyTo(Var.java:482)
        at clojure.core$apply.invoke(core.clj:540)
        at leiningen.core$apply_task.invoke(core.clj:229)
        at leiningen.core$_main.doInvoke(core.clj:294)
        at clojure.lang.RestFn.applyTo(RestFn.java:139)
        at clojure.core$apply.invoke(core.clj:542)
        at leiningen.core$_main.invoke(core.clj:297)
        at user$eval42.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(Compiler.java:5424)
        ... 11 more
Caused by: org.apache.maven.wagon.ResourceDoesNotExistException: Unable to downl
oad the artifact from any repository
        at org.apache.maven.artifact.manager.DefaultWagonManager.getArtifact(Def
aultWagonManager.java:332)
        at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(De
faultArtifactResolver.java:200)
        ... 33 more
どうやら内部的にはMavenを使っているようなので、 ~/.m2/settings.xmlにproxy設定を追加してみたが状況は変わらず。ちなみに、プロキシがローカルホストなのは、NTLM認証が面倒なのでローカルプロキシを入れているため。

<settings>
  <proxies>
   <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>localhost</host>
      <port>9090</port>
    </proxy>
  </proxies>
</settings>

切り分けのためにMaven3をインストールし、切り分け用のpom.xmlを作って depenencies に lein-noir 1.2.1 を追加。リポジトリにも clojars を追加してから mvn compile を叩くと、正常にダウンロードが完了した。この後再び lein plugin install lein-noir 1.2.1 と叩くと、無事にインストールが完了したらしい。謎。
lein plugin install lein-noir 1.2.1
Copying 1 file to C:\DOCUME~1\....~1\LOCALS~1\Temp\lein-c7edc836-8953-4a2b-b0e
0-830eeeaa1ad0\lib
Including lein-noir-1.2.1.jar
Including clojure-1.2.1.jar
Created lein-noir-1.2.1.jar
Noirプロジェクト作成
LeiningenでNoirプロジェクトを作成。
lein noir new samplenoir
Creating noir project:  samplenoir
Creating new dirs at:  D:\...\projects\clojure\samplenoir
Adding files...
Project created!
プロジェクトディレクトリに移動してlein runでサーバが起動してデフォルトアプリケーションが利用可能になる。
lein run
Downloading: org/clojure/clojure/1.3.0/clojure-1.3.0.pom from central
Downloading: org/sonatype/oss/oss-parent/5/oss-parent-5.pom from central
Downloading: noir/noir/1.2.1/noir-1.2.1.pom from central
Downloading: noir/noir/1.2.1/noir-1.2.1.pom from clojars
- 中略 -
Downloading: org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar from clojars
Downloading: org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar from central
Copying 31 files to D:\watanabeknt\projects\clojure\samplenoir\lib
Starting server...
2011-11-08 15:00:00.098:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2011-11-08 15:00:00.098:INFO::jetty-6.1.25
2011-11-08 15:00:00.238:INFO::Started SocketConnector@0.0.0.0:8080
Server started on port [8080].
You can view the site at http://localhost:8080
#<Server Server@1f02b85>
普通に依存ライブラリをダウンロードできているっぽいんですけど、さっきは何がダメだったのだろう?

Noirアプリケーションにアクセス
コンソールに表示されているとおり、localhost:8080にアクセスすればデフォルトページが表示される。ここには、簡単なサンプルとともに、チュートリアルへのリンクが表示されている。

(defpage "/my-page" [] (html [:h1 "This is my first page!"]))

あれ?なんかあんま好きじゃない感じの記法なんですけど…。なんか昔Javaでこんないけてないライブラリがあったようななかったような。
一区切りついて気に入らなかったら、結局Compojureに行ってしまうかもしれない…。

次は、Noirのチュートリアルと、エディタの整備をやりたい。エディタは、CounterclockwiseかClojureboxどちらかの予定。Emacsとは仲良くなれなかったのでCounterclockwiseが有力。