今回は外部ライブラリを使用する方法を見ていきます(一覧)。
FunctionPlotter プロジェクトのソース変更点
今回の変更で、以下の外部ライブラリを使用できるようにします:
group | module | version |
---|---|---|
org.apache.commons | commons-math | 2.1 |
FunctionPlotterController.groovy の変更
FunctionPlotterController.groovy 内の Dynamo クラスに関して
class Dynamo{ ... Dynamo(String function){ def expr = """ import static java.lang.Math.* import static org.apache.commons.math.util.MathUtils.* // commons-math 内のクラス import static org.apache.commons.math.special.Beta.* // commons-math 内のクラス import static org.apache.commons.math.special.Gamma.* // commons-math 内のクラス import static org.apache.commons.math.special.Erf.* // commons-math 内のクラス $function""" this.functionScript = SHELL.parse(expr) } }
のように、関数を表す文字列から Groovy スクリプトを生成する部分に commons-math のクラス(というか static メソッド)を自動 import されるようにしておきます。 これによって
- MathUtils クラスの static メソッド
- Beta クラスの static メソッド (ベータ関数関連)
- Gamma クラスの static メソッド (ガンマ関数関連)
- Erf クラスの static メソッド (誤差関数関連)
がメソッド名のみで使用できるようになります。
FunctionPlotterView.groovy の変更
上記の変更だけでもいいんですが、実行時にしか外部ライブラリを使用しないためサンプルとしては物足りないかなぁということで、(ちょっと無理矢理) View でも commons-math のクラスを使うようにしましょう:
... import org.apache.commons.math.util.MathUtils as CMath // commons-math 内のクラス actions{ ... } application(title: 'Function Plotter', ...){ panel(border:BF.createEmptyBorder(6, 6, 6, 6)){ ... hbox(constraints: BL.SOUTH){ hstrut(width:10) labeledSpinner('from', 0d) 10.times{ hglue() } labeledSpinner('to', CMath.TWO_PI) // commons-math のクラスを使う } } }
ソースコードの変更はたわいなし。
外部ライブラリを使用できるようにするための設定
Griffon で外部ライブラリを使用できるようにするためには、次の2つの方法があります:
- lib フォルダに Jar ファイルを配置する (install-dependency)
- BuildConfig.groovy ファイルに設定を記述する
この設定はどちらか一方で構いません。 lib フォルダに Jar ファイルがあれば BuildConfig.groovy に設定を記述する必要はありませんし、vice も versa です。
lib フォルダに Jar ファイルを配置する install-dependency
プロジェクト・ルートのフォルダ下にある lib フォルダに Jar ファイルを配置すると、特に他の設定をしなくてもコンパイルや実行の際にそのライブラリをクラスパスに含めてくれるようです。 ただ、全てのライブラリとそれに必要なライブラリを手動でダウンロードするのは面倒なので、griffon コマンドでそれらのライブラリをダウンロードしましょう。
使用するコマンドは「griffon install-dependency」です。 プロジェクト・ルートのフォルダ下にて、これに続けて「必要なライブラリの指定」と「ダウンロード先*1」を指定します:
griffon install-dependency org.apache.commons:commons-math:2.1 --dir=lib
ライブラリの指定方法は「《グループ名》:《ライブラリ名》:《バージョン》」です*2。
Griffon のドキュメント*3を見るとこれで OK なハズなんですが、実際には何故か lib フォルダではなく true フォルダ下にライブラリがダウンロードされます・・・ん〜まぁ、単なるケアレス・バグでしょう。 修正されるまでは、面倒ですが手動で移動させるしかないですね。
BuildConfig.groovy ファイルに設定を記述する
次は BuildConfig.groovy ファイルに設定を記述する方法*4。 BuildConfig.groovy ファイルは
- FunctionPlotter/griffon-app/conf/BuildConfig.groovy
にあります。 このファイルの griffon.project.dependency.resolution を設定している箇所に設定を追加します。
griffon.project.dependency.resolution = { ... repositories { griffonPlugins() griffonHome() griffonCentral() //mavenLocal() // Maven のローカル・リポジトリ mavenCentral() // Maven のリモート・リポジトリ } dependencies { // 'build', 'compile', 'runtime', 'test' 'provided' のいずれかのスコープを指定する compile 'org.apache.commons:commons-math:2.1' //runtime 'org.apache.commons:commons-math:2.1' } }
- Maven2 のリモート・リポジトリをライブラリ検索に使用したい場合は、repositories ノード下の mavenCentral() のコメントを外す*5
- dependencies ノード下に、使用したいライブラリとそのスコープを指定する
指定できるスコープの意味は以下のようになっています:
スコープ | 説明 |
---|---|
build | ビルドシステムに必要 |
compile | コンパイルに必要 |
runtime | コンパイルには不必要だが実行時に必要 |
test | 実行時には不必要だがテスト時に必要 |
provided | WAR の配備時には不必要だが開発時に必要 |
だいたい Maven2 のスコープと同じですね。 ただ、そういう仕様なのか単なるバグなのか不明なのですが、Griffon では compile スコープのライブラリは実行時にクラスパスに含められないようになっています*6 *7。 仕方ないので、compile, runtime 両方にライブラリの指定をすることにしましょう*8:
dependencies{ def compile_runtime = 'org.apache.commons:commons-math:2.1' compile compile_runtime runtime compile_runtime }
実行結果
ソースコードの変更と、上記のうちいずれかの外部ライブラリを使用するための設定を行った後、FunctionPlotter を実行して
griffon run-app
関数の箇所に「erf(x)」(erf() は org.apache.commons.math.special.Erf クラスの static メソッド)を入力してグラフを描画すると、以下のように表示されます:
きちんと描画されてるかどうかは wikipedia:誤差関数と見比べて確認してください。
依存している Jar の一覧を作成する dependency-report
特に必要な事項ではありませんが、ライブラリの依存性を俯瞰したい場合は
griffon dependency-report
を実行すると依存性のレポートが生成されます。 レポートは HTML 形式で
- ${FunctionPlotter}/target/dependency-report
フォルダに作成されます。 生成されたページを見る限り、Apache Ivy の機能をそのまま流用してるようですね。
追記
Griffon 0.9.2-beta-3 では、compile スコープで指定したライブラリは runtime にも含まれるようになってました。 ちなみに Gradle でも、脚注に書いた「extendsFrom compile」みたいなのを書かなくても compile スコープのライブラリは runtimeに含まれるようです(Gradle 0.9.2)。
Apache Maven 2.0入門 Java・オープンソース・ビルドツール
- 作者: 野瀬直樹,横田健彦
- 出版社/メーカー: 技術評論社
- 発売日: 2006/12/13
- メディア: 大型本
- 購入: 8人 クリック: 141回
- この商品を含むブログ (97件) を見る
*1:ダウンロード先を指定しない場合は(指定してもだけど) ${user.home}/.ivy2/cache にキャッシュが保存されます。 Maven2 のローカル・リポジトリの役割。
*2:Maven2 の用語だと「《groupId》:《artifactId》:《version》」です。
*3:「Griffon Guide - Reference Documentation」 CommandLine → install-dependency 参照。
*4:詳しくは「Griffon Guide - Reference Documentation」 3.4 Dependency Resolution の項参照。
*5:上記の install-dependency コマンドの場合は自動でこのリポジトリを検索してくれるようです。
*6:Griffon のドキュメントを見ると compile スコープは「Dependencies for the compile step」となっていて、実行時に関しては何も書かれていないのでそういう仕様なのかも知れませんが、後でやる「griffon dependency-report」で生成されるレポートには runtime スコープの箇所に compile スコープのライブラリも掲載されています。 うーむ、謎。
*7:Gradle ではどうなっているのか確かめていませんが、少なくとも「configurations.runtime { extendsFrom compile }」とすれば compile スコープのライブラリをそのまま runtime にも引き継がせることができそうです。 Griffon で似たようなことをするにはどこに設定を書いたものか・・・
*8:compile スコープのみを指定して、全てのライブラリを1つの jar にまとめる「griffon prod package jar」を実行しても大丈夫そうです。 dist/jar 下に実行可能な Jar ファイルが作成されます。