2009년 9월 6일 일요일

[Struts] SSL Extention

内部でSessionを使う場合があるようだ。getSessionで検索。

などに含まれる。


リダイレクト時の条件判定に気になるコメントが。

// Must also check ports, because of IE multiple redirect problem
if (!desiredScheme.equals(usingScheme) || !desiredPort.equals(usingPort))

IE multiple redirect problemって何だろう? コードを見た感じ、IEスキームが正しく設定されない場合がある?CVSを見ると最初からこのコードがある。

[struts] validatewhen

マニュアルに載ってる例。

    <field property="nbaPointGuard" depends="validwhen">
      <arg0 key="careers.nbaPointGuard.label"/>
        <var>
          <var-name>test</var-name>
          <var-value>((heightInInches >= 60) or (*this* == null))</var-value>
        </var>
      </field>

[お仕事][Struts]validateWhen

ユーザガイド*1によると、validationで"requiredif"ではなく"validwhen"が推奨されるようだ。


使い方は簡単で、このように"=="で条件を書くことができる。

<field property="emailAddress" depends="validwhen">
      <arg0 key="userinfo.emailAddress.label"/>
        <var>
          <var-name>test</var-name>
          <var-value>((sendNewsletter == null) or (*this* != null))</var-value>
        </var>
      </field>

注意しなければならないのは、この条件を満たす時はチェックOKということで、決してNGの条件を書くわけではない。


"Aがnullではないならば、このフィールドもnullではない"ことのチェック

 ○:((A == null) or (*this* != null))
 ×:((A != null) and (*this* != null))

あー、情報処理試験でいつも飛ばしておく論理式だな、こりゃ。


しばし悩んだのがこのエラー。

line 1:50: expecting RPAREN, found 'and' at antlr.Parser.match(Parser.java:213)

原因は、こういうことらしい。

A few quick notes on the grammer.

  • All comparisons must be enclosed in parens.
  • Only two items may be joined with <code>and</code> or <code>or</code>
  • If both items to be compared are convertable to ints, a numeric comparison is done, otherwise a string comparison is done.

<var-value>(((A == null) and (B == null) and (C == null)) or (*this* != null))</var-value>

という記述はまかりならんということか。

正しい記述。

<var-value>((((A == null) and (B == null)) and (C == null)) or (*this* != null))</var-value>


・・・メンドクサ!

2009년 9월 5일 토요일

http://s2container.seasar.org/2.4/ja/setup.html

Doltengを使う場合

Seasar2を最も簡単に試すには、Eclipseを使うのがお勧めです。 次のソフトウェアをインストールしておきます。

  • JDK5.0
  • Eclipse3.2
  • Tomcat5.5
  • Tomcat Launcher3.2.1
  • Dolteng
  • DbLauncher
  • 日本語でプロパティファイルを入力するためのプラグイン (任意)

JDK5.0をこのリンクから指示に従ってインストールします。 既にインストール済みの場合はその必要はありません。 次にJDK1.5がPCのデフォルトのJavaになっているのか確認します。 コマンドプロンプトからjava –versionを実行してください。

D:\USER\workspace2\teeda<java -version
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)

上記のようにバージョンが1.5.0_xxxのように表示されればOKです。 もし、OKでない場合は、環境変数のJAVA_HOMEとPATHを確認してください。

Eclipseのバージョン3.2をこのリンクから指示に従ってインストールします。 既にインストール済みの場合はその必要はありません。 標準のJDKのバージョンが1.5系でない場合、Eclipseの起動引数に

eclipse.exe -vm "C:\Program Files\Java\jdk1.5.0_07\bin\javaw.exe"

のように1.5系のjavaw.exeを指定する必要があります。

Tomcat5.5.xをこのリンクから指示に従ってインストールします。 既にインストール済みの場合はその必要はありません。

DoltengとDbLauncherは、Seasarプロジェクトで開発されているEclipse用のPluginです。 Tomcat LauncherはSysdeo社が開発しているPluginですが、Seasarプロジェクトの更新サイトからインストールすることが出来ます。Eclipseのメニューから[Help] -> [Software Updates] -> [Find and Install…]を選択し、 Install/Updateのダイアログを表示させます。 [Search for new features to install]のラジオボタンをチェックして[Next]ボタンをクリックします。 [New Remote site]ボタンをクリックして[Name]を[Seasar Plugin3.2]、 [URL]に[http://eclipse.seasar.org/updates/3.2/]を入力して[OK]をクリックします。 [Finish]ボタンをクリックするとインストールする候補として、 DoltengとDbLauncher、Tomcat Launcherが出てくるので、これらをチェックしてインストールしましょう。 既にインストール済みの場合はその必要はありません。

インストールが終わったら、Tomcat Launcherの設定を行います。 メニューの[Window] -> [Preferences…] -> [Tomcat]を選択してください。 Tomcatバージョンにバージョン5.xを選択し、Tomcatホームにインストールしたディレクトリを指定します。 コンテキスト宣言モードにコンテキストファイルを選び、[OK]をクリックします。

これで、Tomcat Launcherの設定は完了しました。 早速、Tomcatを起動してみましょう。メニューから[Tomcat] -> [Tomcat起動]を選択して、Tomcatを起動します。 エラーなしに無事に起動したのを確認して、一旦、Tomcatを停止させましょう。 メニューから[Tomcat] -> [Tomcat停止]を選択します。

日本語でプロパティファイルを入力するためのプラグインとしてプロパティエディタを このリンクから指示に従ってインストールします (必須ではありません)。 既にインストール済みの場合は、その必要はありません。

すべてのインストールがうまく行ったかどうかを確認するために、Hello Worldと表示する単純な画面を作ってみましょう。 Eclipseのメニューから[File] -> [New] -> [Project]を選びます。 図1のようなダイアログが表示されるので、[Chura Project]を選択します。




[Next]のボタンをクリックしてください。 図2のように、[Project name]に[chura-tutorial]、 [Root Package Name]に[tutorial.chura]と入力し、 JREコンテナーが[Use Default JRE(1.5)]になっていることを確認します。




[Project type]に[Super Agile(Teeda + S2Dao)]を選択し、 [Finish]ボタンをクリックしてください。chura-tutorialのプロジェクトが作成されます。

プロジェクトを右クリックして、[Tomcatプロジェクト] -> [Tomcatのコンテキストを更新]を選択します。 これで開発を始めるための必要な設定は完了しました。 メニューから[Tomcat] -> [Tomcat起動]を選択して、Tomcatを立ち上げます。 HOT deployで開発するので、アプリケーションサーバを起動したままで開発することが可能です。

プロジェクトのツリーを開き、src/main/webapp/viewを右クリックして[New] -> [File]を選びます。

[Enter or select the parent folder]に[chura-tutorial/src/main/webapp/view/hello]と入力し、 [File name]に[hello.html]と入力して、[Finish]ボタンをクリックします。

ファイルが作成されたので、Package Exploreからhello.htmlを右クリックして[Open With] -> [Text Editor]を選びます。 次のようにHTMLを入力してください。

<html>
<body>
Hello World
</body>
</html>

入力が終わったら、hello.html を右クリックして、[Dolteng] -> [View on Server]を選びましょう。 http://localhost:8080/chura-tutorial/view/hello/hello.htmlにアクセスするはずです。 無事にHello Worldと表示されたらプロジェクトの設定はうまくいっています。

Doltengを使わない場合

Doltengを使わないSeasar2の設定方法は次のようになります。

S2-Framework

Seasar2の基本機能(S2Container, S2AOP)を利用する場合には、S2.4.x.zipを解凍してできたseasar2ディレクトリの以下のファイルをCLASSPATHに含める必要があります。

  • lib/s2-framework-2.4.x.jar
  • lib/aopalliance-1.0.jar
  • lib/commons-logging-1.1.jar
  • lib/javassist-3.4.ga.jar
  • lib/ognl-2.6.9-patch-20070624.jar
  • lib/geronimo-j2ee_1.4_spec-1.0.jar (オプション、非J2EE環境で使う場合)
  • lib/portlet-api-1.0.jar (オプション、Portletを使う場合)
  • lib/log4j-1.2.13.jar (オプション、Log4Jを使う場合)
  • resources/log4j.properties (オプション、Log4Jを使う場合)
  • resources/convention.dicon (オプション、「SMART deploy」を使う場合)
  • resources/creator.dicon (オプション、「SMART deploy」を使う場合)
  • resources/customizer.dicon (オプション、「SMART deploy」を使う場合)

S2-Extension

Seasar2の拡張機能(S2JTA, S2DBCP, S2JDBC, S2Unit, S2Tx, S2DataSet)を利用する場合には以下のファイルを追加でCLASSPATHに含める必要があります。

アプリケーションの実行環境により、J2EE関連Jarファイルのいずれが必要になるかが異なります。

S2JTAまたはS2Txを使う場合

アプリケーションの実行環境により、geronimo-jta_1.1_spec-1.0.jarまたはgeronimo-jta_1.1_spec-1.0-tsr.jarが必要になります。

環境geronimo-jta_1.1_spec-1.0.jargeronimo-jta_1.1_spec-1.0-tsr.jar
Servlet対応のWebコンテナ
(Tomcat等)
J2EE1.4対応のAPサーバ-
JavaEE5対応のAPサーバ--
スタンドアロン-

S2TxでEJB互換機能を使う場合

アプリケーションの実行環境により、geronimo-ejb_2.1_spec-1.0.jarが必要になります。

S2-TigerでEJB3を使う場合は必要ありません.

環境geronimo-ejb_2.1_spec-1.0.jar
Servlet対応のWebコンテナ
(Tomcat等)
J2EE1.4対応のAPサーバ-
JavaEE5対応のAPサーバ-
スタンドアロン

S2Container用のプラグインKijimunaも是非ご利用ください。

S2-Tiger

Java5対応機能を使いたい場合は、S2Tiger-2.4.x.zipを解凍してできたs2-tigerディレクトリの以下のファイルをCLASSPATHに含める必要があります。

オプションのJarファイルは、S2JDBCやEJB3、JPAのサポート機能をJavaEE5対応でない環境で使う場合に必要となります。詳細は以下の表を参照してください。

@Resourceを使う場合

アプリケーションの実行環境により、geronimo-annotation_1.0_spec-1.0.jarが必要になります。

環境geronimo-annotation_
1.0_spec-1.0.jar
Servlet2.4対応のWebコンテナ
(Tomcat5.x等)
 (JavaSE6以降は不要)
Servlet2.5対応のWebコンテナ
(Tomcat6等)
-
J2EE1.4対応のAPサーバ (JavaSE6以降は不要)
JavaEE5対応のAPサーバ-
スタンドアロン (JavaSE6以降は不要)

S2JDBC拡張機能またはJPAを使う場合

アプリケーションの実行環境により、gegeronimo-jpa _3.0_spec-1.0.jarが必要になります。

環境geronimo-jpa _3.0_spec-1.0.jar
Servlet対応のWebコンテナ
(Tomcat等)
J2EE1.4対応のAPサーバ
JavaEE5対応のAPサーバ-
スタンドアロン

EJB3を使う場合

アプリケーションの実行環境により、geronimo-ejb_3.0_spec-1.0.jar、geronimo-interceptor_3.0_spec-1.0.jarが必要になります。

環境geronimo-ejb_
3.0_spec-1.0.jar
geronimo-interceptor_
3.0_spec-1.0.jar
Servlet2.4対応のWebコンテナ
(Tomcat5.x等)
Servlet2.5対応のWebコンテナ
(Tomcat6等)
J2EE1.4対応のAPサーバ
JavaEE5対応のAPサーバ--
スタンドアロン

2009년 9월 2일 수요일

the difference from class#getResource and ClassLoader#getResouce

public static Properties getProperties(String filePath) throws IOException{
  //ClassLoader로 InputStream 생성  
  //InputStream is = ClassLoader.getSystemResourceAsStream(filePath);
  InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
  Properties props = new Properties();
  props.load(is);
  return props;
}


getClass().getResourceAsStream(filePath) 와 같음.

단 getClass().getResourceAsStream(filePath) 는 static context에서 사용할 수 없음.


Class::getResource(name) 와
ClassLoader::getResource(name) 은 차이가 있다.

ClassLoader.getResource(name)의 'name'은 '/'로 시작할 수 없고 항상 상대경로로 인식한다.
반면 Class.getResource(name)의 'name'은 '/'로 시작해야만 절대경로가 된다.


Class#getResource と ClassLoader#getResource の違いと怪しさ

Java の実装の話です。

設定ファイルやら相対パスを使ったリソース参照のために、よく getResource() や getResourceAsStream() を用います。
これらに与えるリソース名について Class#getResource() のドキュメントでは以下のような説明がされています。

委譲の前に、このアルゴリズムを使って指定されたリソース名から絶対リソース名が構築されます。

  • name が「/」(「\u002f」) で始まる場合、リソースの絶対名は「/」に続く name の部分である
  • そうでない場合、絶対名は以下の形式になる
    modified_package_name/name
    ここで、modified_package_name は、「. 」(「\u002e 」) を「/」に置き換えたこのオブジェクトのパッケージ名になる

これは実装を忠実に表しています。しかし ClassLoader#getResource() のほうではどのような記法でどこからロードを行うかは記載されていません。ClassLoader は抽象クラスであり、どのように検索を行うかは記述できないのです。ただ、先頭の / の扱いに関しては規定しておいて欲しかった…。

Class#getResource() でも最終的には ClassLoader#getResource() が呼び出されます。しかし、このメソッド自体が、クラスローダの実装によって振る舞いが異なるという問題があります。

リソース名の先頭に "/" を書くか書かないかと、Class#getResource() を呼ぶか ClassLoader#getResource() を呼ぶかで、Sun の JDK(1.4/1.5) に付属の ClassLoader 実装では以下のような挙動になります。

Class#
getResource()
ClassLoader#
getResource()
"/name"ルートから name を検索見つからない
"name"クラスのパッケージディレクトリ相対で name を検索ルートから name を検索

さて、皆さんこのあたりはご存知だったでしょうか?

ClassLoader#getResource() で "/" から始まるパスを指定した場合は有無を言わさずリソースが見つかりません。これはバグとしか思えませんが、ClassLoader#getResource() の検索仕様は明確に決められていないので、仕様ということもできてしまいます。
(ちなみに実装がどうなっているかというと、ディレクトリベースの場合は new URL(baseDirUrl, "/name") という処理が行われ、この結果が壊れます。jar の場合は JarEntry の取得に失敗します)

また、Class#getResource のような振る舞いを期待して ClassLoader#getResource() を呼び出してしまうと、クラスの位置ではなくクラスパスのルートからの相対になるため、謎のバグに見舞われたり、混乱を招いたりします。

これだけならまだいいのですが、アプリケーションサーバなどで独自のクラスローダを用いているものでは、先頭が "/" であっても取得できてしまったりすることがあります(orion server 等で確認)。未確認ですが、先頭の "/" がないと取得できないようなものがもし存在すると、JDK との間のポータビリティが完全に失われます。

最も安全なのは、常に Class#getResource() を用いるということです。これならクラスローダ実装の差異を吸収してくれます。
この場合、相対指定のときにどのパッケージディレクトリになるかというのが、対象の Class クラスによって変わるので、深く考えずに getClass().getResource("相対パス") と書く癖があると落とし穴にはまるかもしれませんのでそこだけはご注意を。

この整理を試みたのは、hibernate が内部的に ClassLoader#getResource() を使ってマッピングファイル読み込みを行っていることが原因で、先頭に "/" を書いていて、且つスタンドアローンでの dbunit での起動時のみマッピングファイルが読み込めないといった現象になったためです。hibernate が Class#getResource() を使っていてくれるか、あるいは JDK のバグとして仕様の明確化&Sun 実装の修正がなされれば良いわけですね。

また、おまけになりますが、ClassLoader#getResource() の場合、検索のルートディレクトリより上位にあるリソースは取得できませんが、URL#getFile() を利用すると、物理パスを取得できるので、書き出し用ディレクトリの取得もできたりします。ただし、この方法でディレクトリを見つける場合は、クラスパスに複数ディレクトリが設定されると危険であるということを念頭におく必要があります。

Seasar j2ee.dicon transaction type (Required, RequiredNew)

トランザクションの自動制御

S2Txの機能を使い、POJO(普通のJavaのクラス)に対して、 トランザクションの自動管理機能を組み込むことができます。

トランザクション属性

Seasar2が標準で用意しているj2ee.diconには、 トランザクション属性に対応したAdviceが定義されています。 j2ee.diconはs2-extension-x.x.x.jarに含まれているので、 開発者のほうで用意する必要はありません。

これらのAdviceは、aspectタグアスペクトの自動登録SMART deployによるトランザクション設定 を使ってコンポーネントに適用します。

属性コンポーネント名説明
Requiredj2ee.requiredTxトランザクションが開始されていなければ、自動的にトランザクションを開始します。
既にトランザクションが開始されていれば、そのトランザクションを引き継ぎます。
トランザクションを開始した場合でも引き継いだ場合でも、 このインターセプタが適用されたメソッドが例外をスローした場合は、 例外の種類に応じてトランザクションがロールバックされるようにマークします。
デフォルトでは、全ての例外に対してロールバックされるようにマークします。
トランザクションを開始した場合、 このインターセプタが適用されたメソッドが 終了 (正常終了した場合および例外をスローした場合の両方) すると、 開始したトランザクションを完了 (コミットまたはロールバック) します。
トランザクションがロールバックするようにマークされていれば、 トランザクションをロールバックします。 そうでなければ、トランザクションをコミットします。
RequiresNewj2ee.requiresNewTx常に新しいトランザクションを開始させます。
既存のトランザクションが開始されているなら、既存のトランザクションを中断し、 自分自身のトランザクションの終了後、中断したトランザクションを復帰させます。
このインターセプタが適用されたメソッドが例外をスローした場合は、 例外の種類に応じてトランザクションがロールバックされるようにマークします。
デフォルトでは、全ての例外に対してロールバックされるようにマークします。
このインターセプタが適用されたメソッドが終了 (正常終了した場合および例外をスローした場合の両方) すると、 開始したトランザクションを完了 (コミットまたはロールバック) します。
トランザクションがロールバックするようにマークされていれば、トランザクションをロールバックします。 そうでなければ、トランザクションをコミットします。
Mandatoryj2ee.mandatoryTxトランザクションが既に開始されてなければエラーにします。
このインターセプタが適用されたメソッドが例外をスローした場合は、 例外の種類に応じてトランザクションがロールバックされるようにマークします。
デフォルトでは、全ての例外に対してロールバックされるようにマークします。
NotSupportedj2ee.notSupportedTx既存のトランザクションが開始されているなら、既存のトランザクションを中断します。
コンポーネントのメソッドの終了後、中断したトランザクションを復帰させます。

例外発生時の動作

デフォルトでは、コンポーネントが例外をスローした場合はトランザクションをロールバックするようにマークされますが、 発生した例外に応じてトランザクションをロールバックするようにマークするかしないかを指定することもできます。

  • addCommitRule(Class)メソッドを使用すると、 トランザクションをロールバックするようにマークしない例外を指定することができます。
  • addRollbackRule(Class)メソッドを使用すると、 トランザクションをロールバックするようにマークする例外を指定することができます。

コンポーネントから例外がスローされると、 addCommitRule()/addRollbackRule()が設定された順番にマッチするかチェックされます。 スローされた例外がaddCommitRule()/addRollbackRule()で指定された例外またはその派生例外であれば、 その設定に従ってトランザクションをロールバックするようにマークします。 スローされた例外がaddCommitRule()/addRollbackRule()で指定された例外とマッチしない場合、 トランザクションはロールバックするようにマークされます。

EJB互換のAdvice

Seasar2が標準で用意しているejbtx.diconには、 EJBのコンテナ管理トランザクション (CMT) と同じように実行時例外 (java.lang.RuntimeException)、 リモート例外 (java.rmi.RemoteException) とその派生例外が発生した場合はロールバックし、 その他の例外 (java.lang.Exception) が発生した場合はコミットするAdviceが定義されています。 ejbtx.diconはs2-extension-x.x.x.jarに含まれているので、 開発者のほうで用意する必要はありません。

属性コンポーネント名
Requiredejbtx.requiredTx
RequiresNewejbtx.requiresNewTx
Mandatoryejbtx.mandatoryTx
NotSupportedejbtx.notSupportedTx

EJB3互換のAdvice

Seasar2が標準で用意しているejb3tx.diconには、EJB3のコンテナ管理トランザクション (CMT) と同じように、@javax.ejb.ApplicationException アノテーションの rollback 要素で true が指定されたアプリケーション例外 (java.lang.Exception) および、 実行時例外 (java.lang.RuntimeException)、 リモート例外 (java.rmi.RemoteException) とその派生例外が発生した場合はロールバックし、 その他の例外が発生した場合はコミットするAdviceが定義されています。 ejb3tx.diconはs2-tiger-x.x.x.jarに含まれているので、開発者のほうで用意する必要はありません。

属性コンポーネント名
Requiredejb3tx.requiredTx
RequiresNewejb3tx.requiresNewTx
Mandatoryejb3tx.mandatoryTx
NotSupportedejb3tx.notSupportedTx

SMART deployでの利用

SMART deploy環境でトランザクションの自動制御を利用する場合の設定については、 「DI Container」-「トランザクション制御を設定する」を参照してください。

eclipse speedy startup Tip!!

from: http://www.raibledesigns.com/page/rd/20030312
I changed my shorcut icon (Win2K) to have the following as it's target:

eclipse.exe -vmargs -Xverify:none -XX:+UseParallelGC -XX:PermSize=20M -XX:MaxNewSize=32M -XX:NewSize=32M -Xmx256m -Xms256m

Eclipse now starts in a mere 6 seconds (2 GHz Dell, 512 MB RAM). Without these extra settings, it takes 11 seconds to start. That's what I call a performance increase! (2003-03-12 09:32:04.0)

from: http://www.raibledesigns.com/comment.do?method=edit&entryid=065039163189104748672473500018
I tried this out, but the memory settings don't seem to have anything to do with startup time.
18 seconds - "eclipse.exe"
13 seconds - "eclipse.exe -vmargs -Xverify:none"
12 seconds - "eclipse.exe -vmargs -Xverify:none -XX:+UseParallelGC -XX:PermSize=20M -XX:MaxNewSize=32M -XX:NewSize=32M -Xmx96m -Xms96m"

It's only the Xverify:none parameter which has a noticeable effect on reducing startup time. On the java website I found that this parameter turns off bytecode verification ( http://developer.java.sun.com/developer/onlineTraining/Security/Fundamentals/Security.html ), although the default is supposedly "only verify classes loaded over the network".