宣言していた通り、Clojure+Leiningenでやや簡単にGAEアプリをつくれるようにしてみました。
blankプロジェクトはこちら。
Compojureは最新の0.4.0のスナップショットをjarに固めてClojarsにおきました。
leiningenのインストールがまだの場合はこちらを参考にインストールしてください。
Google App Engine SDKを用意していない場合はここからDLしてきてbinディレクトリをパスに追加してください。いまのところ1.3.1対応です(appengine-java-sdk-1.3.1.zip)
$ git clone git://github.com/making/clj-gae-blank.git $ cd clj-gae-blank $ lein compile # 開発版サーバ起動 $ dev_appserver war # -> http://localhost:8080/にアクセスすると「Hello!」と出るはず。 # 本番環境へデプロイ $ vi war/WEB-INF/appengine-web.xml # applicationタグ内に自分のAPPIDを記入 $ appcfg.sh update war # -> http://APPID.appspot.com/にアクセスすると「Hello!」と出るはず。
あとはソースみていじってください。コードは数行しか書いてないから雰囲気でわかると思います。
lein replでwar/WEB-INF/classes, libにパスが通っていないみたいなので、projectホームに、シンボリックリンクを貼った方が良いです。ln -s war/WEB-INF/classes,ln -s war/WEB-INF/lib。lein-swakを使う場合も同様。
Created at : 2010-03-22 06:15:56
Updated at : 2010-03-22 06:31:06
Category : Programming::Lisp::Clojure::Leiningen
1.1.0がリリースされ少し仕様が変わったみたいです。当分は1.0.1で様子見します(2010/02/22)
→調査状況(2010/03/21):
どうもproject.cljの:mainに指定したnamespaceの.cljファイル(およびそこからuseされているファイル)のみコンパイルされる模様。。lein newでは:main入っていないし、何か変じゃないかな?
最新(安定)版は1.1.0(最終更新日時点)
$ wget http://github.com/technomancy/leiningen/raw/stable/bin/lein $ sudo install -m 755 lein /usr/local/bin/ $ lein self-install
$ wget http://github.com/technomancy/leiningen/tarball/1.0.1 $ tar xzvf technomancy-leiningen-fb13db7.tar.gz $ sudo install -m 755 technomancy-leiningen-fb13db7/bin/lein /usr/local/bin/ $ lein self-install
Created at : 2010-02-01 01:25:23
Updated at : 2010-03-21 02:34:41
Category : Programming::Lisp::Clojure::Leiningen
Hadoopの簡単なサンプルをClojureで書いてみました。leiningenでビルドするとらくちんでした!
leiningen 1.1.0対応しました(2010/03/10)
サンプルコードはオライリーのHadoop本、例2-6。Java版はこちら。
(defproject clj-max-temperature "0.1.0-SNAPSHOT"
:description "Sample of Hadoop on Clojure"
:dependencies [[org.clojure/clojure "1.1.0"]
[org.clojure/clojure-contrib "1.1.0"]
[org.apache.mahout.hadoop/hadoop-core "0.20.1"]
;; ここから先は全部必要か分からない
[commons-cli/commons-cli "1.2"]
[commons-codec/commons-codec "1.3"]
[commons-el/commons-el "1.0"]
[commons-httpclient/commons-httpclient "3.0.1"]
[commons-logging/commons-logging "1.0.4"]
[commons-logging/commons-logging-api "1.0.4"]
[commons-net/commons-net "1.4.1"]]
:dev-dependencies [[leiningen/lein-swank "1.1.0"]]
:main clj_max_temperature)
(ns clj_max_temperature
(:gen-class)
(:import (org.apache.hadoop.fs Path)
(org.apache.hadoop.io IntWritable LongWritable Text)
(org.apache.hadoop.mapreduce Job Mapper Mapper$Context Reducer Reducer$Context)
(org.apache.hadoop.mapreduce.lib.input FileInputFormat)
(org.apache.hadoop.mapreduce.lib.output FileOutputFormat)))
(gen-class
:name clj_max_temperature.mapper
:extends org.apache.hadoop.mapreduce.Mapper
:prefix "mapper-")
(defn mapper-map [this key value #^Mapper$Context context]
(let [line (str value)
year (.substring line 15 19)
quality (.substring line 92 93)
air-temperature (Integer/valueOf
(.substring line
(if (= (.charAt line 87) \+) 88 87)
92))]
(if (and (not (= air-temperature 9999))
(.matches quality "[01459]"))
(.write context (Text. year) (IntWritable. air-temperature)))))
(gen-class
:name clj_max_temperature.reducer
:extends org.apache.hadoop.mapreduce.Reducer
:prefix "reducer-")
(defn reducer-reduce [this key #^Iterable values #^Reducer$Context context]
(.write context key (IntWritable. (reduce max (map #(.get %) values)))))
(defn -main [& args]
(when (not (= (count args) 2))
(.println System/err "args error!")
(System/exit -1))
(let [job (Job.)]
(FileInputFormat/addInputPath job (Path. (nth args 0)))
(FileOutputFormat/setOutputPath job (Path. (nth args 1)))
(doto job
;; リテラルで現在のクラスの取り方が分からない。。。
(.setJarByClass (Class/forName "clj_max_temperature"))
(.setMapperClass (Class/forName "clj_max_temperature.mapper"))
(.setReducerClass (Class/forName "clj_max_temperature.reducer"))
(.setOutputKeyClass Text)
(.setOutputValueClass IntWritable))
(System/exit (if (.waitForCompletion job true) 0 1))))
Reducerの中でmap/reduce使ってるのがいけてるでしょ!
プロジェクトはこちら
$ git clone git://github.com/making/clj-max-temperature.git $ cd clj-max-temperature
$ lein compile # uberjarだけでcompileも行われるが、コンパイルエラーが発生してもjar作成に進むので開発時は別に実行した方が良い $ lein uberjar $ hadoop jar clj-max-temperature-standalone.jar input/sample.txt output
でおk。(スタンドアローンモードでのみ確認)
スタンドアローンなら、Hadoopをインストールしなくても
$ java -Xmx1000m -jar clj-max-temperature-standalone.jar input/sample.txt output
だけでもおk。簡単な動作確認に良さそう。
もっとMapReduceを使いやすくなるマクロをつくりたいね。
こんなのももうあるけど。
Created at : 2010-02-22 03:21:30
Updated at : 2010-03-20 04:54:16
Category : Programming::Lisp::Clojure::Leiningen