goo blog サービス終了のお知らせ 

N2 ToolBox(跡地)

跡地です。引っ越しました。http://d.hatena.ne.jp/nosen

Maven2 Technology Previewリリース

2005-04-10 13:05:00 | オープンソース
Maven2のテクノロジープレビュー版がついにリリースされた
模様です。

http://maven.apache.org/maven2/index.html

最近アクティビティが活発すぎて、全然追いきれて無かったのですが。。
みなさん、是非ダウンロードして動かしてみましょう!

Mavenのサイト更新

2005-03-30 02:24:00 | オープンソース
最近(3/15ころ)Mavenのサイト
大幅に更新されました。どこに何が書いてあるのかがはっきり分かるように
なって、とてもいい感じです。

ところで、仕事でMavenを使う場合に、やっぱり困るのはドキュメントが
少ないこと、それも日本語のドキュメントが少ないことです。
自分がそのプロジェクトにどっぷり浸かっている場合は、自分が頑張って
ソース読むなり、英語読むなりすればいいだけなのでよいのですが、
問題はスポット的にプロジェクトの支援に入る場合です。
この場合、ビルド環境のメンテを誰かにひきつがなければならないわけですが、
このとき、Mavenというややこしいツールを説明する資料を自分で書くのは
とてもしんどい、というか無理です。

今回、更新されたドキュメントが日本語で読めれば、「ココ見とけ」で
済んで便利なので、是非Ja-Jakartaで翻訳に取り組みたいと考えています。

Maven2: POM中の日本語

2004-12-16 01:09:39 | オープンソース
たしか現行Mavenがまだ1.0rc2くらいだったころ、POMの中に
記述した日本語が化け化けになるというバグがありました。

m2ではそのへんはどうなっているんだろうと、試してみました。

その結果判明したのは、
文字コードがシステムのデフォルトエンコーディングだったら通る
ということです。微妙。。。

問題はm2がPOMをパースする時に使っている、plexus-utilについてくる
XMLプルパーサにありました。このパーサは
XML Pull APIというのと同じシグネチャのインターフェースを
実装しているのですが、XML Pull APIの仕様によると、XML宣言のとこに
書いてあるエンコーディングから文字コードを判定する
というフィーチャはあくまでオプションの扱いに
なっています。plexus-utilについてくるパーサは
最低限の実装しかしてないので、当然そのようなフィーチャは
サポートされるはずもなく、パーサを使う側(=modelloが生成したコード)
でもエンコーディングを指定していないので、
自動的にデフォルトエンコーディングとしてパースして
しまっている模様です。

Shift_JISで書いたPOMをLinux上でビルドしたりとか、普通にありそう
なのでこれは結構いたいのでは。。

直そうとすると、plexus-utilのXMLプルパーサとmodelloにだけ
影響があって、実はm2は変更しなくていいので、m2のMLに投げていい問題
なのかどうかも不明です。。。困った。

XMLプルパーサのソースなんてとても手がつけられなさそうだと
思ってたのですが、実は以外とシンプルな作りになっているので
頑張って自分で直してみるというのも面白いかも。

Maven2:プラグインを作ってみよう!

2004-12-12 21:31:23 | オープンソース
お久しぶりです。
さすが師走と言うか、忙しくてなかなかblog書く暇がありません。

今日はm2のPluginのつくり方について調べたことのメモです。
調べているうちにさらに様々な疑問点、問題点が噴出してきてしまって
いるのですが、それはとりあえず置いておいてプラグインの書き方の話しに
集中しましょう。

m2のPluginの作り方は意外と簡単で、以下の3ステップでOKです。

  1. Plugin用のPOMを作る。

  2. AbstractPluginクラスをextendしてJavaクラスとしてプラグインを記述する。

  3. plugin:installゴールを実行


これで、作ったPluginがローカルリポジトリにインストールされて、
使えるようになります。
以下、各ステップをもうちょい詳しく解説します。

1. Plugin用のPOMを作る

まずPlugin自体のPOMを作ります。このPOMはリポジトリにインストールされて、
Pluginが依存するjarを自動的にダウンロードする時などに使われます。
今回作ったPOMは以下のような感じです。
<?xml version="1.0" encoding="Shift_JIS"?>

<project>
  <!--
    おまじない。Pluginの共通の親POM。
    Mavenリポジトリ内のPOMを継承している!
   -->
  <parent>
    <groupId>maven</groupId>
    <artifactId>maven-plugin-parent</artifactId>
    <version>2.0-SNAPSHOT</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <!--groupIdはかならずmaven-->
  <groupId>maven</groupId>
  <!--artifactIdはmaven-[Plugin名]-plugin-->
  <artifactId>maven-foo-plugin</artifactId>
  <name>My First Plugin</name>
  <type>plugin</type>  
  <!--いまのところバージョンはこれ以外指定できない-->
  <version>1.0-SNAPSHOT</version>  
  <inceptionYear>2001</inceptionYear>
  <package>org.apache.maven</package>
  <logo>/images/maven.gif</logo>
</project>


2.AbstractPluginクラスをextendしてJavaクラスとしてプラグインを記述する。

いよいよプラグイン本体の作成です。
今回作ったのはPOMに書かれたプロジェクト名を
出力するというごく簡単な物です。
ソースコードは大体以下の通りです。パッケージ宣言とかインポート文は省いてます。

/**
 * @goal print
 *
 * @description deploys a pom to remote repository
 *
 * @parameter
 *   name="projectName"
 *   type="String"
 *   required="true"
 *   validator=""
 *   expression="#project.name"
 *   description=""
 *
 */
public class SampleMojo extends AbstractPlugin {
    public void execute(PluginExecutionRequest request, PluginExecutionResponse response) {
        String pn = (String) request.getParameter("projectName");
        System.out.println("Project Name:" + pn);
    }
}


実装しなくてはならないのはexecuteだけのようです。
なんだかServletみたいなインターフェースですね。
JavaDocの中に定義しているパラメータとrequest.getParameterで取得している
パラメータとの対応関係に注意して下さい。
プラグインが必要とするパラメータは設定情報として切り出されて、
コンテナ側が勝手にrequestオブジェクトにセットしてくれるようになっています。
おかげでm2のpluginはPluginのインターフェースにのみ依存し、
m2のCoreには依存しないように記述することが出来ます。

2.plugin:installゴールを実行

ここまで出来たらプロジェクトのベースディレクトリで
m2 plugin:install
を実行すると、JavaDocの中に書かれていた設定情報から
XML形式の設定ファイルを生成し、クラスをコンパイルし、Jarに固め、
ローカルリポジトリにインストールし、POMもローカルリポジトリにインストールし、
使える状態に持っていってくれます。

このプラグインを実行するには
m2 foo:print
でOKです。
POMのname要素に書かれているプロジェクト名が出力されるはずです。

Eclipse Technology Project

2004-11-08 23:01:41 | オープンソース
Eclipse Technology Projectって怪しげなプロダクトが
沢山あって、良く分からないですよね。
僕の後輩のKという男が書いている

このエントリ
はいま立ち上がってるプロジェクトを概説して
くれてます。

個人的にはGMTとかオムレツとか、MDAがらみはもうちょい成熟してこないと
怖くて手が出せない感じです。

Web Standard Toolってのは面白そうですね。
もし将来的にMaven2と統合されれば、Maven2=ビルド、Eclipse=ソースコード編集
っていう住み分けができそう。

Maven2:プラグインの解決

2004-11-05 07:10:57 | オープンソース
Maven2の小ネタをまた一つ。

Maven2ではプラグインはGoalを実行する時に必要に応じて自動的に
ダウンロードされるようになります。
(そのためMaven2のディストリビューションはかなりコンパクトです)
現状ではゴールの実行時に以下のような流れで処理が行われます。

  1. ゴールを実行するプラグインが既にロードされているかチェックする

  2. ロードされていなかった場合、ローカルのリポジトリにプラグインの
    jarがあるかチェックする

  3. ローカルのリポジトリにプラグインのJarが無い場合、
    リモートリポジトリからダウンロードする

  4. プラグイン用に新しいClassWorldsのClassRealmを作って、
    プラグイン自体のjarと依存するjarを追加する


ダウンロードするJarファイル名は、11/4日現在、

maven- + [pluginId] -plugin-1.0-SNAPSHOT.jar

という名前で決めうちになっており、ソースコードには

これは全然イケてない。ArtifactIDもバージョン名の展開の仕方
も、もっとましな方法を考えないとね


という意味のことが書かれています。
このせいで、genappプラグインとか、1.0に存在するけど2
でまだ出来てないプラグインを実行しようとすると、
jarはダウンロードできるけど、META-INF/plugin.xmlという
m2におけるプラグインの設定ファイルが読めなくてエラーになります。

それはともかく、面白いのは上記手順のうち2, 3, 4はMaven2自体でなく
Maven2が採用しているコンテナであるplexusがやってくれているという
ことです。Mavenは「このプラグインはまだロードしてないから適当に
ロードしといてね」とお願いするだけで、その後の面倒な
処理は全部plexusが引き受けてくれます。

plexusには必要なJarをMavenリポジトリから探して来てClassRealmを
作ってくれるコンテナAPIの実装が存在するのです。

つまり、Plexusを使うと、jarの依存関係をバージョン間の依存まで含めて
実行時に自動的に解決し、必要があればダウンロードまでしてくれる
アプリケーションを簡単につくることが出来そうです。
もうJar地獄とはおさらばですね。

FieldInjectionがplexusの最大の特徴かと思っていたら、
なかなかどうして、ユニークな機能を持ってるもんです。
ちょっとAvalonっぽい雰囲気も漂わせてます。

Maven2というコンポーネント

2004-11-02 03:22:27 | オープンソース
随分久しぶりになってしまいました。

職場で風邪がアウトブレイクしていて、体調が最悪だったのと、
心も風邪をひいていて、やる気が燃え尽きていたのが原因です。
まだ完全に復調していません。ほんと先週は最悪でした。
1年ぶり位で熱をだして仕事に穴をあけてしまいました。

金でなんとかなるならやる気を買いたい今日このごろです。

愚痴ばっか言っててもしょうがないんで、久しぶりにMaven2について
調べたことを少々。

Maven1.0は、完全にコマンドラインベースのアプリケーションとして
作られていて、基本的には起動してgoalを実行したらVMも終了という
流れになっていました。
これはantの様なビルドツールとして使う分には問題ないのですが、
eclipseなどのIDEに埋め込んで使ったり、サーブレットコンテナと
同一VMで起動したい時にはよろしくありません。
特にクラスパスがらみで底の見えない穴にはまりこんでしまうこと
請け合いです。現に職場で僕の近くの席の人が見事にはまって
ました。

Maven2はそれ自体がコンポーネントとして他のアプリケーションに
埋め込まれることを前提に、よく考えられて設計されている様です。

第一に、ClassWorldを使用してプラグインごとにClassRealmを分けて
いるため、クラスパスの問題はずっと少なくなります。

第二に、プラグインとPOMのライフサイクルが
慎重に区別されています。
POMがMaven#executeメソッドの実行中のみ生きている
情報なのに対し、プラグインの情報というのは適切にキャッシュされ、
複数のビルドで共有されるべきものです。

Maven2ではV1のようにプロジェクトのパラメータをシステムプロパティ
で与えることをせず、すべてPOMのなかに閉じ込めています。
そしてPOMファイルはMaven#executeメソッドの引数で与えることができる
ので、異なるプロジェクトのビルドを同一VMで連続して行ったとしても、
パラメータが混じっておかしなことになることがありません。
余計なプラグインの情報を読み直すこともありません。

第3に、ビルド実行中に保持されるビルド固有のデータは、全て
Maven#executeメソッド(ビルドのエントリポイントになるメソッド
のローカル変数として初期化される
MavenSessionクラスのインスタンスの中に保持されます。
ぱっとソースを眺めた印象では、おそらく、
Maven#executeメソッドはマルチスレッドで実行しても問題
ないのではないかと思います。
複数プロジェクトのビルドを並行して行うような熱いことが
普通にできてしまいそうです。

(実際に動かして確認してないので、話半分で読んでくださいね)


APT(Almost Plain Text)のサンプル

2004-09-22 23:38:50 | オープンソース
    ----------------
        APTの文法
    ----------------
        ikkoan
    ----------------
    2004/9/22

トップレベルのセクションのタイトル

  今日は趣向を変えてAPT(Almost Plain Text)形式でお送りします。
  主なAPTの文法のサンプルを示したいと思います。
  文書のタイトル、著者、日付は大体冒頭のような形式で書きます。
  インデントなしの行は、トップレベルのセクションタイトルになるようです。

  インデントがある連続した行は段落として扱われます。
  インデントの量はどうでもいいみたいです。

~~これはコメント
~~ここに変換後のHTMLを置いておきますね。

*サブセクション1のタイトル

  サブセクションは、上のようにかきます。

**サブセクション2のタイトル

  同様にサブセクションのレベルを下げたい時は上のようにします。
  アスタリスクは4個までです。

*リストの書き方

**番号なし

    *リスト1

    *リスト2

      *サブリスト1

       リストにネストされたパラグラフ

      *サブリスト2

    *リスト3
  まあ、見たまんまですね。

**番号つき

  [[1]] リスト1

  [[1]] リスト2

~~リストを強制的に終了

  []

  [[a]] リスト1

  [[a]] リスト2

  これもみたまんまですね。

*PREタグのようなもの

------------------------------------------
このようにかこまれたテキストは
    そのままの
       フォーマットで
              表示されます。
------------------------------------------

+------------------------------------------
このようにかこまれたテキストは
    枠で
       括られて
              表示されます。
+------------------------------------------

*図

[d-pre1] M45プレアデス星団

  図と図のタイトル。図はイメージファイルへのパス名。ただし拡張子なし。

*テーブル

  テーブルはちょっとややこしい。

*-----------+--------------------------:-----------------*
|右寄せ(1,1)|左寄せ(1,2)               |中央寄せ(1,3)    |
*-----------*--------------------------*-----------------*
|右寄せ(1,1)|最初の行の設定が生きる    |中央寄せ(2,3)    |
*-----------+--------------------------+-----------------+
|複数       |foo                       |bar              |
|行         |fooooooo                  |barrrrr          |
*-----------+--------------------------+-----------------+

  大体以下のルールに従う.

  *行頭は*と---でテーブル開始&行区切り

  *+は右寄せ

  *:は左寄せ

  *|でセル区切り

*リンク

  {Anchor} {{{Anchor}Anchor}} へのリンク

  {{{http://www.google.co.jp}Google}}へのリンク

  {{{http://www.geocities.jp/nn_51/apt/sample.txt}ソースはこちら}}


FireFox1.0のLive Bookmarkを手動で追加してみる

2004-09-17 13:09:12 | オープンソース
FireFox1.0 Preview Releaseがリリースされましたね。

早速インストールして使ってみました。

Live Bookmarkはかなりいいですね。もはやFireFoxという名の
RSSリーダと化していると思います。欲を言えば、未読の記事だけを
フィルタしたり、新着記事を通知してくれたりするとさらにいいと思います。

新しい検索機能の動作もかなり好きです。

この2つが1.0リリースのハイライトかと思われます。

ところでLive Bookmarkは以下のような動作をするのですが、

・headタグ内にlinkタグでrssフィードが示されていた場合、
右下に"RSS"アイコンが表示される
・表示された"RSS"アイコンをクリックするとブックマークにRSSフィード
が追加され、記事に対応するブックマークが動的に生成される

世の中にはlinkタグで場所を示していないRSSフィードも結構あります。
(Bulknewsとか)
そういうRSSフィードをLive Bookmarkとして追加したいときはどうしたら
いいんでしょうか?
GUI上で操作する方法がわからなかったので、
とりあえず直接bookmark.htmlを編集して何とかしてみました。

ブックマークの一つのエントリは以下のようになっています。

ADD_DATE="1095381455"
LAST_MODIFIED="1095389379"
FEEDURL="http://bulknews.net/rss/rdf.cgi?NikkeiNet"
ID="rdf:#$zqWuU2">Nikkei Net


このFEEDURLという属性があるとLive Bookmarkとして扱われるらしいので、
上記の例のようにRSSフィードの場所を追加されるとうまいこといきます。

それにしてもFireFoxは勢いがありますね。
IEからの乗り換えユーザも増えている
そうです。

人がIEからFireFoxに乗り換えるポイントを想像してみました。
(1) 動作が軽い
(2) タブブラウザが使いやすい
(3) セキュリティホールが少ない
(4) 検索ツールバーがいい
(5) ダウンロードマネージャがいい
(6) 開発者であれば、DOM Inspectorはうれしい
(7) ブックマークを検索できるのはいい
(8) ロゴが好き
(9) クレジットがスクロールするのがこじゃれている
(10) 単に天邪鬼である
(11) あたらしものずき
(12) インストールモンキーである
(13) とにかく、ビルが嫌い

要は、好みの問題ということでしょうか。

僕もデフォルトブラウザとして使わせてもらってますが、やっぱり動作が軽いし、
全体的な操作感も好きです。
それにしても普通の人はIEから乗り換えるのは相当めんどくさいと感じるとは
思いますが。


Surefire

2004-09-01 18:36:43 | オープンソース
Maven2でtestゴールを実行するとSurefireプラグインという聞きなれないプラグインが実行されます。
Surefireというのは、またしてもCodehausで開発されているテストのための何かということしかわかっていません。。。
ソースツリーを少し眺めてみたところ、どうやらJUnitに限らず、いろいろな種類のテストを複数まとめて実行し、結果を報告するためのフレームワークのようです。
http://cvs.surefire.codehaus.org/surefire/
からソースコードを見れます。上記URLには以下のようなディレクトリがあります。

surefire
surefire-beanshell
surefire-booter
surefire-jython
surefire-web
surefire-xmlrpc

ディレクトリ名から察するに、どうやらテストをBeanShellやJythonで書いたり、WebアプリケーションやXML-RPCのテストをしたり、といった処理を共通のインターフェースから起動できるようにしたいのではと思われます。

Surefireを構成する主要なコンポーネントには以下のようなものがあります。

・Battery - テストを実行する
・Reporter - テストを結果を報告する
・SurefireBooter - Surefireを起動する

Batteryの実装としてはディレクトリからJUnitテストケースを探し出して実行するものが取りあえず動く状態にあるようです。Surefireは全体的になるべく他のライブラリに直接依存しないというポリシーで作られているらしく、JUnitを起動する部分は全てリフレクションで処理されています。
Reporterの実装としては、今のところConcoleReportとFileReportの2つがあります。

使い方としては、Maven2のSurefireプラグインのソースコードを見るのがわかりやすいと
思います。以下に引用します。

        SurefireBooter surefireBooter = new SurefireBooter();

        surefireBooter.addBattery( "org.codehaus.surefire.battery.DirectoryBattery", new Object[]{basedir, includes, excludes} );

        surefireBooter.addClassPathUrl( new File( mavenRepoLocal, "junit/jars/junit-3.8.1.jar" ).getPath() );

        surefireBooter.addClassPathUrl( new File( mavenRepoLocal, "surefire/jars/surefire-1.1.jar" ).getPath() );

        surefireBooter.addClassPathUrl( new File( classesDirectory ).getPath() );

        surefireBooter.addClassPathUrl( new File( testClassesDirectory ).getPath() );

        for ( int i = 0; i <classpathElements.length; i++ )


例によってまだ何のドキュメントもなく、CVSに入ってるソースコードをチラッと調べただけの結果なので、
間違ったこと書いてるやもしれませんが。。