JDNI/ developing applications that use JNDI

configure JNDI caches
JNDI caching can greatly inrease performance of JNDI lookup operations. By default, JNDI caching is enabled.
JNDI clients can use several properties to control cache behavior.
1.
from the command line by entering the actual string value.
ex.
java -Dcom.ibm.websphere.naming jndicache.maxentrylife=1440
2.
in a jndi.properties file by creating a file names jndi.properties as a text file with the desired properties settings.
ex.
com.ibm.websphere.naming.jndicache.cacheobject=none
3.
within a java program by using PROPS_JNDI_CACHE java constants, defined in the com.ibm.websphere.naming.PROP file.
java.util.Hashtable env = new java.util.Hashtable();
...

// Disable caching
env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE); ...
javax.naming.Context initialContext = new javax.naming.InitialContext(env);

sample:
import java.util.Hashtable;
import javax.naming.InitialContext;
import javax.naming.Context;
import com.ibm.websphere.naming.PROPS;

/*****
Caching discussed in this section pertains to the WebSphere Application
Server initial context factory. Assume the property,
java.naming.factory.initial, is set to
"com.ibm.websphere.naming.WsnInitialContextFactory" as a
java.lang.System property.
*****/

Hashtable env;
Context ctx;

// To clear a cache:

env = new Hashtable();
env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_CLEARED);
ctx = new InitialContext(env);

// To set a cache's maximum cache lifetime to 60 minutes:

env = new Hashtable();
env.put(PROPS.JNDI_CACHE_MAX_LIFE, "60");
ctx = new InitialContext(env);

// To turn caching off:

env = new Hashtable();
env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE);
ctx = new InitialContext(env);

// To use caching and no caching:

env = new Hashtable();
env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_POPULATED);
ctx = new InitialContext(env);
env.put(PROPS.JNDI_CACHE_OBJECT, PROPS.JNDI_CACHE_OBJECT_NONE);
Context noCacheCtx = new InitialContext(env);

Object o;

// Use caching to look up home, since the home should rarely change.
o = ctx.lookup("com/mycom/MyEJBHome");
// Narrow, etc. ...

// Do not use cache if data is volatile.
o = noCacheCtx.lookup("com/mycom/VolatileObject");
// ...


specify the name syntax
INS syntax is designed or JNDI clients that need to interoperate with CORBA applications. this syntax
allows a JNDI client to make the proper mapping to and from a CORBA name. INS syntax is very similar to the JNDI syntax with the additional special character, dot(.). dots are used to delimit the id and kind fields in a anme component. a doc is interpreted literally when it is escaped. only one unescaped dot is allowed in a name component. a name component with a non-empty is field and empty kind field is represented with only the id firld value and must not end with an unescaped dot. and empty name component is represented with a single nescaped dot. an empty string is not a valid name component represntation.



XXX

ref:
JNDI を使用するアプリケーションの開発
http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tnam_develop_naming.html

tag : JNDI XXX

2011-08-06 07:03 : j2ee : コメント : 0 : トラックバック : 0 :

J2EE/ JNDI/ リソース参照

JNDIネームスペースはセルを頂点とするツリー構造になっている
(=WAS管理モデルのセル-ノード-サーバの関係と同様)

JNDIの名前は3種類ある
JNDI完全修飾名
JNDIシンプル名
JNDI ENC名

JNDI完全修飾名
コンテキスト名を上位のものから"/"で区切って表記する
ただし
ノード・コンテキスト名の前には"nodes/"を入れ
サーバ・コンテキスト名の前には"servers/"を入れる
ex.
was3NetWork/nodes/was2/servers/server1
(was3NetWorkというセルの下のwas2というノードの下のserver1というサーバ)
WAS V5.xでは
セル名を"cell"で置換できるので
cell/nodes/was2/servers/server1
ともできる
このセルレベルからコンテキストを順に記述したものがJNDI完全修飾名(compound名)
クラスタ構成であれば
cell/clusters/{クラスタ名}
となる

JNDIシンプル名
jdbc/NantokaDataSourceみたいな書き方のこと
lookupする側のAPが稼動するプロセス内でのみ有効な名前

JNDI ENC名
"java:comp/env/jdbc/NantokaDataSource"みたいに"java:comp:env"で始まる書き方のこと
コレが推奨される書き方
DataSource dc = (DataSource) ictx.lookup("java:comp/env/jdbc/NantokaDataSource");
な具合にlookupする
ENC は environment naming context(環境ネーミングコンテキスト) で
lookupする側のWebアプリ(*.war)やEJB-JAR(*.jar)内でのみ有効なネームスペースに定義される

※ JNDIでのlookupは何度行っても結果は同じなので初期化時に取得するのが一般的


作成したdatasourceはWASのJNDIネームスペースの何処にどのようにbindされているのか?
dumpNameSpace utilityを使うとサーバを示すコンテキストの直下にJDBCプロバイダで定義したdataソースがbindingされているのが分かる
(最上位)/nodes/was3/servers/jdbc/sample
てな具合
※ dumpNameSpace utility:
WASのJNDIネームスペースにバインドされたオブジェクト(contextとbinding)とlinkの一覧を表示するdumpNameSpace.[bat|sh]

完全修飾名はフルパスなのでlookup出来て当然
が同様にしてENC名でcell/nodes/was3/servers/jdbc/sampleをjava:comp/env/jdbc/sampleで取ることは出来ない
ENC命はAP内のみで有効なlocalなnamespaceに定義されているのに対し
datasourceはAP内のresourceでないために取れない
なので
ENC名からserver側のblobalなnamespaceで定義されたresourceを指す何らかの参照を持たせば良い
コレがJ2EE仕様のリソース参照(resource reference)の背景


リソース参照を定義するためには?

WASに添付のAAT(application assembly tool)を使用するか
WebSphere StudioのDD(deployment descriptor : 配置記述子)エディタを使用する
※ 後者はweb.xmlに記述されるやり方

リソース参照を定義したらそのAPをデプロイする
途中の「リソース参照をリソースにマップ」リソース参照がbindingされる


ENC名+リソース参照を利用するメリットは?

完全修飾名にはセルのトポロジーに依存するだけでなく
was3やserver1のようにノード名やサーバ名に依存するコンテキスト名が含まれる
JNDI完全修飾名を使用していた場合
開発から運用の間に環境が変わるとAPのコード修正と再コンパイルが必要になる
一方
JNDI END名とリソース参照 なら
APの外部でリソースとのmappingが出来るためコード修正も再コンパイルも要らない
というのがメリット


ref:
今さら人に訊けないJNDI: 第2回 「リソース参照って何ですか?」
http://www.ibm.com/developerworks/jp/websphere/library/was/was_jndi/2.html

tag : JNDI リソース参照

2011-08-02 01:44 : j2ee : コメント : 0 : トラックバック : 0 :

Java Servlet

■サーブレットの生い立ち

Java Servlet
Webサーバ(HTTPサーバ)をJavaアプリケーション・サーバに変身させるJavaテクノロジである
そのため
Java Servletは必ずといってよいほどCGIと比較される


CGIプログラムは
基本的に1つのプロセスで動作する
入力として環境変数(GET方式/PUT方式)または標準入力(PUT方式)を使い
結果として標準出力を使う
コマンドプロンプトで動作確認もできる
開発言語は Perl である


CGIの欠点
1. プロセス起動のためパフォーマンスが悪い
2. ステートレス(複数のリクエストにまたがってメモリ上でデータを維持できない)
3. コンピュータの機種によってPerlの互換性がない



Java Servletが登場


Java Servletの開発手順
ユーザー・プログラムを作成するときに
HttpServletクラスを継承したクラス(ユーザー・サーブレット)を作成する

ユーザー・サーブレットは
サーバ・プロセスである「サーブレット・エンジン」に
ユーザー・クラスとしてロードされ
基本的には1つの共通インスタンスを生成される
サーブレット・エンジンはそれ自身がJavaのプログラムである
該当サーブレットに対するHTTPリクエストは
このインスタンスに対してのスレッドとしてリダイレクトされる
これによって
HTTPリクエストの処理がユーザー・プログラムによって処理され結果がブラウザに送られる

この方法だと
プロセスの起動や終了処理がなく
スレッドであるため高速で
使用するリソースも少ない
さらに
インスタンスは一度ロードされるとメモリ上に維持されるため
アプリケーションの状態を維持することも可能である
これによりステートフルな技術であるといわれている
また
Javaで非常に高い移植性を発揮する

サーバ・プロセスであるサーブレット・エンジンがユーザー・サーブレットを呼び出すルール
1. リクエストに対するサービス・メソッドが定義されているか確認する
GETリクエストに対してはdoGetメソッド
POSTに対してはdoPostメソッドといった具合
2. doXXXメソッドが1つでも定義されるのに
リクエストに合致するメソッドがない場合
そのリクエストはServletが処理できないことを意味する
3. doXXXメソッドが1つもなく
serviceメソッドがあれば それが呼ばれる

ユーザー・サーブレットは
サーバに呼び込まれた時
生成されたインスタンスが共通に使われるため
スレッド間で共有できるものはインスタンス生成時にinitメソッドで初期化しておく
initメソッドは
ServletConfigオブジェクトを引数にもらう
RDBにアクセスするときのJDBC-URLなど外部データは ServletConfigに詰めて サーブレットに渡す
ServletConfigは
サーブレットのクラスファイルと同じディレクトリにクラス名「.servlet」というファイル名でXML形式にて置く

終了処理はdestroyメソッドで行う


サンプル

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;public class EasyServlet extends

HttpServlet {
public void init( ServletConfig config ) throws ServletException {
super.init( config ); // 初期化処理
}

public void destroy() {
super.destroy(); // 終了処理
}

public void service( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println( "<'HTML>" );
out.println( " <'BODY>" );
out.println( " サーブレット!" );
out.println( " <'/BODY>" );
out.println( "<'/HTML>" );
}
}

旧来のJavaアプリケーション・サーバでは
サーブレットのクラスファイルはアプリケーション・サーバの特定のクラスパスに
JSP/HTML/JPG/GIFのようなコンテンツ・データは
HTTPサーバのドキュメント・ルートに置かれる
のがルール


J2EE対応サーバでは
これらのファイルはすべて*.WAR(Web Application Archive)といわれるJARファイルに入れる
のがルール


■セッション管理
Java Servlet にはセッション管理機能がある
ステートフルのからくりもコレ

Java Servlet の仕様は
Sun Microsystems社のJavaWebServer(JWS)で提供され
その後分離した仕様として公開された後
J2EEに吸収された
セッション管理は
JWS 1.1 alpha時代に追加された概念

XXX

tag : Java Servlet XXX

2009-10-28 23:50 : j2ee : コメント : 0 : トラックバック : 0 :

JTA/JTS

JTA/JTS
Java Transaction API / Java TransactionService
J2EEアーキテクチャにトランザクション処理サービスを提供する

J2EE仕様には
JTAは必須とあるが
JTSは実装の1つの選択とある


JTSのトラン・マネージャ
トランザクション・マネージャは
トランザクションの開始/完了/コミット/ロールバック管理する

JTSのトランザクション・マネージャの機能
* アプリとアプリサーバにトランザクションのスコープと存続期間の操作性を提供する
* シングルトランザクションに対して複数のアプリケーションやコンポーネントの包含を可能にする
* グローバルトランザクションをサポートするリソース・マネージャとの連携
* 複数のリソース・マネージャとの通信を伴うグローバルトランザクションの実行と完了
* トランザクション同期のサポート
* ほかのトランザクション・マネージャとの連携

J2EE SDKではJTSに基づくトランザクション・マネージャの実装が提供されていてる



JTAトランザクション
主に3つの要素で構成さる
1
アプリからトランザクションの境界設定やトランザクション管理を実行するためのjavax.transaction.UserTransactionインタフェース
主にWebアプリやBean管理のトランザクションを持つEJBで使用する
2
トランザクション・マネージャがアプリのトランザクションの境界設定や
トランザクションの管理を行うためのjavax.transaction.TransactionManagerインターフェイス
主にコンテナ管理のトランザクションを持つEJBのEJBコンテナによって使用される
3
トランザクション・マネージャがXA準拠リソースのリソース・マネージャと連携するためのjavax.transaction.xa.XAResourceインターフェイス


JTAトランザクションは
複数のコンポーネントやリソース・マネージャ間にまたがることのできるトランザクション
そのため
分散アプリケーションとして
非常に柔軟かつ複雑なトランザクション処理を開発できる
しかし
本来トランザクションが持つべきACID属性をシステムとして確実に実現するためには
極力アプリケーションサーバにトランザクション処理を任せた方が無難
そのために
アプリケーションサーバは自動的にトランザクション処理を実行できるよう
属性をEJBにセットするだけでJTAトランザクションを操作できるしくみ
―コンテナ管理によるトランザクション境界の設定―
を提供している

また
JTAトランザクションをプログラミングによって利用するには
JTAのjavax.transaction.UserTransactionインターフェイスを使用する


■EJBでのトランザクション
EJBには
Bean管理によるものと
コンテナ管理によるもの
の2種類のトランザクション境界設定がある
□コンテナ管理によるトランザクション境界設定
6つのトランザクション属性
(Required, RequiresNew, NotSupported, Supports, Mandatory, Never)
をEJBのメソッドに関連付けられる

コンテナ管理によるトランザクション境界設定を使うEJBの場合
EJBコンテナがトランザクション境界を管理する
EJBが実行される際
メソッドのトランザクション属性によって
どのようなトランザクション管理をEJBコンテナで行う必要があるかがコントロールされる

コンテナ管理によるトランザクション境界設定を使用する利点
* EJBのトランザクション動作は
プログラムではなく、宣言によって指定される
これにより、アプリケーションコンポーネントプロバイダは
トランザクション境界設定コードをコンポーネント内に作成する必要がなくなり
コンポーネントとしての独立性を高めることができる
* トランザクション境界設定をEJBコンテナに任せるので信頼性を向上できる
* EJBを再利用する場合に、用途に応じてトランザクション属性を変更し活用することができる

□Bean管理によるトランザクション境界設定
EJBはJTAのjavax.transaction.UserTransactionインターフェイスを使用して
トランザクション境界を明示的に設定する
選択できるのは
セッションBeanだけ
※ エンティティBeanは 常にコンテナ管理によるトランザクション境界設定を使用する必要がある


Bean管理トランザクション境界設定を使ったJTAインターフェイスの使用法
UserTransactionオブジェクトは
EJBContext.getUserTransactionでlookupされ 使用される
UserTransaction ut = ejbContext.getUserTransaction();
ut.begin();
// perform transactional work here
ut.commit();


■Webアプリのトランザクション
Webアプリ(JSP、Servlet)は
EJBのようなJTAの緊密な連携は持っていないため
JNDIを使ってUserTransactionオブジェクトをルックアップしてから
UserTransactionインターフェイスを使ってトランザクションを境界設定する

Context ic = new InitialContext();
UserTransaction ut =
(UserTransaction) ic.lookup("java:comp/UserTransaction");
ut.begin();
// perform transactional work here
ut.commit();

Webアプリでトランザクション処理を実装する場合
トランザクションの伝播と状態の遮断等に注意すること


アプレット/アプリクライアントでのトランザクション
アプレットやアプリケーションクライアントのトランザクションUserTransaction使えばサポート可能
アプレットやアプリクライアントがUserTransactionオブジェクトに直接アクセスできるか
コンテナで提供される機能次第


■JMSとトランザクション
J2EE1.3では
アプリケーションサーバは
JMSサービスをトランザクションで連携するリソース・マネージャとしてサポートする


■JCAとトランザクション
J2EE1.3では
アプリケーションサーバは
JCAもリソース・マネージャとしてサポートする
JCAのリソースアダプタは
JTAのXATransactionインターフェイスの実装している必要あり


ref:
Javaを紐解くための重点キーワード:JTA/JTS
http://www.atmarkit.co.jp/fjava/keyword/jkey/jkey05.html

tag : JTA JTS

2009-10-27 23:53 : j2ee : コメント : 0 : トラックバック : 0 :

Timer and Work Manager API

TimerWorkManager
Oracle (bea) と IBMが共同作成した仕様。
TimerWorkManagerで、JavaEEアプリ内にEJBとサーブレットを同時プログラミングが可能になる。
※別名称をCommonJ。

CommonJ Timer API は、
作業を特定の間隔でスケジューリングする場合を想定したAPI。
CommonJ Work API は、
作業を優先順位に基づいて処理する場合を想定したAPI。

Timer API @commonj.timer package
アプリ内に定義された特定のリスナに対し、
アプリでタイマー通知コールバックをスケジューリングして受信できる。

Work Manager API @commonj.work
アプリでEJBまたはServlet内の作業の優先順位を決められる。
アプリは、複数の作業項目をコンテナ内部でプログラム的に実行できる。

Timer API
IF:
TimerManager
 管理対象の環境においてタイマーを作成及び使用するためのスレッドセーフなIFで
 アプリ内の全般的なスケジューリングする。
 デプロイメント記述子に定義すると
 そのインスタンスはローカルJava環境でJNDIルックアップでアクセス可能で、
 lookup()する度、TimerManagerの新しい論理インスタンスが返される。
 ※1アプリに複数のTimerManagerインスタンスを設定できる。
 TimerManager.schedule()でTimerListenerを特定の時刻に/間隔で実行するよう
 スケジューリングする。
 ―TimerManagerの中断/再開/停止
   TimerManager.suspend(): 中断
   ※中断中のタイマーは再開されるまで保留される。
   TimerManager.resume(): 再開
   TimerManager.stop(): 停止 (全アクティブタイマーの停止)
   ※stop()されたTimerManagerインスタンスは
    全てのTimerListenerインスタンスのモニタを停止する。
*TimerListener
 タイマー通知を受信するIFで、開発者が実装する。
*Timer
 TimerManagerを介してタイマーがスケジューリングされた時に返される。
 ローカルタイマーとクラスタワイドタイマーがある。
 -ローカルタイマー
  単一のサーバJVM内でスケジューリングされる。
  JVMが動作している限り動作し続け、JVMが終了すると失敗する。
 -クラスタワイドタイマー
  クラスタ内の各サーバを含む他のJVMを認識する。
  クラスタメンバの少なくとも1つが有効である限り、動作し続ける。
  ゆわゆるジョブスケジューラ。
  ※ジョブスケジューラでは以下メソッドはサポート外。
    -CancelTimerListener
    -StopTimerListener
    -TimerManager#suspend()
    -TimerManager#resume()
    -TimerManager#scheduleAtFixedRate()
    -TimerManager#stop()
    -TimerManager#waitForStop()
    -TimerManager#waitForSuspend()

□ジョブのキャンセル
ジョブは、プログラムまたは、AdministrationConsoleでキャンセルできる。
*プログラムでのキャンセル
 JobRuntimeMBean#cancel()を呼ぶ。
 *JobRuntimeMBeanの取得方法
   -方法1
     JobScheduler.schedule()で取得したTimerオブジェクトの
       toString()でID(スケジュールされたジョブID)を取得する。
     スケジュールされたジョブIDで
       JobSchedulerRuntimeMBean.getJob(id)を呼ぶ。
   -方法2
     JobSchedulerRuntimeMBean.getExecutedJobs()で
       少なくとも1回実行されたジョブのJobRunTimes配列を取得する。
 ※一度も実行されていないジョブはキャンセル出来ない。

□デバッグ
-Dweblogic.debug.DebugSingletonServices=true -Dweblogic.JobScheduler=true

Work API
1アプリ内での複数の作業項目の同時実行を可能にするAPI。
≒java.lang.Thread APIのコンテナ管理の代替機能。

IF:
WorkManager
*Work
*WorkItem
*WorkListener
*WorkEvent
*RemoteWorkItem

ref:
Timer and Work Manager API , dev2dev, Oracle / bea
http://otndnld.oracle.co.jp/document/products/wls/docs103/commonj/commonj.html

tag : Timer Work Manager WebLogic

2009-06-22 02:23 : j2ee : コメント : 0 : トラックバック : 0 :

NETWORK/ SOAP & IIOP

SOAP / Simple Object Access Protocol
XMLとHTTPなどをベースとした、他のコンピュータにあるデータやサービスを呼び出す為のプロトコル。
SOAPによって外部から利用可能な、部品化されたWebベースのアプリケーションソフトは「Webサービス」と呼ばれる。
インターネット上で各社が提供しているWebサービスを集め、誰でも検索・照会できるようにするWebサービスを「UDDI」という。

下位プロトコル:HTTP OR JMS

UDDI/ Universal Description, Discovery, and Ingegration
XMLを応用した、インターネット上に存在するWebサービスの検索・照会システム。
UDDIでは、登録情報は、WSDLというXMLベースの言語で定義され、通信にはXMLベースのプロトコルであるSOAPを用いているため、通常のWebブラウザなどの他、SOAPやXMLに対応した様々なアプリケーションソフトから利用できる。


IIOP / Internet Inter-ORB Protocol
分散オブジェクト技術の規格の一つであるCORBAに準拠して定められた、異なるORB間でメッセージを交換する為のプロトコル。
IIOPを使うと、インターネットなどのTCP/IPネットワークで接続された複数のコンピュータに分散配置されたオブジェクトと呼ばれるソフトウェア部品同士が、機種の違いやプログラミング言語の違いを超えて、互いにデータの受け渡しをしたり、処理を依頼したりすることが出来る。


ORB / Object Request Broker
異なるマシン上に分散して存在するオブジェクト(プログラム部品)間で、データや処理要求などのメッセージをやり取りする際に用いられる仲介ソフトウェア。
CORBAが標準仕様。


ref:
http://e-words.jp/

tag : SOAP UDDI WSDL IIOP ORB

2009-04-01 23:21 : j2ee : コメント : 0 : トラックバック : 0 :

Timer Manager API

■イントロ
Java EE環境で利用可能なタイマー機能を実現するFW。
Timerの設定に応じてcallback methodを呼び出してくれるため
時刻/時間を指定して処理を自動的に起動したいケースに便利なソリューション。

※似た機能で Java SEのクラスTimerがある。
 Java SE#TimerをJava EEで使うのは避けること。
 ∵Java SE#Timerは内部でThreadクラスをを使用しているため
  Timerクラスを利用したSスレッドはJava EEコンテキストに関連付けられないから。

Timer Manager API
Java EEコンテキストを持つスレッドをタイマー駆動で実行できるようにする。
-->Java EE環境におけるTimerクラスの代替手段。


■Timer Manager API のインタフェース
commonj.timers.CancelTimerListener
commonj.timers.StopTimerListener
commonj.timers.Timer
commonj.timers.TimerListener
commonj.timers.TimerManager

TimerListenerTimerManagerが中心人物。

TimerListener
コールバックメソッドであるtimerExpiredメソッドを規定するもの。
開発者は TimerListenerインタフェースを実装して
タイマー駆動で処理したい内容をプログラム。

TimerManager
タイマー設定を行う為のインタフェース。
ネーミング・サービスを介して TimerManager実装クラスの参照取得する。
TimerManager実装クラスのscheduleメソッド(もしくはscheduleAtFixedRateメソッド)の引数に
TimerListener実装クラスと タイマー動作規定値を渡して
タイマー駆動の設定で行う仕組み。


■フロー
① ネーミング・サービスにTimerManager実装クラスを登録
② TimerManager実装クラスを利用するJava EEコンポーネントのDDファイル(web.xml)にリソースの参照を設定
③ TimerListener実装クラスの作成
④ TimerManagerAPIを利用するJava EEコンポーネントで ネーミングサービスからTimerManager実装クラスを参照取得
⑤ TimerManagerAPIを利用するJava EEコンポーネントで TimerManager実装クラスのschedule(||scheduleAtFixedRate)メソッドの呼び出し
⑥ TimerManager実装クラスのscheduleメソッドで指定したタイマー設定に応じて TimerListener実装クラスのTimerExpiredがコールバックされ 処理実行

□TimerManager#schedule/scheduleAtFixedRateメソッドの引数
 ・コールバックメソッドが最初に実行される時刻/最初に実行されるまでの遅延時間
 ・一度だけ実行されるか/繰返し実行されるか

□TimerListener#timerExpired
独立したスレッドとして処理を開始する。
スレッドには JavaEEコンテキストが渡される。
-->TimerManagerAPIでセキュリティやトランザクション等のJavaEEの各サービスが利用できる。


■タイマーのキャンセル
commonj.timers.Timer#cancel()でタイマー実行を終了できる。


■タイマーのライフサイクル
TimerManagerAPIが提供するタイマー機能には永続性はない。
→Workオブジェクトの場合と同様に
 アプリケーションサーバの遮断で 全てのタイマー設定が消失する。


ref:
http://www.itarchitect.jp/enterprise/-/31381-3.html

tag : Timer Manager API commonj TimerListener TimerManager

2009-03-09 23:49 : j2ee : コメント : 0 : トラックバック : 0 :

DL/ じゃばじゃば入門

【*】Java動かすに要るもの
+ソースコード
API
+コンパイラ
JVM (Java仮想マシン)

どれもWindowsにもLinuxにもないから自力でインストールすること。


【*】API
J2SEJ2EEのこと。
いわゆる関数郡。
Javaには やたら関数があって 代表的なAPI(関数郡)が J2SEJ2EE
J2SE
Java使うための最小限のAPIの塊。
J2EE
Web上でJavaを使うためのちょっと高級なAPIの塊。

ちなみに
JavaAPIJARファイル。


【*】実行環境とコンパイル
API(関数)使ってソースコード書くだけでは Javaは実行できんもの。
Javaのプログラムを実行するには
Javaを実行する専用のソフトウェアが必要で これが Java仮想マシン(JVM)。

ソースコードをコンパイル(翻訳)すると JVMで実行できるファイル形式となる。


【*】JDK
Java Development Kit
API と コンパイラ と JVM をまとめたもの。
JDKさえインストールしてまえば 3/4のインストールが完了してまうからくり。

最新のJDKは バージョン1.6(6.0)。
※1.4までのJDKJ2SDK
※1.5以降のバージョン表記:J2SDK1.4→JDK5.0。

JDKには J2SEが入っていて J2EEは入ってない。


【*】開発環境作り
インストール方法:
ダウンロード↓
http://java.sun.com/javase/downloads/index.jsp
Java SE Development Kit(JDK)6 Update 11

jdk-6う11-windows-i586-p.exe
を取得して 実行すればインストールは完了。
↓なのが出来てるはず。
C:\Program Files\Java\jdk1.6.0_11

次 パス。
[C:\Program Files\Java\jdk1.6.0_11]ディレクトに行けば Javaが動くわけやけど
いちいちディレクトリ移動するのはメンドウ。
だからパスを通してまおう ゆうこと。
パスさえ通しちゃえば どっからでもこのファイルが利用できるようなるけんね。

パスの通し方:
スタート>マイ コンピュータ>コンテキストメニュー>プロパティ
環境変数>詳細設定>環境変数
HOGEHOGEのユーザー環境変数(U)
JAVA_HOMEゆう変数があれば そいつを選択して>編集
なければ>新規
変数名(N): JAVA_HOME
変数値(V): C:\Program Files\Java\jdk1.6.0_11
で>OK
変数を登録できたら PATH変数の最後に その変数を追加してPATHに通す。
環境変数>HOGEHOGEのユーザー環境変数(U)>PATH>編集
変数値(V): うにゅうにゅ…;%JAVA_HOME%\bin
>OK

パスが通ったことの確認方法:
スタート>すべてのプログラム>アクセサリ>コマンドプロンプト
を開いて
C:\>javac -version
って入力して
javac 1.6.0_11
って表示されて
C:\>java -version
って入力して
java version "1.6.0_11"
って表示されればOK。

※javacのバージョンとjavaのバージョンは同じであること!
違うてるときは↓から削除。
コントロールパネル>アプリケーションの追加と削除

あとはソースコード作って実行するのみ。


【*】トムキャット
JDKインストールしてパス通してソースコード書いても
Webで動かすにはまだ不十分で Tomcatを入れんといけん。
Tomcatゆうのは WebでJavaを動かすためのプログラム。

Tomcatには JARファイルになったJ2EEも含まれている。

Tomcatのインストール方法:
http://tomcat.apache.org/ から Tomcat 6.x をクリック
Quick Navigation: 6.0.18>Binary Distributions>Core>Windows Service Installer
apache-tomcat-6.0.18.exe を実行
言われるままに進んじゃって。
ただ Choose Install Location>Destination Folder は
C:\Tomcat6.0
やのうて
C:\Tomcat6_0
にしとくと無難やも。
"."とか" "とかは何かと悪さする原因になるけんね。
やったらJDKも入れると変えときや ゆう話やけど。。
あと 途中でJDKのパス聞かれるけ 自分のJDKのパス入れてや。
Java Virtual Machine>C:\Program Files\Java\jdk.6.0_11

ちなみに Tomcat6.0.18には バグがあるらしい↓。
C:\Tomcat6_0\conf\tomcat-users.xml
の1行目を修正。


<'?xml version='1.0' encoding='utf-8'?>


【*】Tomcatのフォルダ構成
conf: 設定ファイル
logs: ログファイル
webapps: 自分のプログラムファイル(アプリ)
bin: 実行ファイル


【*】IDE
統合開発環境
ちまちまテキストファイルでソースコード書いて配置してって出来るけど
メンドイけ エクリプスゆうIDEを入れて楽チンにする。
↓からダウンロード。
http://archive.eclipse.org/eclipse/downloads/drops/R-3.2.2-200702121330/index.php
あれこれあるとあとあと便利やけ
All-In-One-Eclipse
とか
MyEclipse
とか初めから全部あれこれ入ってるエクリプスを入れた方がヨイかも。
最新のeclipse3.4はまだないやも知れんけど。


ref:
http://www.searchman.info/java_eclipse/1000.html

tag : DL Java API JVM J2SE J2EE JAR JDK J2SDK JAVA_HOME

2009-03-01 14:11 : j2ee : コメント : 0 : トラックバック : 0 :

J2EE1.4

JAX-RPC v1.1 (Java API for XML-based RPC)
SAAJ (SOAP with Attachments API for Java)
Web Services for J2EE
JAXR (Java API for XML Registries)
WS-Iへの対応@JAX-RPC

JAX-RPC
XMLを使ったRPC(Remote Procedure Cell:遠隔操作呼び出し)を実装するためのJavaの標準仕様
JCPにてJSP-101として策定されたもの
JAX-RPCの仕様は以下が目的
・JavaプラットフォームでのXMLベースのRPCをサポートするAPIの定義
・基本レベルのプロトコルバインディングの定義
JAX-RPCベースのサービスの定義/Javaアプリを開発するための基本APIの定義
・ヘテロジーニアス(混合)な環境での相互接続性のサポート
JAX-RPC実装に対する適合性と相互接続性の検証のための要件の定義
・JAX-RPC APIとメカニズムの拡張可能+モジュラー保持

■RPC
遠隔操作呼び出し
RMI(Remote Method Invocation)と同じ意味
要は分散オブジェクトの技術
環境Aで環境Bにいる処理を実行させたい時に両者を繋げる必要がある
環境Aと環境B間にミドルウェアを挟んで両者を連携させる方式がRPCゆうもの
JAX-RPCは RPC+Java+XML+J2EEって感じ

ちなみに
既存するJavaの分散オブジェクト技術の Java-RMIやEJBに対し
JAX-RPCは 分散オブジェクトを連携させるWebサービスのAPI
つまり、SOAPWSDLUDDIといったXMLで分散オブジェクトモデルをJavaで実現するもの
Webサービス技術
XMLを使ったシステム連携技術
インターネット上でRPCを行う仕様が含まれてる

■JAX-RPCの決まりごと
・JAX-RPCの使われ方
・前提
WSDL/XML-Java間のマッピング
SOAPバインディング
・添付付きSOAP
・コアAPI
・クライアント・プログラミング・モデル
・サービス・エンドポイント・モデル
・サービス・コンテキスト
SOAPメッセージ・ハンドラ
・JAX-RPCランタイム・サービス
・相互接続性
・拡張可能タイプ・マッピング

■JAX-RPCの概要
JAX-RPCをサポートするミドルウェア/開発ツール/それに搭載されるアプリの関係を定義
JAX-RPCは RPCの仕様であって
Webサービス・アーキテクチャであるSOAPWSDLUDDIによるデルタモデルを実現するものでない

利用する技術がSOAPとWSDL
発見メカニズムにJNDIを利用

JAX-RPCでは
Webサービスの機能を提供するプログラムコードを サービス・エンドポイント と呼ぶ
エンドポイントの機能は
interface句で定義することになっていて
これを サービス・エンドポイント・インタフェース(SEI) という

サービス・エンドポイントは J2EEのコンポーネント・モデルに従うとされていて
EJBのステートレス・セッションBeanや JavaBeanなどが実装に使われる
サービス・エンドポイントは
J2EEサーバにデプロイされて実行されるが
デプロイモデルや方法はJAX-RPCの管轄外で
J2EE1.4のWeb Services for J2EE (JSR-109)で規定されている

 [ServiceClientAP]←WSDL―[WSDL]←JavaMapping→[ServiceEndPoint]
      ↓                                ↑
     [Stub]                          Container/Dispatch
      ↓                                ↑
 JAX-RPC CoreAPI                      JAX-RPC CoreAPI
ClientSide/JAX-RPC Env←-protocol/transport-→ServerSide/JAX-RPC Env

仕掛け
クライアントが サービス・エンドポイント・インタフェースに対してプログラミング
インタフェースの実装はスタブ
スタブを呼び出すことで クライアント側の実行環境がSOAPでサーバ側の実行環境を呼び出す
サーバ側の実行環境が リクエストをサービス・エンドポイント(JavaBean/EnterpriseBean)にdispatchしてメソッドを呼び出す
メソッドの戻り値が 逆ルートを通ってクライアントアプリケーションに戻る

スタブは WSDLから自動生成されるもので サーバベンダによって異なるもの
スタブは サービス・エンドポイント・インタフェースが実装されてる
クライアント・アプリは このスタブのインタフェースに対してプログラミングすることで サービスを呼び出せる

■WSDL/XML-Java間のマッピング
Webサービスのインタフェース情報はWSDLで記述するのがルール
JAX-RPCは WSDLとJavaのマッピングルールを定義

名前のマッピング
XMLに付けられた名前(要素名)は 基本的にJavaのクラスや変数名にマッピングされる
Javaで使ってはいけないキーワードには アンダースコアが前に付加される

型のマッピング
XML SchemaとSOAPエンコーディングをサポートすること
要は複雑な定義
マッピング機能は JAX-RPC実装したJ2EEサーバが提供

■SOAPバインディング
JAX-RPCはバインディングに依存しない仕様で
SOAPバインディングは 単なる1つの選択肢として定義されてる

SOAPの仕様では
スタイルにRPC型とドキュメント型
エンコーディングにSOAPエンコーディングとリテラル型
がある
JAX-RPCは↓な組合せをサポート
・RPC/encoded
・RPC/literal
・document/literal

J2EEサーバは ↑の他に↓クラスの使い方も規定
・javax.xml.soap.SOAPElement
・javax.xml.soap.SOAPFactory
・javax.xml.soap.SOAPFaultException

■添付付きSOAP
SOAPなどのXMLプロトコルでは バイナリ形式のデータを取り扱い難い

添付データを扱う方式として[SOAP Messaging with Attachments]を仕様として規定
JAX-RPCでは MIMEを利用する添付データをサポート
JavaコードからMINE処理するために JavaBeansActivationFrameworkのjavax.activation.DataHandlerを利用
JAX-RPCをサポートするサーバは 用意されたハンドラで SOAPメッセージを簡単に添付データを付加できる仕組み

■コアAPI
クライアント側のプログラムコードが使うクラス/インタフェース
・javax.xml.rpc.Stub(IF)
・javax.xml.rpc.Call(動的呼び出しモデル)
・javax.xml.rpc.Service(IF)
・javax.xml.rpc.ServiceFactory
・javax.xml.rpc.JAXRPCException

ServiceFactory、Service、Cellは 低レベル・インタフェースと呼ばれ JAX-RPCのクライアント・ランタイムに直接アクセスできる

このAPIでクライアントの実装には2つのアプローチが可能
Stub(IF)を実装したスタブ(SOAPでいうプロキシクラス)を生成する方法
(プリビルド型でサービスにバインドする方法)

Cell(IF)を実装するダイナミックにバインドする方法
一般的なのは前者

ダイナミックバインド方式は
JavaBeansのリフレクション等と似たもの
これでワークフローエンジンなどでサービスをプラグインしたり
開発ツール上でサービスを動的に認識して扱ったりできるようになる

■クライアント・プログラミング・モデル
JAX-RPCのクライアントはJNDIでLOOKUPしてサービスに対するポート(インタフェース)を取得する

スタブの取得
Context ctx = new InitialContext();
com.example.StockQuoteService service = ctx.lookup("java:comp/env/StockQuoteService");
com.example.StockQuoteProvider provider provider = service.getStockQuoteProvider();
float quotePrice = service.getLastTradePrice("ACME");

実行するために
デプロイメント・ディスクリプタにservice-ref-nameやservice-ref-typeを記述する

■サービス・エンドポイント・モデル
Webサービスの機能を提供するモジュールの実装形式、サーバ上での稼動形式を決めたもの

JAX-RPCが規定しているサービス・エンドポイント・モデルは
サーブレット・コンテナ上にデプロイされるJAX-RPCサービスのためのもの
EJBコンテナ上でのJAX-RPCサービスは JSR-109/EJB2.1で規定されてる

サーブレット・コンテナ上のサービス・エンドポイントは
Javaクラスで WSDLの記述とマッピングされる
WSDLが既存する場合は
マッピングツールで雛形を生成し 中身を埋める
もしくは
既存Javaクラスにインタフェース(サービス・エンドポイント・インタフェース)を定義し それを基にWSDLを生成する

■サービス・コンテキスト
サービスと呼び出し元のクライアント間で取り交わされる状態を維持するための情報
実際にはSOAPヘッダで交換される

サービス・コンテキストは2種類
暗黙的 と 明示的

暗黙的サービス・コンテキスト
セキュリティ情報のようなJ2EEが自動的に運搬するようなもの

明示的サービス・コンテキスト
アプリケーションに実装する必要のあるもの


ref:
http://www.atmarkit.co.jp/fjava/kaisetsu/j2eewatch01/j2eewatch01.html

tag : JAX-RPC SAAJ Web Service JAXR WS-I SOAP WSDL UDDI

2009-01-31 20:14 : j2ee : コメント : 0 : トラックバック : 0 :

SOAP

SOAP
分散アプリケーションのためのプロトコル
さまざまな場所に分散したサービスを相互に結び付け システムとシステムを連携させることができるようになる

SOAP」と「WSDL
すべてのWebサービスが利用する基本技術

Webサービス
クライアント/サーバ型で稼働するもの
Webサービス=クライアントプログラム+サーバプログラム


□サーバプログラム
Axis
Apache Projectにて開発/メンテナンスされているWebサービス実行/開発環境

Axisのサーバ側プログラムをAxisエンジンといい
サーバ上で稼動するServletプログラムとなる

Axisエンジンをサーバ配置して起動するまでの手順
Axisエンジン・モジュール群をサーバに配置
 \webapps\axisディレクトリを\webapps以下にコピー
 →サーバへのSOAPエンジンのインストール完了
SAAJJAX-RPCパッケージの移動
 \webapps\axis\WEB-INF\libにあるsaaj.jar, jaxrpc.jarファイルを\{srv}\libに移動
 →Tomcatの仕様でjava.xxxやjavax.xxxというパッケージ名を持つクラスを\webapps以下のディレクトリから読み込まないため

【*】jaxrpc.jar
 Java API for XML-based RPC (JAX-RPC
 JavaでXML リモート・プロシージャ・コール(RPC)を実行するための機能を提供
 →SOAPを利用したRPCを動かすためのAPI

【*】saaj.jar
 SOAP with Attachment API for Java(SAAJ
 SOAP通信を行うための機能を提供
 SOAP 1.1の仕様に準拠
 SOAP with Attachment(SOAPの添付ファイル対応)に対応
 JAXM仕様(Java API for XML Messaging)の機能の一部

Axisエンジンはサーバの上で稼働するServletなので
Tomcatを起動すればAxisエンジンが使える状態になる

サーバとAxisエンジンの稼動確認
tomcatの場合
サーバ:http://localhost:8080/index.html
Axisエンジン:http://localhost:8080/axis/index.html


□クライアントプログラム
MS-DOSコマンドプロンプトで実行するJavaアプリケーション・プログラム
JavaアプリケーションをMS-DOSコマンドプロンプトで実行するには
PATH環境変数の設定
CLASSPATH環境変数の設定
が必要

Java実行/開発環境のPATH設定
 javaコマンドやjavacコマンドが使えるよう SDKへのPATHを設定
 > set PATH=c:\jdk{ver}\bin;%PATH%
AxisライブラリをCLASSPATHへ追加
 AxisのライブラリをCLASSPATHに設定
 基本的に\libのjarファイルをすべて追加
 ※バージョンが次第でxerces.jar(XMLパーサ)も追加
  \{srv}\lib\xerces.jarを\libにコピー
  SDK 1.4.0以上は不要な操作
 > set AXIS_HOME=c:\axis-ver
 > set AXIS_LIB=%AXIS_HOME%\lib
 > set CLASSPATH=.;%AXIS_LIB%\xerces.jar;%AXIS_LIB%\saaj.jar;
 %AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\axis.jar;
 %AXIS_LIB%\wsdl4j.jar;%AXIS_LIB%\commons-logging.jar;
 %AXIS_LIB%\tt-bytecode.jar;%AXIS_LIB%\log4j-1.2.4.jar;%CLASSPATH%
 ※set CLASSPATH以降は1行で記述すること

これらのコマンドをWebサービス・クライアントを実行するMS-DOSコマンドプロンプトで実行
これらをbatファイルにすると
------------------------------
set JAVA_HOME= c:\jdk1.3.1_04
set AXIS_HOME=c:\axis-1_0
set AXIS_LIB=%AXIS_HOME%\lib

set PATH=%JAVA_HOME%\bin;%PATH%

set CLASSPATH=.;%AXIS_LIB%\xerces.jar;%AXIS_LIB%\saaj.jar;
%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\axis.jar;
%AXIS_LIB%\wsdl4j.jar;%AXIS_LIB%\commons-logging.jar;
%AXIS_LIB%\tt-bytecode.jar;
%AXIS_LIB%\log4j-1.2.4.jar;%CLASSPATH%
/-----------------------------

□いざ実行
ディレクトリに移動
クライアントを実行

↓初回実行結果
------------------------------
>java samples.userguide.example3.Client こんにちは

- Mapping Exception to AxisFault
AxisFault
faultCode: {http://xml.apache.org/axis/}Server.NoService
faultString: The AXIS engine could not find a target service to invoke! targetService is null
faultActor: null
faultDetail:
stackTrace: AxisFault
faultCode: {http://xml.apache.org/axis/}Server.NoService
faultString: The AXIS engine could not find a target service to invoke! targetService is null
faultActor: null
faultDetail:
/-----------------------------

↓連続実行結果
------------------------------
>java samples.userguide.example3.Client こんにちは

The AXIS engine could not find a target service to invoke! targetService is null
/-----------------------------
クライアント(Client)がWebサービスを呼び出したけど
------------------------------
Axisエンジンが「実行するサービスを見つけることができない」(targetService is null)でいる
/------------------------------

サービスを見つけられるように以下を実行
>java org.apache.axis.client.AdminClient samples\userguide\example3\deploy.wsdd

↓実行結果
------------------------------
Done processing
/-----------------------------

もっかいクライアントを実行
------------------------------
>java samples.userguide.example3.Client こんにちは

You typed : こんにちは
/-----------------------------

※samples.userguide.example3.Clientは
 クライアントから受け取った文字列をそのまま戻すサービス

引数に入力した文字列がそのまま表示されてるから稼動成功


↓実行
------------------------------
>java org.apache.axis.client.AdminClient samples\userguide\example3\undeploy.wsdd

Done processing
/-----------------------------

もっかいクライアントを実行
------------------------------
>java samples.userguide.example3.Client こんにちは
/-----------------------------

↓実行結果
------------------------------
The AXIS engine could not find a target service to invoke! targetService is null
/-----------------------------
→最初のときのようにサービスが使えない状態になってる


ref:
http://www.atmarkit.co.jp/fjava/rensai2/wbsrvic01/wbsrvic01_1.html

tag : SOAP WSDL axis saaj jaxrpc jar AXIS SAAJ JAX-RPC

2009-01-31 03:03 : j2ee : コメント : 0 : トラックバック : 0 :

JavaClient & WebService @J2EE

ベンダーに依存しないコードの書き方

の前に


JavaのWebServiceClientは ざっくり2タイプ
・非管理クライアント
・J2EEコンテナ管理のクライアント

こやつらが取らにゃならんステップも2つ
・サービス ルックアップ
・アクセス


WebServiceの強みはインターオペラビリティー(相互運用性)


Webサービスインターオペラビリティー組織(WS-I.org)の働きで
Webサービス技術(SOAPWSDL、UDDI)同士の相互動作が可に。

Webサービスのクライアントは多種
他のWebサービスやったり スクリプト言語で書かれたクライアントやったり C#クライアントやったり Javaクライアントやったり
このクライアントで ルックアップしたり アクセスしたりして Webサービスを呼ぶ ゆう仕組み


Webサービスの役割
Webサービスのプロバイダ:
 WebサービスをWSDL(Web Service Description Language)ドキュメントで記述
Webサービス:
 UDDI(Universal Description, Discovery and Integration)レジストリに対して発行される
Webサービス要求者:
 UDDIで Webサービスを見つけ Webサービスにバインドし そのサービスを呼ぶ

serviceProvider ―publish→ serviceRegistry ←find→ serviceRequester ―bind→ serviceProvider ...


JavaでのWebサービスの標準
Java技術標準の開発は JSRs(Java Specification Requests)が JCP(Java Community Process)に提出されることで行われる

2つのJSRsがWebサービスアーキテクチャをハンドル
・JSR 101: XMLベース(JAX-RPC)用Java API
・JSR 109: エンタープライズWebサービスの実装


JAX-RPC
簡単で使いやすいJava APIを定義
→XMLベースのRPC(リモートプロシージャーコール)とJavaからXMLへ、またはその逆を定義するもの
WSDL→Java/JavakaraWSDLへのマッピング:
 ex. WSDLnoポート型がJavaSEI(サービス・エンドポイント・インタフェースへのマッピング
・XMLデータ型⇔Javaデータ型へのマッピングで単純型、複雑型、配列

JSR109
J2EE環境でのWebサービスのプログラミング・モデルとアーキテクチャを規定
SOAP1.1とWSDL1.1を元にJAX-PRCを使用


ここまでちんぷんかんぷん…


サービス・ルックアップ
2種
・非管理クライアント
・J2EEコンテナ管理クライアント

非管理クライアント
=J2EEコンテナで管理せんゆうこと
→ようはJ2SEクライアント
≒ゆわゆる単純なJavaコマンド
非管理クライアントに対するサービスルックアップは
サービスアクセスポイントのインスタンス生成のファクトリであるJAX-RPCServiceFactoryを通してやる
一方
J2EEコンテナ管理クライアント
に対するサービスルックアップはJNDIルックアップで実現

JAX-RPCServiceFactory
うんぬんぬんぬんん…

JNDIサービスルックアップ
J2EEコンテナ管理のクライアントは
EARファイルに パッケージされていて J2EEコンテナの内部から実行する
Javaコードに加えディスクリプタもアーカイブ中にパッケージされてる
J2EEコンテナ管理のクライアントには
・アプリケーション・クライアント・コンテナ・クライアント
・Webコンテナ・クライアント:JavaBean/サーブレット
・EJBコンテナ・クライアント:EJB
と異なるものがある


サービス・アクセス
JAx-RPCServiceはプロキシやスタブのファクトリとしても働く
一旦サービスをインスタンス化すると 3つのメソッド持つ
・スタブ
・動的プロキシ
・DII(Dynamic Invocation Interface:動的呼び出しIF)
スタブと動的プロキシ・メソッドはSEI(サービス・インタフェース・エンドポイント)を使用
SEI
WSDLポート型要素で記述されたWebサービスの運用操作のJava表現で
Webサービスと相互動作するJavaクライアントに使われるメソッドを定義するJavaインタフェース


まーいろいろあるゆうことや。

ref:
http://www.ibm.com/developerworks/jp/webservices/library/ws-javaclient/index.html

tag : SOAP WSDL

2009-01-27 23:31 : j2ee : コメント : 0 : トラックバック : 0 :

パッケージング

□J2EEパッケージング
J2EE仕様に準拠した
「どんなアプリケーション・サーバでも通用するポータブルEAR」
を作成すること。

□J2EEパッケージング 3大原則
ルール①
 EARは、独立・自己完結させること。
 ※EAR以外のライブラリ参照や要APサーバ特有のクラスパス修正はご法度。
 ※[他のシステムのリモートメソッドを呼び出す]系の依存関係の残留はOK。

ルール②
 クラスローダ・デリゲーションモードは、APクラスローダと各WARクラスローダ、
 共に[PARENT_LAT]にすること。

ルール③
 クラスローダ・ポリシー(アイソレーション・モード)はデフォルトのままにすること。
 ※[単数(シングル)][アプリケーション]等に変更しないこと。
 ※アイソレーション・モードは、
  パッケージングが出来ていないEARへの一時的な救済策に使うもの。
 ※デフォルト設定
  アプリケーションごとにアプリケーション・クラスローダが1つで、
  さらに下位クラスローダとして、WAR毎の専用WARクラスローダが1つずつ割り当てられる。
  

□パッケージング策①/重複戦略
ターゲットアプリ:
 WebアプリとしてWARが3つ、EJBモジュールとしてejb-jarが2つ、さらに複数のライブラリを使用。
 各Webアプリは、さらにStrutsを使用。

―例①―
luv-app.ear
 |― META-INF/application.xml
 |― ejb1.jar
 |― ejb2.jar
 |― utility.jar
 |― commons-xxx.jar
 |― luv1.war
 |  |― WEB-INF/lib
 |     |- utility.jar
 |     |- commons-xxx.jar
 |     |- struts.jar
 |― luv2.war
 |  |― WEB-INF/lib
 |     |- utility.jar
 |     |- commons-xxx.jar
 |     |- struts.jar
 |― luv3.war
 |  |― WEB-INF/lib
 |     |- commons-xxx.jar
 |     |- struts.jar
 |     |- web-util.jar
―/例①―

目標: 自己完結したEAR。
使用するライブラリのうち、J2SE/EEに含まれていないものは、
全てEAR内にパッケージング。
EAR・WAR配下にそれぞれが使用するライブラリを配置。

J2EEコンテナは、EAR内に配置した各モジュールやライブラリをどうやって認識してるのか?
・WARやejb-jar系のJ2EEモジュール
  →EARのDD(DeploymentDescriptor:配置記述子)である[META-INF/application.xml]内に明記されてる。
・各WAR内の[WEB-INF/lib]以下のライブラリ
  →コンテナの担当、ってゆう仕様。
・EAR直下のJ2EEモジュールでないライブラリ
  →ただ置くだけでは、認識されない!!

上記のパッケージ構成のEARをアプリケーション・サーバにデプロイすると
各クラスローダの担当モジュールは以下の通り。

―例①:デプロイ後―
luv-app.ear
 |
 |―ejb1.jar / Application ClassLoader
 |―ejb2.jar / Application ClassLoader
 |―commons-xxx.jar
 |―utility.jar
 |
 |―luv1.war / WAR ClassLoader
 |  |
 |  |―utility.jar
 |  |―commons-xxx.jar
 |  |―struts.jar
 |
 |―luv2.war / WAR ClassLoader
 |  |
 |  |―utility.jar
 |  |―commons-xxx.jar
 |  |―struts.jar
―/例①:デプロイ後―
EJBモジュールはutility.jar等に依存する。
しかし、
utility.jarは、EJBモジュールのクラス検索対象外の
下位クラスローダ(WARクラスローダ)にロードされているため
EJBモジュールには、utility.jarを見つけられない。
結果、正常に動作しない。

□パッケージング策①/重複戦略/Bundled Optional Package
Bundled Optional Package:
 EAR内に同梱され、J2EEモジュールから使用されるライブラリ

使用する依存ライブラリーをJ2EEコンテナに教える必要がある。
→マニフェストファイルのClass-Pathエントリに必要なライブラリを定義する
 ※Class-Pathエントリに記述するパスは、EARのトップからの相対位置で指定すること。


ejb1.jar(EJBモジュール)が、utility.jar等に依存している場合

EJBモジュール内部のマニフェスト・ファイル[META-INFO/MANIFEST.MF]に使用するライブラリを宣言する
―例:ejb1.jar内のMETA-INF/MANIFEST.MF―
Manifest-Version: 1.0
Class-Path:
utility.jar
commons-xxx.jar
commons-yyy.jar
commons-zzz.jar
―/例:ejb1.jar内のMETA-INF/MANIFEST.MF―
J2EEコンテナは、J2EEモジュールである、WARとejb-jar内のマニフェストファイルをチェック。
Class-Pathエントリがあった場合、
そこに宣言されているライブラリをアプリケーション・クラスローダ配下に配置する。
※EARトップ直下に依存ライブラリがある場合、
 Class-Pathエントリには、Jarファイル名のみで指定。

※依存ライブラリの発見の仕組みは連鎖する。
 依存先ライブラリ内のマニフェストファイルに更にClass-Pathエントリがあった場合、
 依存先ライブラリの依存先ライブラリをも、アプリケーションクラスローダ下に同様に配置する。
 
※WARはライブラリじゃない
 luv1.war内のマニフェスト・ファイルに
 ----------------------
 Manifest-Version: 1.0
 class-path: luv2.war
 ----------------------
 と書いてもluv2.war内のクラスは見れない。
 WARはWebアプリであってライブラリでない。
 ※あるWar内のクラスを別のWar内で使用したい場合、
  そのクラスはUtilityJarとしてライブラリ化すべし。

※ライブラリとしてのJarの条件
 Javaのパッケージ階層構造がそのままJar内部のディレクト構造と一致していること。
 ※EJBモジュールは、条件を満たす点では、ライブラリとしてのJarである。


□パッケージング策②/ユニーク戦略
1つのEARにstruts.jarやらcommons-xxx.jarやらが重複してる
→無駄
⇒より重複をなくしてユニークなものしてしまおう ゆう戦略

luv-app.ear
 -META-INF/application.xml
 -ejb1.jar
 -ejb2.jar
 -utility.jar
 -commons-xxx.jar
 -struts.jar
 -luv1.war
 -luv2.war
 -luv3.war
  -WEB-INF/lib
   -web-util.jar

―例②:デプロイ後―
luv-app.ear
 |--ejb1.jar
|--ejb2.jar
|--utility.jar
|--commons-xxx.jar
|--struts.jar
|-


―/例②:デプロイ後―

ref:
http://www-06.ibm.com/jp/software/websphere/developer/j2ee/strategy/3.html
2008-10-31 20:19 : j2ee : コメント : 0 : トラックバック : 0 :

クラスローダ/ デリゲーション・モード

デリゲーション・モード
WARクラスローダそのものを単純標準出力した結果
--------------------
com.ibm.ws.classloader.CompoundClassLoader@1f7010c3
 Local ClassPath: ...(略)...installedAppslemonNode02Cell
               luv-app.earluv.warWEB-INFclasses;
          ...(略)...installedAppslemonNode02Cell
               luv-app.earluv.war;
 Delegation Mode: PARENT_FIRST
--------------------
該当クラスローダに関する情報が出力されるように、
クラスローダのtoString()がオーバーライドされている。
これで、該当クラスローダのローカルクラスパス(LocalClassPath)が分かる。

[Delegation Mode: PARENT_FIRST]ゆう出力結果は、
クラスローダデリゲーション・モード(Delegation Mode)が、PARENT_FIRSTであることを示す。


デリゲーション・モードの設定によって、デリゲーションモデルが決まる。
選択できるモードは2つ。
・PARENT_FIRST
・PARENT_LAST

Java基本クラスローダ/ブーストトラップクラスローダ
 (loads /lib/*.jar)

|―Java基本クラスローダ/エクステンションクラスローダ
   (loads /lib/ext/*.jar)

|―Java基本クラスローダ/システムクラスローダ
   (loads CLASSPATH)
  |
  |―WebSphere/EXTクラスローダ
     (loads /lib/*.jar)
    |
    |―banking.ear/アプリケーションクラスローダ
       (loads banking-ejb.jar, utility.jar)
    | |
    | |―customer.war/WARクラスローダ
    | |
    | |―admin.war/WARクラスローダ
    |
    |―trading.ear/アプリケーションクラスローダ
       (loads trading-ejb.jar, utility.jar)
      |
      |―company.war/WARクラスローダ


上記のうち、アプリケーション・クラスローダとWARクラスローダについては、
デリゲーション・モードをカスタマイズできる。

■PARENT_FIRST(デフォルト)
 自クラスローダのローカルクラスパスを探す前に、最初に親クラスローダにデリゲートする。
 親で見つからなかった時に初めて、自分のローカル・クラスパスを探しにく。

■PARENT_LAST
 自クラスローダのローカル・クラスパスを最初に探す。
 見つからなかった時に初めて、親クラスローダにデリゲートする。


■探索順序
デリゲーション・モードの設定次第で、クラスを探す順序が変わる。

ローカル・クラスパスデリゲーション・モード設定
(A)
APP-FIRST
WAR-FIRST
(B)
APP-LAST
WAR-FIRST
(C)
APP-FIRST
WAR-LAST
(D)
APP-LAST
WAR-LAST
Java基本クラスローダー1223
WebSphere Ext
クラスローダー
2334
アプリケーション
クラスローダー
3142
WARクラスローダー4411


WebSphereApplicationServerの管理コンソール上では、
デリゲーション・モードをクラス・ローダ・モード(Class loader mode)と表記している。


■ケーススタディ
PARENT_LASTはいつ役立つのか?

某月某日
A:jakartaプロジェクトのライブラリのhoge-1.2.jar使うてんねんけど
  どうも挙動がおかしいねん。
B:ちゃんとWEB-INF/libに置いとうと?
A:置いとうよ。クラスを見には行ってるようなんやけど…。
  観てみたら、WebSphereのインストールしたディレクト(WAS_HOME)下の
  libディレクトリ内にhoge-1.1.jarがあったわ。
  自分らのAP内に置いたWEB-INF/lib/hoge-1.2.jarやのうて、
  WAS_HOMEのを先に使うてるようやわ。
B:あかんやん!WebSphereでhoge-1.2.jarは使えんゆうこと?
A:WAS_HOME/lib/hoge-1.1.jarをhoge-1.2.jarで置き換えちゃばええちゃうん?
B:いいね。やってみて~
A:あかん。WebSphere自体が立ち上がらんくなってもうた…。

解説
Aがやるべきやったんは、jarの置き換えやのうて、デリゲーション・モードをPARENT_LASTにすること!
デリゲーション・モードを変更することで、
WebSphereそのものに影響を全く与えずに、
自分のWebアプリケーション内に含まれるライブラリが先に優先されるようになる。

→クラスローダが複数ある利点。


■PARENT_LASTの必要性
WebSphere Application Serverの内部ライブラリに影響されることなく
アプリケーションに最新のライブラリを用いたい場合に[PARENT_LAST]が有効

サーブレットの仕様でも
It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs.
(アプリケーションのクラスをロードするクラスローダーは、アプリケーション・サーバー、Webコンテナ全体で使用するライブラリー内よりも、WAR内部のクラスやリソースを優先してロードすることが推奨される。)
ref: 2.4 Specification SRV.9.7.2

なぜだか
websphereは、PARENT_FIRSTがデフォルトだけど..

注:Java基本クラスローダーが担当するコアクラス(java.lang.*など)に関しては、
  Javaのセキュリティー・モデルで禁止されているため、
  たとえ「PARENT LAST」にしても、「上書き」はできない。


□ちなみに WebコンテナTomcat
Tomcatのクラスローダ・ツリー
 Bootstrap
 |
 |―System
   |
   |―Common
     |
     |―Catalina
     |
     |―Shared
       |
       |―Webapp1
       |
       |―Webapp2

ref: The Apache Jakarta Tomcat 5.5 Servlet/JSP Container Class Loader HOW-TO

Tomcatの場合、EARがなく、Webアプリケーション(WAR)だけなので若干違いがあるが、
tomcat#common、share配下よりも各webapps内のクラス・リソースが優先される
とドキュメントに明記されている。
つまり、PARENT_LASTの設定。

■シングルトンがシングルトンでなくなる日
PARENT_LASTとすべきだが、
通常のJavaのクラスローダのデリゲーション・モードは、PARENT_FIRST。

―typical singleton pattern class―
package com.example;
public class Singleton {
  
  private static Singleton instance = new Singleton();
  private int counter;
  private Singleton() {}
  
  public static Singleton getInstance() {
    return instance;
  }
  
  public void increment(int i) {
    counter += i;
  }
  
  public int getCounter() {
    return counter;
  }

}
―/typical singleton pattern class―

1つしかインスタンス生成されない、
というシングルトンクラスのルールでも
以下ルールで破られる。

―クラスの同一性に関するルール―
全く同じパッケージ名・同じクラスでも、
異なるクラスローダからロードされたものは、
同一クラスとして扱われずに、別クラス扱いとなる。
―/クラスの同一性に関するルール―


□実験

―EAR構成―
luv-app.ear
 |― luv-ejb.jar
 |   |― com.example.Singleton
 |   |― com.example.ejb.InEJB
 |― luv.war
    |― WEB-INF/
       |― classes/
       |― com.example.Singleton
       |― com.example.web.ClassLoaderTestServlet
―/EAR構成―

Singletonクラスを、EJBモジュールとWebモジュールの双方に配置。
アプリケーション・クラスローダとWARクラスローダ
両方のデリゲーション・モードをPARENT_LASTに設定。

―test classes―
package com.example.web;

import com.example.Singleton;
import com.example.ejb.InEJB;
...
public class ClassLoaderTestServlet extends HttpServlet {

  protected void service(HttpServletRequest req,
  HttpServletResponse res)
      throws ServletException, IOException {
    testSingleton();
  }

  private void testSingleton() {
    Singleton singleton = Singleton.getInstance();

    System.out.println("1. InWeb - counter: "
             + singleton.getCounter());
    System.out.println("counter: +1");
    singleton.increment(1);
    System.out.println("2. InWeb - counter: "
             + singleton.getCounter());    
    InEJB.testSingleton();
    System.out.println("5. InWeb - counter: "
             + singleton.getCounter());
    
  }
}

package com.example.ejb;

import com.example.Singleton
...

public class InEJB {

  public static void testSingleton() {
    Singleton singleton = Singleton.getInstance();

    System.out.println("3. InEJB - counter: "
             + singleton.getCounter());
    System.out.println("counter: +10");
    singleton.increment(10);
    System.out.println("4. InEJB - counter: "
             + singleton.getCounter());
  }
  
  public static Singleton getSingleton() {
    return Singleton.getInstance();
  }
}
―/test classes―

Webモジュール内のサーブレットClassLoaderTestServletと、
EJBモジュール内のクラスInEJBの両方から
同一のシングルトン・クラスcom.sample.Singletonを使用。


Singletonクラスが1インスタンスしか生成されていない場合、
実行の結果、最後に出力される[counter]は[11]のはず。

―1インスタンスしか生成されていない場合の実行結果―
1. InWeb - counter: 0
counter: +1
2. InWeb - counter: 1
3. InEJB - counter: 1
counter: +10
4. InEJB - counter: 11
5. InWeb - counter: 11
―1インスタンスしか生成されていない場合の実行結果―

が、実際はPARENT_LASTモードでシングルトンでなくなってる。

―実際の実行結果―
1. InWeb - counter: 0
counter: +1
2. InWeb - counter: 1
3. InEJB - counter: 0
counter: +10
4. InEJB - counter: 10
5. InWeb - counter: 1
―/実際の実行結果―

Webモジュール内のサーブレット、EJBモジュール内のInEJBは
それぞれ異なるシングルトンのインスタンスを参照している。

PARENT_LASTモードとなっているため、
サーブレット(@子クラスローダ)は、
WARクラスローダ(子)内にロードされたシングルトンクラスを先に見つける。
一方、
InEJBクラスは、EJBモジュール(親)内にロードされたシングルトンクラスを最初に見つける。

結果、別々のSingletonクラスを参照。
当然、static変数インスタンスもそれぞれのクラスに存在。
→シングルトンのインスタンスが2つ!

PARENT_FIRSTに設定した場合、
シングルトンインスタンスは1つしか生成されず、
JVM全体でシングルトンの役割を果たす。


1つのJVM内で、クラスを識別するキーとなるのは
[パッケージ名+クラス名]ではなく、
[パッケージ名+クラス名+ロードしたクラスローダ]が識別キーとなる。


http://www-06.ibm.com/jp/software/websphere/developer/j2ee/strategy/2.html

tag : クラスローダ デリゲーション・モード WebSphere

2008-09-01 22:53 : j2ee : コメント : 0 : トラックバック : 0 :

クラスローダ/ デリゲーション・モデル

クラスローダ
クラスをロードするもの
クラスは使用される前に必ずクラスローダによってJVM(Java Virtual Machine)のメモリ空間上にロードされる。

public class SimpleTest {
public static void main(String[] args) {

SimpleTest test = new SimpleTest();//①
ClassLoader loader = test.getClass().getClassLoader();
syso("SimpleTest.class is loaded by " + loader);
syso("java/lang/String.class is found at " + loader.getResource("java/lang/String.class"));//②

}
}

クラスローダの取得
 クラスローダはプログラム中からでも取得可能。
 上記は、java.lang.Class#getClassLoaderで取得。
 syso結果は、
 SimpleTest.class is loaded by sun.misc.Launcher$AppClassLoader@3c6d53c4

クラスローダでリソース検索
 ClassLoader#getResource(String)は、*.properties等の読み込みでよう利用されるが、*.classだっけよ見込み可能。
 ※getResource(String)は、リソース検索のメソッド
  引数は、"java.lang.String"ではなく、"java/land/String.class"とすること。
 syso結果は、
 java/lang/String.class is found at jar:file:C:/opt/rad/runtimes/base_v6/java/jre/lib/core.jar!/java/lang/String.class

実際にクラスがファイルシステム上の何処からロードされたを知るのにもクラスローダは有効。

■クラスローダヒエラルキー
1つのJVM内に複数のクラスローダが普通。
J2EEアプリケーション・サーバの世界も同じ。

□WebSphereApplicationServer内のクラスローダ構成
Java基本クラスローダ/ブーストトラップクラスローダ
 (loads /lib/*.jar)

|―Java基本クラスローダ/エクステンションクラスローダ
   (loads /lib/ext/*.jar)

|―Java基本クラスローダ/システムクラスローダ
   (loads CLASSPATH)
  |
  |―WebSphere/EXTクラスローダ
     (loads /lib/*.jar)
    |
    |―banking.ear/アプリケーションクラスローダ
       (loads banking-ejb.jar, utility.jar)
    | |
    | |―customer.war/WARクラスローダ
    | |
    | |―admin.war/WARクラスローダ
    |
    |―trading.ear/アプリケーションクラスローダ
       (loads trading-ejb.jar, utility.jar)
      |
      |―company.war/WARクラスローダ

―ブーストトラップクラスローダ
 一番の親。
 JavaのコアAPIに関するクラス(java.lang.*等)をロード。

―エクステンションクラスローダ
 ブーストトラップクラスローダの子供。
 エクステンション・ディレクトリ(/lib/ext/*.jar)内のクラスをロード。

―EXTクラスローダ
 エクステンションクラスローダの子供。
 WebSphereApplicationServer特有のクラスローダ。
 WebSphereApplicationServer本体のクラスをロード。
 /lib/*.jar等がロード対象。

―アプリケーションクラスローダ
 EXTクラスローダの子供。
 アプリケーション・サーバにインストールされたエンタープライズ・アプリケーション(EAR)ごとに1つずつ専用に割り振られるクラスローダ。
 各EAR内に含まれるejb-jarやユーティリティ-jar内のクラスがロード対象。

―WARクラスローダ
 アプリケーションに含まれるWARモジュール(=Webアプリケーション)毎に1つずつ割り当てられる。
 各WARモジュール内のWEB-INF/classes以下やWEB-INF/lib/*.jar内のクラスがロード対象。

■クラスローダ・デリゲーション・モデル
 クラスローダは、必要に応じて、自分自身でロードせずに、親クラスローダにクラスのロードを委譲(デリゲート)する。
 例えば、
 システム・クラスローダがあるクラスをロードする必要があったとする。
 この時、
 システム・クラスローダは、自分のローカルクラスパス内、すなわち環境変数CLASSPATH内を探す前に、最初に親であるエクステンション・クラスローダにクラスをロードを依頼する。
 同じように、
 エクステンション・クラスローダも、まず親であるブート・ストラップ・クラスローダにクラスのロードをデリゲートする。
 親クラスローダで見つかった場合は、そこで終了。
 親クラスローダで見つからなかった場合になって、初めて子供は自分のローカルクラスパス内を探しにいき、クラスをロードしようとする。
 
 ※注:デリゲートモデルは、子供が親に依頼しても、親が子供に依頼することはない。

■クラスとクラスローダの関係に関するルール

□ルール① クラスロードの際、使用されるクラスローダの決定方法
 クラスAの内部でクラスBを使用するケース。
 クラスAをロードしたクラスローダ[CL-A]が起点となり、クラスBをロードする。
 この時、デリゲーションモデルで、CL-Aの親クラスローダにはデリゲーションするが、
 CL-Aの子供にはデリゲーションしない。
 
 ------------------------------
 package com.example.web;
 public class InWeb {//子階層のクラス
 }
 ------------------------------
 package com.example.ejb;
 ...
 public class InEJB {//親階層のクラス
  private InWeb inWeb = new InWeb();//子階層のクラスの呼び出し
 }
 ------------------------------
 package com.example.web;
 ...(略)...
 import com.example.ejb.InEJB;
 
 public class ClassLoaderTestServlet extends HttpServlet {
 
  protected void service(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
 
  System.out.println("inWeb : " + new InWeb()); // (1)
  System.out.println("inEJB : " + new InEJB()); // (2)
  }
 }
 ------------------------------
 を実行すると
 ------------------------------
 inWeb: com.example.web.InWeb@3e25a5
 サーブレット ClassLoaderTestServlet で service() メソッドを呼び出せませんでした。
 スローされた例外: java.lang.NoClassDefFoundError: com/example/web/InWeb
             at com.example.ejb.InEJB.(InEJB.java:10)
             at com.example.web.ClassLoaderTestServlet.service(ClassLoaderTestServlet.java:20)
             ...(略)
 ------------------------------
 ClassLoaderTestServletの(2)で落ちている。
 クラスInWebは見れてるが、クラスInEjbは見れてない。
 
 クラスClassLoaderTestServletがクラスInWebを使用するときは、
 クラスClassLoaderTestServletをロードしたクラスローダ、
 すなわちWARクラスローダ(子クラスローダ)が、クラスInWebを探しに行く。
 問題なし。
 
 クラスClassLoaderTestServletがクラスInEjbを使用するときは、
 クラスClassLoaderTestServletをロードしたクラスローダ、
 すなわちWARクラスローダが、クラスInEjbを探しに行く。
 が、実際は、
 デリゲーションモデルで、クラスInEjbをロードするのは
 アプリケーションのクラスローダ(親クラスローダ)。
 ※起点クラスローダがWARクラスローダ(子)からAPクラスローダ(親)に変わっている。
 問題なし。
 
 さて、InEjbの中身。
 クラスInEjbがクラスInWebを使用する時は、クラスInEjbをロードした
 クラスローダ(起点クラスローダ)、すなわちアプリケーションのクラスローダ(親)が、
 クラスInWeb(子階層のクラス)を探しに行く。
 が、
 クラスInWebはWARクラスローダ(子)にいるので、親のアプリケーションクラスローダは
 見つけられずに、NoClassDefFoundErrorとなってまう。
 
 あるクラスが、下位クラスローダ配下しか存在しないクラスに依存している構成がNG!
 


ref:
http://www-06.ibm.com/jp/software/websphere/developer/j2ee/strategy/1.html

tag : クラスローダ

2008-08-27 00:57 : j2ee : コメント : 0 : トラックバック : 0 :

Velocity

Velocity
Javaベースのテンプレートエンジン
Web ページや SQL、PostScript といった出力をテンプレートから生成
Javaコードで定義されたメソッドが参照可
JSP、PHPの代替的もの

■VTL
Velocity テンプレート言語(VTL:Velocity Template Language)

□VTL識別子
[英字]から始め [英数字,ハイフン,アンダースコア]で続けること

□VTL指示子認識子[#]
指示子は[#]で始めること

□変数認識子[$]
変数は[$]で始めること

□値識別子[引用符]
値は["]["]で囲むこと

□コメント識別子
・1行コメント
[##]で開始
行末で終了
・複数行コメント
[#*]で開始
[*#]で終了

■[VTL]レファレンス
3種類
・変数
・プロパティ
・メソッド
リファレンスを出入りするものは 全て文字列オブジェクト
文字列オブジェクトでない物は toStringで影で強制変換

□変数
正式表記:[$]+[{]+VTL識別子+[}]
簡略表記:[$]+VTL識別子
値は [set]識別子かjavaコードから取得

□プロパティ
正式表記:[$]+[{]+VTL識別子+ドット[.]+他のVTL識別子+[}]
簡略表記:[$]+VTL識別子+ドット[.]+他のVTL識別子
--------------------
$customer.Address
--------------------
customerで識別されるhashtableを見て キーAddressと関連づけられる値

$customer.Address()
を得る

□メソッド
正式表記:[$]+[{]+VTL 識別子+VTLメソッドボディ+[}]
簡略表記:[$]+VTL 識別子+VTLメソッドボディ
*VTLメソッドボディ
表記:VTL 識別子+左括弧[(]+パラメータ/パラメータリスト(オプション)+右括弧[)]
--------------------
$purchase.getTotal()
$page.setTitle( "My Home Page" )
$!person.setAttributes( ["Strange", "Weird", "Excited"] )
--------------------

□エスケープ
VTL特殊文字はバックスラッシュ[\]でエスケープ
--------------------
#set( $hoge = "piyo" )
1.$hoge
2.\$hoge
3.\\$hoge
4.\\\$hoge
1.$hogehoge ##未定義変数
2.\$hogehoge
3.\\$hogehoge
4.\\\$hogehoge
--------------------
1.piyo
2.$hoge
3.\piyo
4.\$hoge
5.$hogehoge
6.\$hogehoge
7.\\$hogehoge
8.\\\$hogehoge

□大小文字置換
Velocityは Javaのイントロスペクション機能とBean機能を利用して
コンテキスト内のオブジェクトとオブジェクトメソッドの両方のリファレンス名を解決できる。
--------------------
$foo.getBar()
same as
$foo.bar

$data.getUser("jon")
same as
$data.user("jon")

$data.getRequest().getServerName()
same as
$data.Request.ServerName
same as
${data.Request.ServerName}
--------------------

□沈黙リファレンス
Velocity が未定義のリファレンスに遭遇したとき、
通常の挙動として、リファレンスの記述をそのまま出力する。
--------------------
$hoge ##未定義の場合 [hoge]と出力される
$!hoge ##未定義の場合 [](ブランク)と出力される
$!{hoge} ##未定義の場合 [](ブランク)と出力される
--------------------

■[VTL]指示子
スクリプト要素

□[set]指示子
リファレンスの値を設定
書式:#set( $ref = [ ", ' ]arg[ ", ' ] )
#set 指示子は、リファレンスの値をセットする。
値は、変数リファレンスかプロパティリファレンスにセットされる。

[[変数が左側で値が右側で[=]が区切]]
左辺(LHS:LeftHandSide):変数リファレンス/プロパティリファレンス
右辺(RHS:RightHandSide):変数リファレンス/文字列リテラル/プロパティリファレンス/メソッドリファレンス/数値リテラル/配列リスト(ArrayList)
--------------------
#set( $monkey = $bill ) ## 変数リファレンス
#set( $monkey.Friend = "monica" ) ## 文字列リテラル
#set( $monkey.Blame = $whitehouse.Leak ) ## プロパティリファレンス
#set( $monkey.Plan = $spindoctor.weave($web) ) ## メソッドリファレンス
#set( $monkey.Number = 123 ) ## 数値リテラル
#set( $monkey.Say = ["Not", $my, "fault"] ) ## 配列リスト

$monkey.Say.get(0) ## =[Not]
--------------------

※右辺がnullとして評価された場合  null値は左辺に代入されない。
※[set]指示子には #end 文はない。

□文字列リテラル
["]で文字列リテラルを囲むと 中身がパース/処理される。
※[']は バースされない。
※[']のパースは [velocity.properties]#[stringliterals.interpolate=false]で変更可
--------------------
#set( $directoryRoot = "www" )
#set( $templateName = "index.vm" )
#set( $template = "$directoryRoot/$templateName" )
$template

#set( $foo = "bar" )
$foo
#set( $blargh = '$foo' )
$blargh

#set($prefix = "prefix")
#set($suffix = "suffix")
#set($hoge = "$prefix$suffix")
$hoge
--------------------

--------------------
www/index.vm

bar
$foo

prefixsuffix
--------------------

※算術式も記述可
・加算: #set( $value = $foo + 1 )
・減算: #set( $value = $bar - 1 )
・乗算: #set( $value = $foo * $bar )
・除算: #set( $value = $foo / $bar )
・剰余: #set( $value = $foo % $bar )


□if/elseif/else文
条件分岐
書式: #if( [condition] ) [output] [ #elseif( [condition] ) [output] ] * [ #else [output] ] #end
--------------------
#if ($foo == $bar)
AND
#elseif ( $foo || $bar )
OR
#else ( !$foo ) ## NOT SAME AS [$!foo](沈黙リファレンス)
NOT
#end
--------------------

□foreach文
オブジェクトのリストでループ
書式: #foreach( $ref in arg ) statement #end
※Vector、Hashtable、配列の場合のみ使用可
--------------------
<'ul>
#foreach( $product in $allProducts )
<'li>$product<'/li>
#end
<'/ul>
--------------------
※ループカウンタ変数は デフォルト1
([velocity.properties]#[directive.foreach.counter.initial.value]で変更可)

□include
ローカルファイルのインポート
書式:#include( arg[, arg2, ... argn] )
ファイルは、#include指示子が定義される位置に挿入される。
テンプレートエンジンでの中身の処理はしない。
※TEMPLATE_ROOT以下にあるファイルだけインポート可
--------------------
#include( "one.gif","two.txt","three.htm" )
--------------------

□parse
VTLを含むローカルファイルのインポート
書式:#parse( arg )
※TEMPLATE_ROOT以下にあるファイルのみインポート可
--------------------
#parse( "parsefoo.vm" )
--------------------

□#stop
テンプレートエンジンの実行を停止

□#macro
Velocimacro
VTLテンプレートのセグメントの繰り返し
書式: #macro( vmname $arg1[, $arg2, $arg3, ... $argn ] ) [ VM VTL code... ] #end


ref:
http://www.jajakarta.org/velocity/velocity-1.3.1/docs-ja/user-guide.html

tag : Velocity

2008-08-19 01:39 : j2ee : コメント : 0 : トラックバック : 0 :

正規表現

特殊文字列
. ^ $ [ ] * + ? | ( )
→メタ文字列

メタ文字列を単なる文字として使う場合は[\]を前に足す
\. \^ \$ \[ \] \* \+ \? \| \( \) \\

□とにかく何でもいい1文字[.]
半角の[.]で とにかくなんでもいい1文字を表現
ex. 私は...が..→私は早起きが苦手

□行の先頭と最後[^$]
行の先頭や最後にのみ存在する文字列を検索したい場合に[^$]
ex. ^ありがとう→ありがとうから始まるもの
  ありがとう$→ありがとうで終わるもの

□同じ文字の繰り返し[* + ?]
同じ文字の繰り返しを表す正規表現は [*]、[+]、[?]の3つ
・[*]:[*]の直前の文字が0個以上連続するか
 ex. おー*い→おい、おーい、おーーーい
・[+]:[+]の直前の文字が1個以上連続するか
 ex. おー+い→おーい、おーーーい
・[?]:[?]の直前の文字が0個か1個だけ存在するか
 ex. Windows?→Window、Windows

□何でもいい文字の連続[.*]
[* + ?]は[.]と併用可
ex. コーヒーが好き.*。→コーヒーが好きです。、コーヒーが好きかもね。
  [.]が[*]であるもの→何でもいい1文字が0個以上連続するもの

□いずれかの文字列[|]
| で区切られた文字列のいずれかの文字列が存在するもの
ex. hoge|piyo→hoge、piyo

□指定した文字のどれか[[]]
[]中のどれか1つに合致するもの
ex. 今日は[晴曇雨]です→今日は晴です
  A[A-Z]C→ABC
  1[0-9]8→108
  A[^A-Z0-9]Z→A-Z
  []の中で^→XX以外→2番目の文字はアルファベットと数字以外の文字

□グループ化[()]
まとめて数文字単位で処理
ex. (じゃ)+ーん→じゃーん、じゃじゃーん
  明日(ぼく|わたし)は帰宅します→明日ぼくは帰宅します、明日わたしは帰宅します


ref:
http://www.mnet.ne.jp/~nakama/

tag : 正規表現

2008-07-16 05:35 : j2ee : コメント : 0 : トラックバック : 0 :

JSP#include

JSPに、外部のJSPページやHTMLページをincludeする手段は2つ

1.includeディレクティブ:<'%@ include file="ファイル名" %>
2.includeアクション:<'jsp:include page="ファイル名" />

□includeディレクティブ
インクルードする側のJSPページ(親ページ)のコンパイル時に、
インクルードされる側のJSPページやHTMLページ(子ページ)が
親ページの一部として挿入される。
⇒静的なインクルード機能

□includeアクション
Webブラウザが親ページをリクエストするたびに
子ページのコンテンツがレスポンスに挿入される。
⇒動的なインクルード機能

□文字化け対処法
pageディレクティブの
・contentType属性
・pageEncoding属性
を記述する。

□contentType属性
JSPページ出力時の文字コード、およびContent-Typeヘッダに指定する文字コード名を指定する

□pageEncoding属性
JSPページ読み込み時の文字コードを指定する

pageEncodingは省略可
省略時はcontentType属性の値が使用される

contentType属性の本来の目的は「HTTPレスポンスに用いる文字コードの指定」
→1回セットすればOK。
→子ページ側には不要。
が、
子ページにcontentTypeを記述せんと
サーブレット・コンテナ
が子ページの文字コードを判別する手立てがなくなり
子ページ部分の文字化けが発生してしまう。
で、
子ページには、
読み込み時の文字コードを伝える手段として
pageEncoding属性だけを記述しておく。

つまり、
・親ページ:contentType属性で文字コードを指定する
・子ページ:pageEncoding属性で文字コードを指定する


ref:
http://www.atmarkit.co.jp/fjava/rensai3/mojibake04/mojibake04.html
2007-08-30 00:51 : j2ee : コメント : 0 : トラックバック : 0 :

Shift-JIS & Windows-31J

□NG:charset=Windows-31J
======
content="text/html; charset=Windows-31J">
======
cuz.
charset=Windows-31Jだと
PHPのDOMDocument::loadHTMLFile()関数で上手く読み込めない

Windows-31JのエンコーディングはShift-JISと同じ
が、
PHPは不明なエンコーディングと見なして変換する

うんぬんぬん…

ref:
http://d.hatena.ne.jp/eggtoothcroc/20060214

□Windows-31JはShift-JISを拡張したもの
CP932=MS932=MS漢字コード=Windows-31J≒Shift JIS

ref:
http://q.hatena.ne.jp/1167447698
2007-08-17 01:13 : j2ee : コメント : 0 : トラックバック : 0 :

Encoding stg

□そもそも
Javaは 内部的に文字列(String型)をUnicode(UCS-2)で保持。
そのため、
Javaへの文字列の入出力では必ず Unicodeとの間でコード変換が発生。
特に、
Javaのコード変換では、
対応するコードポイントが存在しない場合“?”に変換される。
⇒文字化け

プラス、
Java以外の部分でも発生する!
ex
ファイル転送時のコード変換
ブラウザのエンコーディング設定

□Weblogic#EncodingStgPoint
 HTTPリクエスト
 servlet:
  ・ソースコード中のServletRequest#setCharacterEncoding
  ・weblogic.xml の
  ・weblogic.xmlの
 JSP:
  ・weblogic.xml の
  ・weblogic.xmlの
 HTTPレスポンス
 servlet:
  ・ソースコード中のServletResponse#setContentType
  ・weblogic.xmlの
 JSP:
  ・pageディレクティブのcontentTypeの指定
  ・weblogic.xmlの
 Servlet/JSP内の文字列(コンパイル時)
 servlet:
  ・ソースコードをコンパイルするときのエンコーディングの指定
 JSP:
  ・JSP中のpageディレクティブのcontentTypeの指定
 weblogic.log/コンソールへのログ出力
  ・Javaのデフォルトエンコーディング(起動するユーザーのロケール)
 JDBCによるDBへのアクセス(Oracleの場合)
  ・DBの文字コードセット
  ・WebLogic起動ユーザーのNLS_LANG環境変数
  ・コネクションプールのweblogic.codesetプロパティ

□Shift-JIS
JSPのコード変換に影響を与えうる設定
.JSP内のpageディレクティブ
  <%@ page contentType="text/html; charset=Shift_JIS" %>
.weblogic.xmlのcharset-mappingの指定
  
   Shift_JIS
   MS932
  


pageディレクティブ#contentType#charsetは、
HTTPレスポンスのヘッダに利用される。
HTTPはJavaのエンコーディングではなく、
ianaで規定されているエンコーディングを指定すること。
→pageディレクティブの指定は、Javaの Shift_JISではなく、ianaのShift_JIS*2である。

このEncoding指定は、JSPをコンパイルするときにも使用される
が、
Shift_JISをそのままJavaのShift_JISとして扱うのは問題やも。
Java#Shift_JISは
MS932 or SJIS の別名として定義されてる!
※ JDK 1.3ではMS932だが、JDK 1.4ではSJISとなる。

そこで、

WebLogicでは、
weblogic.xml#charset-mappingに、
ianaの charsetをJavaのcharsetにマッピングする指定を設けて、
明示的にJavaのエンコーディングを指定。

□暗黙の文字コード変換
JSPのコンパイルでは、
JSPファイル→Javaソース(by Servlet)→classファイル
⇒2段階のコンパイル
前者のコンパイル=JSPC
後者のコンパイル=javac

⇒requestからresponseまで4段階のコンパイル

文字化けした場合、どの段階で文字化けたのかをクリアに!

□javacのencoding
javaでは起動するユーザのLANG設定によって
デフォルトのencodingが決められている。
ex
LANG設定=ja_JP.PCK→SJISでコンパイル


ref:
http://www.atmarkit.co.jp/fjava/rensai2/webopt08/webopt08.html
2007-08-17 01:09 : j2ee : コメント : 0 : トラックバック : 0 :

mime

■MIME type
in web, there are two main concepts; extension of file and mine type.
MIMEタイプ=「タイプ名/サブタイプ名」の形式の文字列
WEBサーバーとWEBブラウザの間はこのMIMEタイプを用いてデータの形式を指定。
such as
+ テキスト
→.txt, text/plain
+ HTML文書
→.htm .html, text/html
+ XML文書
→.xml, text/xml
+ JavaScript
→.js, text/javascript
+ VBScript
→.vbs, text/vbscript
+ CSS
→.css, text/css
+ GIF画像
→.gif, image/gif
+ JPEG画像
→.jpg(.jpeg), image/jpeg
+ PNG画像
→.png, image/png
+ CGIスクリプト
→.cgi, application/x-httpd-cgi
+ Word文書
→.doc, application/msword
+ PDF文書
→.pdf, application/pdf
+ any other ref http://www.iana.org/assignments/media-types/index.html
cf.
x-hogehoge means

when a browser ask a webServer a hoge.gif,
server gonna return the hoge.gif telling that this is a data of image/gif-type.
so that,
browser can operate the hoge.gif correctly.

but,
some browser like IE ignore the info of mime-type, and trust the info of extension of the file.
and
some ignore the both info, and checking the content of file, display the file as HTML because the content looks like HTML document. its a unnecessary favors!

so,
mine-type is not perfect.

■how to set MIMEタイプ
it is different depends on the webServer.
if webServer is Apache,
there is a file named hoge.htaccess. using this file to specify the MIME.
so,
create a file with the name "hoge.htaccess" under the directory same as other data like hoge.html.
and
write following in the hoge.htaccess.
"AddType text/html .html"
so that,
webServer gonna send the .html file as a data of text/html mime-type.
the setting is not necessary for .html and .gif files cuz provider-side gonna do that for those file.
but you have to do the setting for something like CGI and RealAudio

■excel file download
for downloading and saving a excel file;
application/octet-stream

for displaying a excel file on a browser;
application/vnd.ms-excel


ref:
とほほのWWW入門
http://www.tohoho-web.com/wwwxx015.htm
2007-08-03 00:15 : j2ee : コメント : 0 : トラックバック : 0 :

web.xml

what in web.xml#web-app

servlet
- servlet-name
- servlet-class
sevlet-mapping
- servlet-name
- url-pattern
welcome-file-list
- welcome-file
error-page
- error-code
- location
taglib
- taglib-uri
- taglib-location
2007-07-25 02:00 : j2ee : コメント : 0 : トラックバック : 0 :

J2EE仕様のフォルダ構成

/root ← Webアプリケーションのルートフォルダ
│ xxx.html ← 静的なコンテンツと jsp ファイル
│ xxx.gif etc.
│ xxx.jsp

└─WEB-INF ← クライアントからは見えないフォルダ
│ web.xml ← 配備記述子(Deployment Descriptor)

├─lib ← jarファイル等のクラスライブラリを格納
└─classes ← Javaのクラスファイルを格納

ref:
サーバサイドJava入門
http://oss.kk-ntc.co.jp/jpug/pukiwiki/pukiwiki.php?%A5%B5%A1%BC%A5%D0%A5%B5%A5%A4%A5%C9Java%C6%FE%CC%E7#content_1_1
2007-07-25 01:55 : j2ee : コメント : 0 : トラックバック : 0 :

web-app

web-app

to use request-scope or session-scope,
you have to def requestContextListener or requestCOntextFilter or DispatcherServlet

if it is for Servlet 2.4 or more,
web-app
 listener
  listener-class
   org.springfw.web.contect.request.RequestContextListener

if it is for Servlet 2.3 or less,
web-app
 filter
  filter-name
   requestContextFilter
  filter-class
   org.springfw.web.filter.RequestContextFilter
 filter-mapping
  filter-name
   requestContextFilter
  url-pattern
   /*
2007-07-25 01:08 : j2ee : コメント : 0 : トラックバック : 0 :

JSPの構成要素

Javaソースを生成、コンパイルのためのJSPの記述のタグ構成

□ディレクティブ
<'%@ ディレクティブ %>
JSPプログラムの特性を定義

□宣言
<'%! 宣言 %>
JSPで使用する変数やメソッドを宣言

□スクリプトレット
<'% Javaコード %>
Javaソースでの JSPのタグでは処理できないプログラムの自由に記述

□式
<'%= 式 %>
JSPからHTMLを出力

□アクション
<'jsp:アクション名 />
定義された特定の動作をするアクションタグの使用

□コメント
<'%-- コメント --%>
JSPコードへ記述するコメント部



□ディレクティブ
JSPページに関する情報を JSPエンジンに伝えるために使用。
3種類:
page
include
taglib

記述の注意
・タグ名、属性、値は、大文字、小文字は異なる文字として扱われる
・「=」と値の間にスペースは記述できない
・値は「'」、又は「"」で囲む

==pageディレクティブ==
JSPページのエンコードの種類や記述されているJSPページの言語等、
JSPページ時全体的な事柄をJSPエンジンに伝える。

主要な設定

・contentType
応答の文字セットとMIMEタイプを指定。
<'%@ page contentType="text/html; charset=Windows-31J" %>
(コンテンツタイプがHTMLで、文字コードが Shift_JISであるを宣言。)

・import
このページで使用するパッケージやクラスのインポート宣言。
複数指定する場合は「,」で区切って指定。
<'%@ page import="java.sql.*, java.util.TreeMap" %>

・session
このページがセッションに参加するか否かをtrue/falseで指定。
trueを指定した場合、セッションオブジェクト「session」の利用が可能になる。
<'%@ page contentType="text/html; charset=Windows-31J" %>

・buffer
JSPページが実行されると、応答オブジェクトに書き込まれた出力は自動的にバッファされるが、
buffer属性を使用することでバッファサイズを設定出来る。
<'%@ page buffer="64kb" %>
<'%@ page buffer="none" %>

・errorPage
JSP実行時の例外が発生した場合に指定したエラーページにWebコンテナが制御を転送。
JSPファイルの先頭で使用すること。
<'%@ page errorPage="/errorpage.jsp" %>

・isErrorPage
errorPage属性で指定されるエラーページであるか否かを true/falseで指定。
trueを指定した場合、javax.servlet.jsp.JspException型の例外オブジェクト「exception」が利用可能。
<'%@ page isErrorPage="true" %>

==includeディレクティブ==
別ファイルの組み込みに使用。
ASPでも同様の機能があり、DB接続などの共通関数は共通ファイルとしてインクルードするのが一般的。
<'%@ include file="common.jsp" %>

pageディレクティブによるインクルードは 静的インクルード。
動的インクルードは インクルードアクション。
静的なインクルード:
JSPページのコンパイル前にインクルードファイルを読み込んでコンパイル。
動的インクルード:
実行時にインクルードファイルを読み込む。

==taglibディレクティブ==
接頭辞と使用するタグライブラリを指定。
<'%@ taglib prefix="test" uri="testtaglib.tld" %>

□宣言
JSPページで使用する変数の宣言や、メソッドの定義に使用。
宣言部に宣言した変数はクラス変数となり、ページがJSPエンジンにロードされた時に一度だけ初期化される。

宣言部は <'%! 各宣言 %> と記述。
JSP内に何度定義してもOK。
一つの宣言部に変数を複数宣言したり、メソッドを複数定義することも可能。
<'%! int iCnt = 0; %>

□スクリプトレット
<'% javaソース %> の中に通常のJavaソースを記述出来る。
宣言部が JSPエンジンにロードされた時に一度だけ実行されるのに対して、スクリプトレットはページにリクエストがあるたびに実行される。
<'%@page language="java"%>
<'html>
<'body>
<'%
for(int i = 0; i <' 10; i++){
for(int c = 0; c <'= i; c++){
out.print("*");
}
out.print("<'br>");
}
%>
<'/body>
<'/html>

※out
JSP内で宣言なしで使用できる暗黙的なオブジェクト
javax.servlet.jsp.JspWriterクラスの実態

□式
任意のオブジェクト型、リテラル値、基本データ型、メソッドの戻り値、算術式の結果を出力。
<'%= 出力する値 %>

※<'%=で始まり、 %>で終了すること
※式はセミコロン(;)で終了すること。

<'%@page language="java"%>
<'html>
<'body>
<'%! int i = 0; %>
<'%= ++i %>
<'/body>
<'/html>

※メソッドを記述する式も有効。ただし、戻り値を持たないメソッドの式での記述は不可。

<'%@page language="java"%>
<'html>
<'body>
<'%!
int i = 0;
int iIncrement(){
return ++i;
}
%>
<'%= iIncrement() %>
<'/body>
<'/html>

□アクション
JSPエンジンに特定の処理を行うように命令できる。
標準で提供されているタグは6種類。
※プログラマがタグを定義してそれをJSP内で使用することも可能。
<'%jsp:forward %> →別ページに遷移
<'%jsp:include %> →動的インクルードを実行
<'%jsp:useBean %> →beanの使用を宣言
<'%jsp:setProperty %> →beanのプロパティ値を設定
<'%jsp:getProperty %> →beanのプロパティ値を取得
<'%jsp:plugin %>


□コメント
<'%-- から始まって、 --%> で終わる。
※JSPのコメントの入れ子はNG。
※スクリプトレットや宣言部では Javaのコメントを使用すること。

[helloworld.jsp]

<'%@ page language="java" contentType="text/html; charset=Windows-31J" %>
<'html>
<'body>
Hello World
<'%-- JSPのコメント --%>
<'% // Javaのコメント形式 %>
<'!-- HTMLのコメント形式 -->
<'/body>
<'/html>

[出力結果]

<'html>
<'body>
Hello World

<'!-- HTMLのコメント形式 -->
<'/body>
<'/html>


ref:
http://www.site-cooler.com/java/j2ee/04_02.htm
2007-07-09 02:25 : j2ee : コメント : 0 : トラックバック : 0 :

Servlet 2.4/JSP 2.0

==error=============
org.apache.jasper.JasperException:
/WEB-INF/jsp/hello.jsp(7,21) TLD又はタグファイル中のattribute指示子に従って属性valueはどんな式も受け付けません

==reason=============
Servlet2.4/JSP2.0JSTL1.0を使用していたため。

※文字化け→see comment

==solution===========
□version of Servlet-JSP
Servlet 2.3/JSP 1.2で使えるJSTLJSTL 1.0
Servlet 2.4/JSP 2.0で使えるJSTLJSTL 1.1

Servlet 2.4/JSP 2.0 → HTMLに直接ELが書ける。
※Tomcat suppots 2.4.

※文字化け→see comment

□2.3準拠
==web.xml==
<'?xml version="1.0" encoding="Shift_JIS"?>
<'!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<'web-app>
...
<'/web-app>
==jsp==
<'%@taglib prefix="c" uri="http://java.sun.com/jstl/core"%>

2.4準拠
==web.xml==
<'?xml version="1.0" encoding="Shift_JIS"?>
<'web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
...
<'/web-app>
==jsp==
<'%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


====================
ref:
Jakarta TomcatとJakarta TaglibsとApache Strutsとその他の部屋
http://kamakura.cool.ne.jp/oppama/ssja/servlet24.html
wakasa.org
http://wakasa.org/archives/java/index.html

tag : Servlet 2.4 JSP 2.0 JSTL 1.1

2007-06-30 01:59 : j2ee : コメント : 1 : トラックバック : 0 :

DAOデザインパターン

J2EEデザインパターンの一つ。
開発者は低レベルのデータアクセス操作と高レベルのビジネスロジックとの分離が目的。
典型的な実装に要するコンポーネント:
DAOファクトリークラス
DAOインターフェイス
・コンクリートクラス(DAOインターフェイスの実装クラス)
・データ転送オブジェクト(バリューオブジェクト)

□トランザクション境界設定
=トランザクションの境界定義の仕方。
J2EE仕様では、2つのモデルを記述。
・プログラマチック・トランザクション境界設定
・宣言トランザクション境界設定(→def transaction property by using EJB deployment-descriptor.)
JDBC APIか、Java Transaction API(JTA)で境界設定の実装。
JDBC API:JTAより簡単
JTA:柔軟性に優れてる

JDBCによるトランザクション境界設定
JDBCトランザクションはConnectionオブジェクトで制御される。
JDBCコネクション・インターフェイス(java.sql.Connection)には2つのトランザクション・モジュール(自動コミット&手動コミット)がある。
JDBCトランザクション境界設定で、複数のSQLステートメントを組み合わせて1つのトランザクションに出来る。
欠点:
複数DBに対応しない点。
(トランザクションのスコープが一つのデータベース・コネクションに限られるため。)

JTAの概略
JavaトランザクションAPI(JTA)と、Javaトランザクション・サービス(JTS)は、J2EEプラットフォーム用の分散トランザクション・サービスを提供する。
分散トランザクションには、トランザクション・マネージャーと、1つ以上のリソース・マネージャが関係する。
リソースマネージャー:
任意の種類の永続的なデータソース。
トランザクション・マネージャー:
トランザクションに関係する同士のコミュニケーションを調整する。

JTAによるトランザクション境界設定
JTAでトランザクション境界設定するには、APはjavax.transaction.UserTransactionインターフェイスのメソッドを起動する。
=UserTransactionオブジェクトへのJNDIルックアップ==
import javax.tansaction.*;
import javax.naming.*;
//...
InitialCotext ctx = new InitialContext();
Object txObj = ctx.lookup("java:comp/UserTransaction");
UserTransaction utx = (UserTransaction) txObj;
==================================================
UserTransactionオブジェクトへの参照が出来ると、APはトランザクションを開始する。
=JTAでトランザクションでの開始====================
utx.begin();
//...
DataSource ds = obtainXADataSource();
Connection con = ds.getConnection();
pstmt = con.prepareStatement("UPDATE..");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
//...
utx.commit();
//...
==================================================
APがcommit()を起動すると、トランザクション・マネージャーは2フェーズ・コミット・プロトコルを使ってトランザクションを終了。

※JTAでトランザクション境界設定をする場合:
javax.sql.XADataSourceとjavax.sql.XAConnection、javax.sql.XAResourceインターフェイスを実装したJDBCドライバが必要。
XADataSourceオブジェクト:XAConnectionオブジェクトのファクトリー。
XAConnections:JTAトランザクションに参加するJDBCコネクション。

J2EEアプリケーションは、JNDIを使ってデータソースをlookup。
一旦データソース・オブジェクトへの参照が出来れば、APはDBに接続できるように、javax.sql.DataSource.getConnection()をコールする。

□XAコネクション

JDBCの自動コミット・フィーチャーはサポートしてない。
APはXAコネクション上のjava.sql.Connectin.commit()やjava.sql.Connection.rollback()をきどうしてはダメ。
代わりにUserTransaction.begin(), commit(), rollbackを使用する。


ref:
http://www-06.ibm.com/jp/developerworks/java/040305/j_j-dao.html

tag : DAO JDBC JTA JTS UserTransaction

2007-05-30 02:58 : j2ee : コメント : 0 : トラックバック : 0 :

Spring2.0 VS EJB3.0

summary of "Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0"
------------------------------
Def

Spring=実装

EJB3.0=仕様

------------------------------
Webサイトにおいて

Spring:
階層化されたJava/J2EEアプリケーションフレームワーク

EJB3.0:
オブジェクト指向、分散型、企業レベルの各アプリの開発および配備のためのコンポーネント・アーキテクチャ

フレームワーク=サポート
アーキテクチャ=決定

------------------------------
持続性

Spring:サポートする
EJB3.0:サポートする

Springは、持続性の設計思想を忠実に守り、持続性のFWを再実装はせず、JDBC、Hibernate、JDO、iBatis、JPA(Java Persistence API)等のFWを統合。
EJB3.0は、エンティティBeanをJPAで置き換え。

□JPA
簡素化された軽量なオブジェクト関係マッピングFWを提供することを目指したもの。
JPAの仕様は、持続性プロバイダとのインタラクション、リレーショナルDBへのentityのmpgのための各IFをdef。

------------------------------
持続性

Spring
Hibernateとの連携の詳細がHibernateDaoSupportクラスによって抽象化されてる。
HibernateDaoSupportクラスはHibernateのplumbingを提供してSpringのHibernateテンプレートと依存関係との連携を支援する。

EJB3.0
コンテナによってentityManagerが自動的に注入される。

□HibernateのSessionとJPAのEntityManager
Hibernate#sessionはentity cacheであると同時にORMエンジンへのIFでもあるが、
JPAでは、これら2つは別物。

------------------------------
持続性

Spring/Hibernate#mapping = xml file

JPA-AP = annotation
→必要な設定が減り、変更対象のobjectに近い場所にmpg dataを置く事で可視性がup。

------------------------------
持続性#cache処理
cache=ORMツールを扱う場合に重要な概念の1つ

Spring
スレッドローカル変数を用いてsession(transaction)をスレッドにアタッチするアプリによってcache処理が実現。

EJB3.0
持続性ctxがtransactionに自動的に伝搬される。

□延滞初期化(lazy initialization)
持続性entityをDBから取得する度にその関係を全て自動的にフェッチするのは非効率的。実際にdataが必要になるまで特定のDB操作を保留すること。

------------------------------
持続性#cache処理

Spring/Hibernateがとっているアプローチは、viewの作成に応じてcacheのopen/closeを行うもの。
Springには、これを簡単化するOpenSessionInViewFilterが用意されている。
(ただし、設定が要る。)

EJB3.0仕様では、持続性ctxに興味深いscopeが追加されており、ステートフルセッションBeanの存続期間を上限としてcacheの存続期間を制限することが可能。
これは拡張持続性コンテキスト(extended persistence context)と呼ばれ、その指定はステートフルセッションBeanにおいて持続性ctxに注釈を付けることによって行う。


------------------------------


ref:
Rod Coffin, "Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0", August 31, 2006
en: http://www.devx.com/Java/Article/32314
ja: http://japan.internet.com/developer/20061114/print27.html

tag : EJB Spring

2007-05-21 00:31 : j2ee : コメント : 0 : トラックバック : 0 :

トランザクションのscopeとトランザクション属性

□Required
クライアントがあるトランザクションの下にあった場合で、
クライアントがビーンのメソッドを呼び出したとする。
この時、このメソッドの実行は、
クライアントが属するトランザクションの下で行われる。
もし、クライアントがトランザクションの下にない場合、
コンテナは、メソッドを走らせる前に、
新しいトランザクションを開始する。
この属性は、たいていのトランザクション処理にたいして有効で、
デフォルトのトランザクション属性として使うことが出来る。

□RequireNew
クライアントにトランザクションの下になかった場合、
メソッドの呼び出しに際して
新しいトランザクションを始めるという点ではRequierdと同じだが、
クライアントがあるトランザクションの下で走っている場合は、異なる処理をとる。
まず、クライアントのトランザクションを一時停止し、
新しいトランザクションを開始させ、その下でメソッドを呼び出す。
メソッドの呼び出しが終わったら、元のクライアントのトランザクションを復活させる。
この属性を使えば、メソッドの呼び出しは、必ず、新しいトランザクションの下で行われるようにすることが出来る。

□Mandatory
クライアントがあるトランザクションの下にあった場合、
ビーンのメソッドの実行は、クライアントの属するトランザクションの下で行われる。
もし、クライアントがトランザクションの下にない場合、
コンテナは、TransactionRequiredException 例外を投げる。
この属性は、結局、すべてのメソッド呼び出しが、クライアントのトランザクションの下で行われるべきことを要求する。

□NotSupported
クライアントがあるトランザクションの下にあり、
ビーンのメソッドを呼び出した場合、
コンテナは、メソッドの呼び出し前に、
クライアントのトランザクションを一時停止し、
メソッドの実行後に、それを復活させる。
もし、クライアントがトランザクションの下にない場合、
コンテナは、メソッドの呼び出しに際して、
新しいトランザクションを始めることはない。
メソッドは、コンテナの生成するトランザクションの下では、
決して実行されないことになる。

□Supports
クライアントがあるトランザクションの下にあった場合、
ビーンのメソッドの実行は、クライアントの属するトランザクションの下で行われる。
クライアントがトランザクションの下にない場合は、
コンテナは、メソッドの呼び出し時に、新しいトランザクションを始めたりはしない。 この属性の場合には、トランザクションの働きが、同じメソッドでも変わることがありうるので、注意が要る。

□Never
トランザクションの下で走っているクライアントが、
ビーンのメソッドを呼び出そうとする時に、コンテナが、RemoteExceptionを投げる。
クライアントがトランザクションの下にない場合、
コンテナが、メソッドの呼び出し時に、新しいトランザクションを始めることはない。


ref:
http://www.wakhok.ac.jp/~maruyama/j2ee/j2ee/node97.html
2007-04-20 22:56 : j2ee : コメント : 0 : トラックバック : 0 :
ホーム

search

ad



counter


tag cloud

category cloud