ラベル Gradle の投稿を表示しています。 すべての投稿を表示
ラベル Gradle の投稿を表示しています。 すべての投稿を表示

2013年3月16日土曜日

G*ワークショップZ Mar 2013 に参加してきた #jggug

みけです。

昨日確定申告の書類を中野税務署に提出したら、

ちょうど中野税務署の門が閉じたところでした。

ギリギリセーフ。


そのあと行って来ました。


G*ワークショップZ Mar 2013 Gradleハンズオン


内容はgithubにあるので、そちらを参考にどうぞ。

https://github.com/nobusue/GradleHandson


あとツイッターの実況中継はまとめられています。

2013/03/15(#jggug)G*ワークショップZ Mar 2013

最近はまとめ職人が洗練されてきていますねw


で、おまいは何をやってたんだ?


何も特にしていないです。

とりあえず、gradleにhelloWorkタスク作って

「hello work」というビルドスクリプト作りました。


毛虫本




Gradle Effective Implementation Guide

この本、翻訳やりたいです。

一ヶ月でやるので、どなたか出版社の人を紹介してくだされ~。



おわり

2013年2月4日月曜日

json-pull-parserをIntelliJ IDEAに適用するためのbuild.gradle

こんばんわ。

みけです。

女医さんがかわいいんですよ。

次回の問診の時には、もっとアプローチしようと思います。

青春だなぁ…

annotation processorの設定


まあ、別にIntelliJ IDEAでannotation processorの設定をするのは、

面倒ではないので、アレですが…

gradlerたるもの、なんでもgradleでできないと、嫌なんです。


というわけで、vvakame氏json-pull-parser

IntelliJ IDEAでも使えるように

build.gradleを記述しました。





ただ、これ結構やっつけで作っているので、

まだ、コンパイルを通すのにいろいろと付け加えなければいけません。

まあ、とりあえず、今日はここまでということで。

明日も女医さんに逢いたいなー!!!!

(2013/02/05 5:39 追記)

修正して、IntelliJ IDEAでもGradleでもビルドできるようにしました。

Pluggable Annotation Processor APIはコンパイルパスに加えておけば、

後の処理は良い感じにやってくれます。

ただ、IntelliJにて生成したコードをGradleコンパイル時に残しておくと、

コンパイルエラーが発生するので、

(IntelliJで生成したソースファイルと
コンパイル時に生成したソースファイルが
同じものなのでコンフリクトする)

コンパイル前にIntelliJで生成した方のコードを

削除するようにしてあります。

一応、IntelliJ IDEAでコード生成する方法


eclなんとかと違って、

ファイル保存操作のないIntelliJですが、

コードを生成する場合は、

明示的にコンパイルするという操作が必要になります。




Gradleでビルドするときの注意


特にないです。




終わり

p.s. vvakame氏〜Java1.7にも対応してくだされ〜〜

2012年12月31日月曜日

gradlebについて

今年(2012年)最後のエントリーになります。

みけです。

Gradleをいつも推していますが、

build.gradleがいつも同じ事ばっかり書いている気がしたので、

gradle builder 略して、gradlebを書いてみました。

aliasにalias gradleb = 'groovy /path/to/gradleb.groovy'

設定しておいて、下のように叩くと、プロジェクト構造とbuild.gradleが生成されます。

$ gradleb  -g org.mikeneck.gradleb.sample -j 1.7 -p sample-web -v 0.1 -a jetty,groovy,idea -d groovy/org.codehaus.groovy:groovy-all:2.0.5,compile/org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.2.Final,compile/org.springframework:spring-core:3.1.2.RELEASE,testCompile/junit:junit:4.11

apply plugin : 'java'
apply plugin : 'jetty'
apply plugin : 'groovy'
apply plugin : 'idea'

group = 'org.mikeneck.gradleb.sample'
version = '0.1'
sourceCompatibility = '1.7'
targetCompatibility = '1.7'

repositories {
    mavenCentral ()
}
dependencies {
    groovy 'org.codehaus.groovy:groovy-all:2.0.5'
    compile 'org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.2.Final'
    compile 'org.springframework:spring-core:3.1.2.RELEASE'
    testCompile 'junit:junit:4.11'
}

スクリプトなので、荒削りな部分はありますが、

簡単にビルドスクリプトが書けます。



2012年8月17日金曜日

Graffiti のmaven repo登録

暑い、

ドラクエのレベル上げルのきつい

ミケです。


Groovyにおけるsinatra



以前、上原さんがこんな記事を書いていました。

[groovy][Graffiti]さらにもう一つのGroovyベースのSinatraライクwebアプリフレームワーク Graffiti - Grな日々(uehajの日記)

よさそうだなと思って、早速使ってみようと思ったのですが…


Maven Centralにartifactが載っていない…orz


Gradleでのビルド化



う~む、どうするべきかと考えていたおり、

一応ソースがgithubにあるということなので、

見てみました。


げ、pom.xml…しかもreleaseプラグインとか一切なし…

かといって、僕もmaven詳しくないからな…


そうだ、gradleがあるじゃん。

というわけで、ビルドをGradleで書き換えて、

pullリクエストを送りました。


あっさりと…



マージしてもらえました。

その後、Kerry Wilsonさん(graffitiの開発者)からメールを頂いて、

pom.xmlとbuild.gradle使うのはどっちがいいのよ?

的な話になり、Groovy使いならGradleだよね~という話をしました。


maven centralにあげないの?


こちらでMaven Centralにあげないの?

と聞いたら、上げる予定はないようなので、

面倒くさくて、

僕の名前でmaven centralにあげちゃいました。

groupId org.mikeneck.graffiti
artifactId mike-graffiti-core
version 1.0.0

で入手できます。たぶん。

ゆーすけさんのページとか

わかめのページとか

参考にしました。

2012年7月18日水曜日

Gradle カスタムプラグイン作ってみた

あ゛ぢ゛い゛

みけです。

某java-jaのイベントにて




ということが話題に上がったので、

そういえば作っていないな(白目

って、ことで、いつも面倒な.gitignoreファイルを

Gradleのプラグインから類推して作り出す

プラグインを作ろうと思った。


参考サイト


参考サイトといえば、@bluepapa32さんのブログがとにかく秀逸!

プロパティファイルを native2ascii するためのプラグインを作ってみた

Gradle のカスタムプラグインを JAR ファイルで公開する方法

これと後は、gradle-gae-pluginのgithubを参考にしました。


build.gradle


build.gradleはこんな感じ。




coreというモジュールのdependencyに、gradleApi()とあります。

こいつが、カスタムプラグインを作る時のミソです。


プラグインの本体はcore/src/main/groovy/og/mikeneck/gradle/git/GitIgnorePlugin.groovyというファイルになります。



このコードのproject.task('git-ignore')という部分によって、

タスクgit-ignoreというタスクが作成されます。

あと、プラグインの名前ですが、core/src/main/resources/META-INF/gradle-plugins/gitignore.propertiesというファイルの

ファイル名でプラグイン名が決定されます。

この場合だと、
apply plugin : 'gitignore'

で、利用することができます。


勉強会


まあ、このあたりのことは明日(2012/07/19)の勉強会にて話します。


目標


大したプラグインではありませんが、

Sonatype OSS Maven Repositoryに載せたいと思います。


2012年5月3日木曜日

#shikadriven 鹿駆動勉強会に行ってきた、しゃべってきた

4/29に鹿駆動勉強会に行って来ました。

鹿駆動ってなんぞ?という人はあまりいないでしょうが、

一応、説明しておくと、

奈良で勉強会が開催されないので、

勢いで開催しちゃいました!しかも、能楽堂で!

って感じの勉強会です。

詳しくはこちら


参加者のブログはいろいろとあるようです。

ITとともに生きよう - 「鹿駆動 勉強会 参加してきた #shikadriven」

人生、気合いと具合 - blog - 鹿駆動勉強会(4/29)

システムアーキテクトのごった煮 - 鹿駆動勉強会で人生初LTしました!

koeだめ - 鹿駆動勉強会で奈良時代の技術について話をしてきた #shikadriven

他多数…

togetterにもまとめができております。


実は、自分も発表してきました。

資料はこちらになります。



まあ、タイトルはJavaFXとJavascriptになっていますが、

中身はコンパイルのためのDIコンテナの話です。

GradleのコンパイルモデルはJavaをコンパイル→Groovyをコンパイルという順番なので、

JavaがGroovyの実装に依存している場合は、

コンパイルエラーが発生するというものです。

これを避けるために、インターフェースから実装クラスを指定できるようなものが欲しいと思って、

DIコンテナを作りました。

というところまで話したかったけど、

まあ、全くもって話できませんでしたね。


なお、作成したDIコンテナはこちらで公開しております。

https://github.com/mike-neck/gj-groovy-joint


しかし、皆さん、LTうまかったですな〜。

オレももっとLT訓練しないとと思った次第です。

2012年4月4日水曜日

gradle + IntelliJ IDEAでプロジェクトをGit管理下に置く方法

JavaOne初日の申し込んでいたセッションがすべて終わって、

おとなしくしているみけです。


プロジェクトをGit管理下に置く


git cloneしてbuild.gradleを落としてきたのに、

gradle ideaした後に、

IDEAにGitの管理下に置くかと聞かれるのは嫌ですよね?


そんなときこそ、gradleがあるわけで、

build.gradleファイルに次のような記述を追加しておけば、

いちいちそんなこと聞かれなくなります。






2012年4月1日日曜日

会社員、辞めました。

一応、今日は真面目モードで。

みけです。

TopGate、辞めました。


以前にもお伝えしたとおり、

昨日、3月31日を以って、

株式会社TopGateを退職いたしました。


社長の加藤昌樹氏、

Google API Expertの小川信一氏や、

Android全般に詳しいわかめまさひろ氏、

世界の揺下こと山下武志氏、

をはじめとする優秀な技術集団の一員として

いっしょに働けたことを誇りに思います。


会社員を辞める?


さて、これも私をTwitterでフォローしている方や、

ブログを読まれている方、

実際に私とお会いしたことのある方などには、

ご存知の方も多いと思いますが、

私は所謂普通の人と比べてみると、

ムラの多い人間であるようです。


実際、今冬の冬眠状態や、

今私が認識している睡眠相前進症候群状態を始めとして、

所謂普通の人と比べてメンタル面で

非常に奇異な特性を持っているようです。


そういった特性は認識しているのは

まあ、どうでもよくって???

問題は所謂普通の人との付き合い方にあります。


睡眠相がずれていくのは、

昼間、普通の人に対して資本が求める働きを

私は応えられないとか、

冬はほとんど成果が出せないなどという

問題をはらんでいます。


そのうえで、身体を普通の人に合わせるのか、

生活を身体に合わせるのかという問いを立てた時に、

私としては後者のほうを選択することにしました。


私自身としては、もし下記の条件でも雇っていただける会社があるなら、

お話だけは伺いたいと思っています。

  • 一日の勤務時間は6時間まで。延長は一切なし
  • 週の勤務日数は4日まで
  • 覚醒時間が常にずれていくので、自宅勤務可能
  • 夏季休暇はいらないですが、冬季休暇を3ヶ月いただける
  • Groovyをやらせていただける

おそらく、この条件を満たせるような会社はないと

思っていますので、

会社員を辞めるという決断をいたしました。


身体に合わせるという選択肢


私と同様に身体的な問題で成果を発揮できない状態で

いる人間というのは、

資本の側から見ると厄介な存在だと思う一方で、

その人間の側からしても資本の欲求に応えられないという

フラストレーションの溜まるものであります。


そのフラストレーションにより自身がなくなり、

またさらに成果を発揮できなくなって、

フラストレーションが溜まるという状態は、

おそらく私がこの30数年の間に何回も経験したものです。


いい加減、この課題に対して何らかのアクションを

取らないといけないわけで、

そのアクションとして、先程も記述しましたが、

生活を身体に合わせるという選択肢を採択することにしました。


個物と一般


もちろん、皆さんも自分の身体というのをご存知なわけで、

私のような選択をすることは、

「みんな頑張っているのに、なぜお前は…」

と言いたくなるところもあるでしょう。


私自身、このブログで幾度か表明していますが、

マルクスを信望しています。

マルクスの考え方というのは非常に徹底的なもので、

交換が成立しないなら価値はなかったという考え方は

非常に説得力があります。


マルクスの思想の背景には、

「個物はいかにして一般性を獲得するか」

という問題設定があるような気がします。


そうした個別唯物的な考え方に照らした時に、

「みんなが…」という社会主義的な考え方には

相容れないものがあります。


私は個物と一般という対立は無意味なものだと考えていて、

その両項の差異を明確にしていくという方法があるのではないかと思っています。


ちょっと最後の部分はうまく伝えられていない気がしますが…


欲望


経済的な行為であれ、なんであれ、

人間には欲望があって、欲望が行動のすべての源泉であると思います。


私も何かを動かすことや、何がどう動いていることを理解すること、

こういったことに非常に欲望を感じています。

(他にもありますけどね)


GroovyというJavaでできた言語が動いていることへの興味、

そして何かを動かせるという興味から

受け取る欲望の充足が非常に大きいということを私は感じています。


もっとこの欲望とその充足を満たしてみたいと思います。


そこで、以前表明したように

5月くらいには会社として登記できるように

会社を作ることにします。


計画


私はgradle_jaというコミュニティを立ち上げて、

gradleというGroovyのプロダクトの普及を当面やっていこうと思っています。

が、5月スタートアップに向けて4月はその準備、

そのあとは当面の資金稼ぎのためのサービス開発、

GrailsというGroovyのプロダクトの研究・調査、

Spring RooというJavaプロダクトの研究・調査、

という感じで一カ月を過ごしていこうと考えています。


以上、能書きが多かったと思いますが、

今後とも皆様よろしくお願いします。




2012年3月3日土曜日

Gradle + Groovy + Ideaをやってみよう

簡単なGradleのbuild.gradleファイルを作成してみた。

ビルドスクリプト


このbuildスクリプトはGoogle-guiceとh2データベースとjunitを入れるだけの簡単なプロジェクト。



読めば大体わかりますね。
javaとgroovyを使って、IntelliJ IDEAで開発できて、jarを最終的に吐き出すプロジェクトです。

GradleをMavenと比較して残念なところに、generate-archetypeみたいに、いい感じのディレクトリツリーを作ってくれるコマンドがないので、
とりあえず、ideaタスクの後に自作して強引に作るようにしています。


Tasks


Gradleでどのようなタスクがあるかを一覧表示します。



gradle tasksというコマンドがそれです。


プロジェクトの作成


では、ideaプロジェクトを作成しましょう。




gradle ideaコマンドとgradle structureコマンドを打つことでプロジェクトの構造が出来上がります。

実際にはideaタスクの後にstructureタスクを割りこませる方法があるんですが、忘れた…orz


プロジェクトの取り込み


では、作成したプロジェクトをideaで取り込みます。


Open Projectを選択します。

先程作成したgradle-study2.iprファイルを選択します。



こんな感じに依存性を解決したideaプロジェクトが作成されます。



GroovyでJUnit


JUnit4はPOJOまたはPOGOでできるので、GroovyでもJUnit4のテストを書けます。

では早速やってみましょう。

パッケージ作り忘れたので、src/test/groovyディレクトリで、[Alt + Insert]を押します。(MacではCtrl + n)




ここで「pa…」と入力すると、packageが選択できます。


適当にパッケージ名を入れましょう。



パッケージができたら、作成したパッケージのところでまたもや[Alt + Insert]。(MacではCtrl + n)

GroovyClassを選択します。



適当なので適当にクラス名を入れます。



早速、@Beforeから書いて行きましょう。



IDEAの素晴らしいところは、あの忌々しい[Ctrl + Space]を入れなくてもどんどん補完してくれる所




さらには依存性が解決している範囲で、あの忌々しい[Ctrl + 1]を入力しなくても、[Alt + Enter]で勝手にimport文を作ってくれるあたり。


なんか適当にlistとかいうフィールド、インスタンスを作ってみましたが、
これはフィールドとして設定しましょう。

listが初出の場所にカーソルを当てて、[Ctrl + Alt + f]、(Macの場合は[コマンド + alt + f])

でいい感じにフィールドを作成してくれます。



適度にスコープを選択して、defで割り当てましょう。


おもむろにテストを書いてみましょうか。

なんか、何もしていないのにアノテーションですら自動補完してくれます。



JUnit4をJavaでやるときはもちろん、org.junit.Assert.assertThatあたりを用いますが、
Groovyでテストをするときは、そんなもん使いません。

assertだけで十分です。


テストわざと間違えていますが…

テストを実行するのは、[alt + shift + F10]です。

何のテストを実行したいか選択して下さい。

メソッド単位で実行できます。



さて、実行結果です。
もちろんテスト間違えているので、どうなるか気になりますね。

テスト実行結果。



何がどういう値で、何が間違っているかがちゃんと表示されるんです。

これはGroovyだからできるんです。Power Assertと言います。

これはGroovyだからできるんです。Power Assertと言います。

大事な事ですから二度言いました。

これはGroovyだからできるんです。Power Assertと言います。


これがJUnitのassertThatなどだったら、expected<4> but got <3> くらいしか出してくれません。


この親切さ。これはGroovyだからできるんです。Power Assertと言います。


こいつはテストを直しておきます。



POJOのテスト


POJOもテストしましょう。もちろんテストはGroovyでやっちゃいます。


とりあえず、誰でも思いつきそうなPOJOでPersonというクラスを作ります。


メンバーはintのageとStringのfirstNameとlastNameです。

getterとsetter作らないとですね。


何もない所で、[alt + insert]を押します。(Mac版ちょっとど忘れ)



とりあえず、メンバー全部選択しましょう。



まあ、このあたりはeclipseでもやれるので、どうということはないですね。



じゃあ、テストを書きましょう。もちろんGroovyで。

Groovyでは特にコンストラクターが指定されていなければ、内部のフィールドに値を一気に代入させることができます。



ほんまかいな?と思うので、assertをかけてみましょう。




さ、テストを実行しましょう。


ほれ、ノープロブレム!!!!



Gradleに戻って


とりあえず、テストを落ちるようにしておきます。




では、gradleでテストを実行します。

テスト実行結果




さて、テストが2つコケたらしいですね。

では結果をhtmlファイルで見てみます。

これがレポートファイルです。


これらの詳細を見ることができます。




ちゃんとテストがどういう点が悪くてfailしたのか一目瞭然ですね。

というわけで、Gradle、あの複雑なpomを書かなくても、いい感じで、ココまでやってくれるのですから、今はAnt + Ivyだけどという人は是非トライしてみましょう。


2012年2月25日土曜日

Gradle、ちょっと面倒な所

どうも。

ビルドツールではGradleを一押ししているのですが、
まだまだ開発中故に残念なところがあるので、
そのメモです。

Dependencyの指定にGStringが使えない




プロジェクトの依存ライブラリーを指定するときに、
同じGroupIdで同じバージョンを使うときに、
プロパティを設けておいて、
それを利用する方がのちのち便利です。

Groovyの場合、文字を展開するのに便利なGStringクラスがあり、
変数を置き換える際にそれを利用します。

というわけで、dependencyの指定にはGStringを利用したいわけです。



上記のbuild.gradleでは、
GAEのバージョンやSlim3のバージョンをプロパティに設定して利用しているわけですが、
こんな感じのエラーが発生します。



GStringStringにキャストできないということらしいです。

対策


仕方が無いので、カッコ悪いですが、toString()メソッドを利用します。



これはソースを読んで、パッチでも送りましょうかね…

Windowsでの問題


Macなら多分問題はないと思いますが、
Windowsでやっていると、
文字コードの問題が出てきます。

これについては、@nobeansさん『豆無日記』「Gradleで文字エンコーディングを指定する方法」に詳しく書かれています。

先ほどのbuild.gradleでWindowsでコンパイルする場合、こんなエラーが出ます(コードページは932、ソースはUTF-8)。



@nobeansさんのページに書かれたとおりに修正するとこんな感じのbuild.gradleファイルになります。



これで、なんとかうまく走りました。



ココらへんは、今年中にmilestoneが30くらいまでになるというGradleですので、対策してくれるんじゃないかななどと勝手に期待してみたり…


追記:2012/02/25 8:45

@orange_cloverさんからアドバイスがあったページ
『設計と実装の狭間で。』の「[Gradle]Gradleで文字エンコーディングを指定する方法」に書いてあった方法でも
エンコーディングの指定が可能なようです。



ところが、ひとつだけ残念なところが…



IntelliJ IDEAの10.5だとエラーになってしまうんですよね…

もちろん実行できますが…


2012年2月22日水曜日

MavenからGradleに移行するただひとつの理由

MavenかGradleか?

この前の日曜日、MavenかGradleかといった論争がTLを賑わしていました。


Gradleがいいよとか、Mavenがいいよとか、Ivyだよとか、sbtだよとか、やっぱここは老舗のAntだとか…

Gradle一押しのオレの意見


MavenからGradleへ移行するたった一つの理由










それは











特にない




Mavenでちゃんとビルドができているプロジェクト、それでいいんじゃない。
それで顧客に価値が提供できているという時点で、Mavenは大きな貢献をしていると思います。

Gradleでビルドができているプロジェクト、それでいいんじゃない。
SpringとかHibernateなんかがそうです。
それで顧客に価値が提供できているという時点で、Gradleは大きな貢献をしていると思います。

だから、そういうプロジェクトがMavenからGradleへ無理に移行することもとくにないと思うし、GradleからMavenへも然り。

Mavenのpom.xml読みづらいけど、IntelliJ IDEAで読めば、結構読める。
そもそもpom.xmlわかりづらいっていう問題は、数カ月努力すれば読めるようになる。
これはオレの経験則から。
Antのbuild.xmlよりはわかりやすいですよ。pom.xml。


GradleやMavenを本当に導入するべきプロジェクトというのは、

開発者各自がjarとかzipとかをダウンロードしたり、特定の端末でないと商用ビルドができないとか、特定の担当者がいないとビルドができないとかそういう属人的、属端末的、個々人がバラバラ的なプロジェクト、そういうプロジェクトにこそ導入するべきだと思うわけです。

その意味で、
@ikeike443さんのツイート「ライブラリを探すのに未だにGoogleで検索して適当に見つかったものを手でダウンロードして、依存関係は手と目で一生懸命さがして解決して、みたいにやってる方いるもんなあ。プロダクションではまたバージョンの違う組み合わせのライブラリを使ってて動かないみたいな。」が最も的を得ていると思いました。


というわけで、多分世の中にたくさんあるであろう各自が勝手にライブラリーを落としてきて自分とこだけうまくいくようなプロジェクトにこそ、Mavenは導入してもらいたいし、Gradleは導入してもらいたい。

2012年2月19日日曜日

久々にAppEngineをやってみた。

まあ、以前も小川さんの『Slim3』本を写経していましたが、かなり忘れていたっていうのもあるので、写経しました。

だいぶAppEngineのバージョンも上がっており、
色々と気になるところはありますが、
まだまだ情弱なオレのことですので、
基本をもう一回みっちりと叩きこんでおきたいと思います。

使用した環境は以下のとおりです。

  • IDE : IntelliJ IDEA 10.5
  • Google AppEngine 1.6.2.1
  • Slim3 1.0.15
  • maven 3.0.4
  • gradle-milestone-8

一応必要そうな依存性はpom.xmlで集めましたが、
ここは、小川さん、わかめが嫌いそうなGradleでやって見ることにします。

なお、今回はテストはChapter5-Section3-example1のコードを少し改造してやっています。

まずは、pom.xml



長いです。

pom.xml情弱のオレには辛かったです。
この編は小川さんのサポートがないと生きていけません。

これをbuild.gradleで書きなおしてみました。



テストコードはこんな感じです。



Gradleでの実行結果はこんな感じです。



mavenでの実行結果はこんな感じです。




maven情弱のオレにはmavenは敷居が高すぎましたorz


2011年12月12日月曜日

恥ずかしくて今さら聞けない、GMongo講座 1

さて、昨日は恥ずかしくて今さら聞けない、mongodb講座 1などというものを書いたわけですが、今日は

恥ずかしくて今さら聞けない、GMongo講座 1


です。

みなさんお間違えのないようにお願いします。

GMongoって何ぞ?という方もいると思いますので、とりあえず、簡単に説明すると、

Groovyからmongodbにつなげるthin ドライバーです。

もっと詳しく知りたい?ググレカスりましょう。

導入

GitHubのアドレスはhttps://github.com/poiati/gmongoです。

ここからzipダウンロードしてpathを通してやってください。

なお、このライブラリーは標準のmavenリポジトリーにも登録されています。
mavenから使いたい場合は、次のように記述すると使えます。

    <dependencies>
        <dependency>
            <groupId>com.gmongo</groupId>
            <artifactId>gmongo</artifactId>
            <version>0.9.2</version>
        </dependency>
    </dependencies>


おっと、私のように頭がゆとり系の人にはmavenなんて難しいことを書いてはダメでした。

@Grapesでは次のような感じです。

@Grapes(
 @Grab(group='com.gmongo', module='gmongo', version='0.9.2')
)


Gradleでは次のような感じになります。

repositories {
    mavenCentral()
}

dependencies {
    groovy : 'com.gmongo:gmongo:0.9.2'
}


ちなみにJavaとの親和性の高いGroovyですから、Groovyで書かれたライブラリを使ってJavaで開発なんてこともできると思います(テキトー)

では、昨日と同じような感じで使ってみたいと思います。

クライアント起動インスタンス化


ホスト名とポート番号を渡してやるだけでインスタンス化できます。
MongoTest.groovy

import com.gmongo.GMongo
import org.junit.Before

    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
    }


これだけで、mongodbとの接続が完了します。

DBの選択


使うDBを選択します。

昨日のuse db名称ですね。
これはGMongoの次のメソッドを用いることで、DBインスタンスを取得できます。

MongoTest.groovy

import com.gmongo.GMongo
import org.junit.Before
import com.mongodb.DB

    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
    }


レコードの登録


SQLで言うところのinsertですね。

昨日の例では、mydb.itemsというエンティティ(?)に入れましたので、同様のコードを書きたいと思います。

まずはエンティティの取得から。

MongoTest.groovy

import com.gmongo.GMongo
import org.junit.Before
import com.mongodb.DB

    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def entity = db['items']
    }


えっ、これだけ!?

そうなんです。これだけなんです。

さすがGroovy、Groovyかわいいよ、Groovy。

あとは、このentityにデータを入れていけば良いのです。

昨日の例ではここで登録するデータの形式はJSONでしたが、

さすがGroovy、Hashでデータを入れられます。

MongoTest.groovy

import com.gmongo.GMongo
import org.junit.Before
import com.mongodb.DB

    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def entity = db['items']
        10.times {
            entity.insert([type : 'data', value : it])
        }
    }


さて、ではデータが登録されているかどうかテストしてみましょう。
MongoTest.groovy

import org.junit.Test
import com.gmongo.GMongo
import org.junit.Before
import com.mongodb.DB
class MongoTest {
    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def entity = db['items']
        10.times {
            entity.insert([type : 'data', value : it])
        }
    }

    @Test
    public void testSetUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def list = db.items.find()
        assert list.size() == 10
    }
}


では、テスト実行!


はい、通りました!


片付け


テストを通ったのは良いのですが、これこのままにしておくと、
後でテストこけます。

なので、テストデータを作成したら、 @Afterを使ってデータを削除しておきましょう。
MongoTest.groovy

import org.junit.Test
import com.gmongo.GMongo
import org.junit.Before
import com.mongodb.DB
import org.junit.After

class MongoTest {
    @Before
    public void setUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def entity = db['items']
        10.times {
            entity.insert([type : 'data', value : it])
        }
    }

    @Test
    public void testSetUp() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        def list = db.items.find()
        assert list.size() == 10
    }

    @After
    public void tearDown() {
        def mongo = new GMongo('localhost', 27017)
        def db = mongo.getDB('mydb')
        db.items.remove([:])
    }
}



ちなみに、 @Afterで実行したコマンドはmongodbにおける次のコマンドと同じです。


> db.items.remove({})
> 


はい、以上、今日はここまで。

次回はまたmongodbに戻ります。


2011年9月11日日曜日

Gradleでスローテスト問題を解決するAgain

前回、こんな記事書きました。
見事に効果がわからないという結果が出てきて、どうやればいいのか考えていましたが、
さすがGroovyクラスタに素晴らしい先輩がいらっしゃいました。

@bluepapa32 先輩です。
単純に、スリープするコード


    for (int i = 0; i < 100; i++ ) {
        Thread.sleep(10);
    }


を埋め込めばよかったわけですね。

というわけで、こんなテスト生成スクリプトでテストを大量に作ってみることにしました。


CreateTest.groovy

import static groovyx.gpars.GParsPool.*;
def packagePath = 'C:/Users/mike/IDEA_Project/GradleSample/src/test/java/orz/mikeneck/gradle/sample/boxunbox/test'

def head = $/
package orz.mikeneck.gradle.sample.boxunbox.test;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/$

def body = $/
    public static final int SIZE = 100;
    private List<Integer> intList;
    private List<Long> longList;
    @Test
    public void testInteger()   throws InterruptedException {
        int[] array = new int[SIZE];
        int position = 0;
        for(Integer item : intList) {
            array[position++] = item;
            Thread.sleep(10);
        }
        for (int i : array)
            assertThat(i, is(intList.get(i)));
    }
    @Test
    public void testLong()  throws InterruptedException {
        long[] array = new long[SIZE];
        int position = 0;
        for (Long item : longList) {
            array[position++] = item;
            Thread.sleep(10);
        }
        position = 0;
        for(long item : array)
            assertThat(item, is(longList.get(position++)));
    }
    @Before
    public void setUp() throws Exception {
        Integer[] integers = new Integer[SIZE];
        Long[] longs = new Long[SIZE];
        for(int i = 0; i < SIZE; i++)
            integers[i] = new Integer(i);
        intList = Arrays.asList(integers);
        for (int i = 0; i < SIZE; i++)
            longs[i] = new Long(i + Integer.MAX_VALUE);
        longList = Arrays.asList(longs);
    }
}
/$

def numbers = []
(1..300).each {
    numbers << it
}

withPool {
    numbers.collectParallel { number ->
        def className = "BoxUnboxTest${number}"
        def name = "${className}.java"
        def fileName = "${packagePath}/${name}"
        def define = "public class ${className} {"
        def content = new StringWriter()
        content << head
        content << define
        content << body
        println ' ---- '
        println "now processing : $fileName"
        println ' ---- '
        new File(fileName).write(content.toString(), 'UTF-8')
        assert new File(fileName).exists() == true
    }
}


10msecを100回Sleepするテストメソッドが二つで、ひとつのテストの実行にかかる時間は2sec。
これが300個あるので、必要な時間は600sec = 10min かかるテストです。

実際に一つテストを実施してみました。


2secかかっていますね。
これが300個用意されるので、10minかかることが想定されます。

では、次のGradleスクリプトで実行してみましょう。


build.gradle

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.8.2'
}



なお、マシンの環境は次のような感じです。
OS : Windows 7
CPU : Intel Xeon X3460 (8Core) (64bit)
RAM : 8.00GB




では、実行、というかその間に色々と他のことで負荷がかからないように、
IntelliJ IDEAが起動していて、このブログだけがChrome上で起動しているという状態にしておきます。
で、IntelliJのRunツールで実行するのではなく、ふつうにコマンドから起動します。

さて、オレはその間、『JOJOの奇妙な冒険』を読むこととします。

では、いざ実行…




c:\Users\mike\IdeaProjects\TestingGradle>gradle build
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 15 mins 42.983 secs


15分43秒、マジ遅え。
しかも、最初の数個目までのテストは結構サクサク進んでいたけど、200を越えたあたりからテストの実行速度が落ちてきた感じがする。
こういう時はJVMの再起動などが必要なのかもしれん。

というわけで、さっそく、並列処理を試してみようと思う。

build.gradle

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    testCompile 'junit:junit:4.8.2'
}

test {
    maxParallelForks = 6
    forkEvery = 30
}



前回にも書きましたが、
  • maxParallelForksは並列するスレッド数。
  • forkEveryは指定した回数テストを実行するとJVMを再起動して、OutOfMemoryExceptionを回避する仕組みです。

では、実行開始です。


c:\Users\mike\IdeaProjects\TestingGradle>gradle build
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test
:check
:build

BUILD SUCCESSFUL

Total time: 2 mins 42.544 secs




えっ、2分Σ(゚д゚lll



めちゃくちゃ早くなっていません?
元々15分43秒かかっていたのがたったの2分43秒。

単純に計算すると

15min43sec / 6(core) = 2min37sec


となるから、妥当な値ですね。

では、テストのサマリーを比較してみましょう。



並列化前



並列化後



これを見るとCPU時間は変わっていません。
つまり、CPU時間をすべて複数コアで実行したために早くすることが出来たという事になります。

というわけで、結論

GradlemaxParallelForksを使うともれなくスローテスト問題が解決できる。



2011年8月24日水曜日

Gradle で スローテスト問題を解決する。


今、『Building and Testing with Gradle』(O'Reilly)という本を読んでいます。

Gradleのスローテスト問題への対応


さて、この本の一節に次のような記述がありました。

When JUnit tests reach a certain level of proliferation within a project, there is a motivation to run them in parallel to get the results faster. However, there would be a great overhead to running every unit test in its own JVM. Gradle provides an intelligent compromise in that it offers a maxParallelForks that governs the maximum simultaneous JVMs that are spawned.

In the same area of testing, but with a different motivation, is the forkEvery setting. Tests, in their quest to touch everything and exercise as much as possible, can cause unnatural pressure on the JVM's memory allocation. In short, it is waht Java developers term a "leak". It can merely be the loading of every class causing the problem. This isn't really a leak since the problem stems from the fact that loaded class definitions are not garbage collected but instead are loaded into permgen space. The forkEvery setting causes a test-running JVM to close and be replaced by a brand new one after the specified number of tests have run under an instance.


まあ、訳すのが面倒なので、大雑把にまとめると、
  • maxParallelForks … テストの並列実行数
  • forkEvery … JVMの再起動の頻度(OutOfMemoryExceptionを回避するためにJVMを再起動する。)
ということになります。

使い方はこんな感じになります。
build.gradle

apply plugin: 'java'
repositories {
    mavenCentral()
}
dependencies {
    testCompile 'junit:junit:4.8.2'
}
test {
    maxParallelForks = 5
    forkEvery = 30
}


この例ではテストが5個同時に実行されて、30個のテストクラスが実行される度に一度JVMが再起動されるということになります。
これにより並列でテストを行い、かつOutOfMemoryExceptionを回避して、スローテスト問題に対応してくれるということです。


テストの準備

まあ、こういう本は実際動かしてみてなんぼですので、テストをやってみることにしましょう。

まずはテストを強引に作ります。

CreateTest.groovy

import static groovyx.gpars.GParsPool.*;

def packagePath = 'C:/Users/mike/IDEA_Project/GradleSample/src/test/java/orz/mikeneck/gradle/sample/boxunbox/test'

def head = $/
package orz.mikeneck.gradle.sample.boxunbox.test;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/$

def body = $/
    public static final int SIZE = 400;
    private List<Integer> intList;
    private List<Long> longList;
    @Test
    public void testInteger() {
        int[] array = new int[SIZE];
        int position = 0;
        for(Integer item : intList)
            array[position++] = item;
        for (int i : array)
            assertThat(i, is(intList.get(i)));
    }
    @Test
    public void testLong() {
        long[] array = new long[SIZE];
        int position = 0;
        for (Long item : longList)
            array[position++] = item;
        position = 0;
        for(long item : array)
            assertThat(item, is(longList.get(position++)));
    }
    @Before
    public void setUp() throws Exception {
        Integer[] integers = new Integer[SIZE];
        Long[] longs = new Long[SIZE];
        for(int i = 0; i < SIZE; i++)
            integers[i] = new Integer(i);
        intList = Arrays.asList(integers);
        for (int i = 0; i < SIZE; i++)
            longs[i] = new Long(i + Integer.MAX_VALUE);
        longList = Arrays.asList(longs);
    }
}
/$

def numbers = []
(1..400).each {
    numbers << it
}

withPool {
    numbers.collectParallel { number ->
        def className = "BoxUnboxTest${number}"
        def name = "${className}.java"
        def fileName = "${packagePath}/${name}"
        def define = "public class ${className} {"
        def content = new StringWriter()
        content << head
        content << define
        content << body
        println ' ---- '
        println "now processing : $fileName"
        println ' ---- '
        new File(fileName).write(content.toString(), 'UTF-8')
        assert new File(fileName).exists() == true
    }
}


Groovyで書いていますが、まあヒアドキュメントで書かれているので、どういうテストかすぐにわかると思います。
大量(400 x 2 = 800個)のオブジェクト生成および基本型のintlongのボクシング・アンボクシングというコストのかかるようなテストを400個作ります。

ちなみに単体でテストするとこれくらいの速度です。


ここから単純に計算すると 0.014s x 400 -> 5.6s くらいかかることが想定されます。


テストの実行(並列しない)


まずは並列実行しない場合のテスト
build.gradle

apply plugin: 'java'
repositories {
    mavenCentral()
}
dependencies {
    testCompile 'junit:junit:4.8.2'
}


実行結果

C:\Users\mike\IDEA_Project\GradleSample>gradle test
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE

BUILD SUCCESSFUL

Total time: 6.945 secs
C:\Users\mike\IDEA_Project\GradleSample>


約6.9秒くらいですかね。

何回か実施しましたが、だいたい同じくらいの時間でした。

テストの実行(並列する)


並列実行( 3並列 : 50回に一回JVMをリロード )する場合。
build.gradle

apply plugin: 'java'
repositories {
    mavenCentral()
}
dependencies {
    testCompile 'junit:junit:4.8.2'
}
test {
    maxParallelForks = 3
    forkEvery = 50
}



実行結果

C:\Users\mike\IDEA_Project\GradleSample>gradle test
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE

BUILD SUCCESSFUL

Total time: 7.943 secs
C:\Users\mike\IDEA_Project\GradleSample>


あれ、7.943sもかかっている!

何回か挑戦…


:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE

BUILD SUCCESSFUL

Total time: 7.025 secs
C:\Users\mike\IDEA_Project\GradleSample>gradle test
:buildSrc:compileJava UP-TO-DATE
:buildSrc:compileGroovy UP-TO-DATE
:buildSrc:processResources UP-TO-DATE
:buildSrc:classes UP-TO-DATE
:buildSrc:jar UP-TO-DATE
:buildSrc:assemble UP-TO-DATE
:buildSrc:compileTestJava UP-TO-DATE
:buildSrc:compileTestGroovy UP-TO-DATE
:buildSrc:processTestResources UP-TO-DATE
:buildSrc:testClasses UP-TO-DATE
:buildSrc:test UP-TO-DATE
:buildSrc:check UP-TO-DATE
:buildSrc:build UP-TO-DATE
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE

BUILD SUCCESSFUL

Total time: 6.964 secs
C:\Users\mike\IDEA_Project\GradleSample>


う~ん、大して変わらないですね。





これはひょっとしてもっとテストケースを作らなければならないのかな?

とすると、今の手元にある環境ではちょっと実験できないので、
続きは家に戻ったらやってみます。


実験環境
OS : Windows 7
CPU : Intel Core i7 L640 (クアッドコア)
RAM : 8.00GB