そのままビルドはできますが、Tomcatにデプロイしてアクセスすると日本語が文字化けしてしまいます。原因は、JSPプリコンパイル時の文字コードが、UTF-8固定になっていることにあります。生成するServletのソースコードのデフォルト文字コードがUTF-8になっています。Windowsで開発している場合はソースコードはMS932で書くことが多く、コンパイル時もMS932を指定するので、ここで文字化けが起こってしまうのです。対応としては、TomcatプラグインのJellyスクリプトを改造するしかありません。(Tomcatプラグインには、プリコンパイル時の文字コードを指定するプロパティは用意されていないようです)Tomcatプラグインのplugin.jellyに、_jspcと言うゴールがあり、その中でjasper2タスクが実行されるようになっています。jasper2タスクには、javaEncodingプロパティが用意されているので、これを使って文字コードを指定するようにすればOKです。コメント:2Mavenトラブル事例-Maven1.0.xでTomcatプラグイン続々Mavenでのトラブル事例。Maven1.0.2で、Tomcatプラグイン1.2.xは使えません。org/apache/tools/ant/taskdefs/Redirectorが発生します。これは、Maven1.0.2にバンドルされているAntのバージョンが古い(1.5.3)のが原因です。上述のクラスRedirectorはAnt1.6で新規追加されたクラスなので当然Ant1.5.3環境では存在しません。Maven1.0.2のAntを1.6.xにバージョンアップすることも試みたのですが、あちこち不整合が起こるようで上手くいきませんでした。結局、Ant1.6.xをバンドルしたMaven1.1.xを使うことで対処。Maven1.0.2の方が安定しているのであえてそうしていたのですが。続Mavenでのトラブル事例。以下の問題が生じました。下に生成されたServletのソースコードが出力されます。この状態で、JCoverageレポートを生成すると。C:\\Hoge/target/docs/jcoveragejava.io.FileNotFoundException:C:\\Hoge\\target\\docs\\jcoverage\\org\\apache\\jsp\package-frame.html(指定されたパスが見つかりません。org.apache.maven.jcoveragereport.CoverageReportGenerator.execute(CoverageReportGenerator.java:68)とエラーが発生します。含まれていないことが原因です。対応はいくつかの設定が必要です。</preGoal>このように、JCoverageレポートのpreGoalを追加し、プリコンパイルされたServletの所在をソースディレクトリに追加します。ポイントは、5~7行目です。存在しない場合は、ソースディレクトリを追加しないようにします。しておかないと、今度は逆にプリコンパイルしていない状態でJCoverageプラグインがエラーになってしまいます。org/**/*.*次に、プリコンパイルされたServletをJCoverageレポートの対象から外します。プリコンパイルされたServletのJUnitテストなんて書いているわけがないので、JCoverageの対象にすると、カバレージが下がってしまう為です。して見てみると、Mavenのプラグイン群は、組み合わせの相性が脆弱であるといわざるを得ません。1つの組織で開発しているわけではなく、多くのオープンソースコミュニティによって開発されているので、しょうがないとは思いますが。コメント:0Mavenトラブル事例-プロパティ名にハイフンは使えないMavenでのトラブル事例。してもMaven(1.x。2.xは試してないので知りませんが)はデリケートです。プラグインのバージョンが違うだけで、それまで動いていたものが動かなくなったり、問題が発生しているのにエラー表示なく正常終了したり。プラグインの品質にもややバラツキがあり、Maven本体のバージョンアップと同期してメンテナンスされていないものも少なくないようです。文句はこのくらいとして。今回はプロパティの命名でハマりました。maven.xmlに自作のゴールを書き、prject.propertiesでそのゴールで使うプロパティを定義しました。HOGEHOGEこれを実行すると。値が取得できず、'0'になっています。原因は、プロパティの名前に'-'(ハイフン)を使っていることでした。secondsちゃんとプロパティの値が取得できました。'-'等は命名によく使うのですが、こんな落とし穴があったとは。今トリビアの泉をやってますが、トリビアの種でオナラの臭いを体から消す(離す)にはどうすれば良いか、と言う検証をやってました。以前から思っていたのですが、なにげにトリビアの泉の検証は高度だと思います。・明確なゴールを設定する。・どうすればゴールにたどり着けるか、あるいはどれだけの条件を満たせばゴールに到達できるかを考える。・ゴールにたどり着くまでに何をしなければならないか、シナリオを考える。・とっかかりとなる仮定を立てる。・シナリオに従い、順次検証して行く。いったことをやっています。普段、仕事をしていて常々思っているのですが、このように仕事に対してゴールを明確にし、着実に仕事を進めていくというのはなかなか難しいものです。人間、考えなくてもわかるところ、楽なところからやろうとするので、どうしても行き当たりばったりになりがちです。その結果、あれこれとやってはみたものの結局目的は果たせずに無駄な労力を使ってしまった、と言う事も少なくありません。仕事の進め方で悩んだ時は、トリビアを思い出してみよう。依存したプロジェクトをビルドする時の問題。SeasarファウンデーションのMavenリポジトリSeasar2関係のライブラリは、標準のリモートリポジトリであるibiblioでは公開されていないようで、Seasarファウンデーションの公式サイトにリポジトリがあります。ここでは、Maven1.x用と、Maven2.x用のリポジトリが用意されているようなのですが、Maven1.x用の方はメンテナンスされておらず、ライブラリが古いままで更新が止まっています。この問題は、既に他の方が解決されていて、ここに対応方法が書かれています。ありがとうございました。「s2-framework-2.3.11.jar」のダウンロードを試みています。ダウンロードに失敗しました。ビルドのプロセスを続ける事が出来ません。以下の依存関係が満たされていない為です:s2-framework-2.3.11.jarと言うエラーが発生し、ライブラリをダウンロードできません。Mavenの-Xパラメタを指定してデバッグ情報を出力してみると。Application:「s2-framework-2.3.11.jar」のダウンロードを試みています。ダウンロードに失敗しました。URLに、...maven//org.seasar.container...と、スラッシュが2つ付いてしまっています。原因は、Mavenの実装にあるようです。(Mavenのバグ?と言うか想定外の使い方なのでしょうがないんでしょうが)対応としては、artifactIdの先頭に"../"を付与して無理やりURLを補正すると、とりあえずうまくダウンロードできました。(他に問題が出るかもしれませんが。)例えば、<dependency><groupId>../org.seasar.container</groupId><artifactId>s2-framework</artifactId><version>2.3.11</version><properties><war.bundle>true</war.bundle></properties></dependency>のような感じです。Maven2.xに移行するべきなのかな。コメント:2javadocでIllegalArgumentException現在参画しているプロジェクトの開発環境構築のため、あれこれと試していると、JavaDoc生成で例外が発生。Method):以下略こんなことは初めてだったのですが、あれこれ調べているとWeb上に情報が。http://forum.java.sun.com/thread.jspa?tstart=0&forumID=41&threadID=551665&trange=15どうやら、環境変数CLASSPATHの設定が悪さをしているらしい。CLASSPATH=として、CLASSPATHをクリアしてやるとエラーにならずにjavadocを実行できます。CLASSPATH設定のどこがマズかったのかと言うと、既に存在しないjarファイルへの参照が含まれていたのが原因だったようです。CLASSPATHからこの記述を削除することで問題解決しました。コメント:0S2Daoの例外ハンドリングS2Daoを使ったアプリケーション設計を考えているのですが、ひとつ課題に直面しました。それはS2Daoが送出する例外です。実行時例外を投げます。この時、例外の種類によってはエラーとはせずに、アプリケーション内部でハンドリングしたい場合があります。レコード更新時の楽観的排他制御に引っかかった場合、NotSingleRowUpdatedRuntimeExceptionが送出されるようなのですが、この場合はエラーとはせずに例外を無視したり、リトライを試みる、などです。このような例外ハンドリングをする場合は、その例外の型を知っておかなければなりません。実装(ロジック)を記述しない(しなくて良い)と言う点です。例外ハンドリングはDaoではできず、その呼び出し元であるビジネスロジックで行なうことになります。言う事は、ビジネスロジックが例外の型を知っておく必要があり、ビジネスロジックがS2DaoのAPIに依存してしまうことになります。J2EEのWebアプリケーションで一般的な多層アーキテクチャでは各層の依存関係を持たせたくないので、上記のようにビジネスロジック層がデータアクセス層の実装に依存してしまうのは望ましくないと思っています。はて、どうしたものか。思っていたのですが、S2AOPのThrowsInterceptorを使うことを思いつきました。上記のようなS2Dao固有の例外をキャッチし、抽象的な例外でラップして送出します。DaoException(e);}}のような感じです。ここで送出しているDaoExceptionはアプリケーションで独自に定義した例外で、S2Dao等の特定のプロダクトに依存しません。このアスペクトをDaoに設定するdiconファイルは以下のようになります。--><aspect>s2DaoThrowableInterceptor</aspect><aspect>dao.interceptor</aspect></component></components>※S2Daoへのアスペクトの追加は、dao.interceptorより前に記述しないと追加したアスペクトが機能してくれませんでした。することで、ビジネスロジック層ではDaoExceptionを受け取ることになり、S2Dao固有の例外を意識しなくて済むはずです。シンプルな方法がありそうな気も。コメント:0DIコンテナの価値・メリット昨今のJavaによるシステム開発(特にWebアプリケーション)では、DIコンテナの使用が当たり前のようになってきています。今回、僕が参画したプロジェクトでも、Seasar2の採用を検討しています。ここで周囲の人から「DIコンテナって何がうれしいの?」という質問が。うーむ、すぐに思いつくところでは、1.オブジェクト間の直接的な依存関係を排除でき、オブジェクトの再利用性や保守性が高まる。2.アスペクト指向技術との組み合わせによって、トランザクション管理と言った非業務ロジックを任せることができる。3.インターフェースベースの設計が促進され、オブジェクトの責務が明確化すると共にシステムの品質向上に繋がる。4.モックやスタブへの切替えが用意になり、ユニットテストがし易くなる。言ったところでしょうか。他の類フレームワーク...MVCフレームワークやO/Rマッピングフレームワークなど...に比べると効果が直感的にわかりにくいです。ある程度、Javaでの開発経験があれば理解してもらえますが、そうではない人(マネージャや業務SEの方)にはなかなかDIコンテナの利点を理解してもらえません。良い設計ができてこそ効果を発揮するのではないかと言う事です。(DIコンテナに限らず、何でも使えば良いってものではないですが)再利用性や拡張性、保守性を高めようと設計していくと、自ずとオブジェクト間の依存関係を弱めようと考えます。インターフェースを使うことで、オブジェクト同士の結合度を下げようとするわけです。インターフェースを利用しても、必ずどこかにオブジェクトの依存関係を記述しなければなりません。Methodといったデザインパターンを使うことで、この「依存関係を記述する場所」を一元化していたのですが、それでもプログラムに依存関係を埋め込むことには変わりありません。そこで、DIコンテナを使いたいと言う動機が産まれます。DIコンテナを使えば、DIコンテナの定義ファイルに依存関係を記述するので、プログラムからは依存関係の記述を排除できます。このように、「良い設計とは何か」「それを実現するにはどうするか」と言うストーリーを理解してはじめてDIコンテナの価値がわかるのではないかと思います。逆に、良い設計ができなければ、DIコンテナのメリットを充分に活かすことができません。DIコンテナを使うには、多層アーキテクチャや、J2EEパターン、アーキテクチャパターンなどの知識も必要になってくるのではないでしょうか。コメント:2プロフィールAuthor:crossroad関西在住。フリーランスのソフトウェアエンジニア。エレキベース(Rock&Roll)とお酒が好物でございます。