‘Application Server/GlassFish’ カテゴリーの投稿

「GlassFish v3 で実感!! エンタープライズ Java の進化」資料公開

Java Hot Topic セミナーのプレゼン資料とデモを公開します。

今回の発表のポイントは、Java EE 6 になり開発が如何に楽になったか、アプリケーションサーバのインストールも起動も如何にかんたんで高速になったのかという点に集中して説明を致しました。原稿は合計 120ページ程ありますが、全てを発表したわけではなく、抜粋して説明しました。特に JPA 2.0 については日本でまだあまり資料がないので参考にして頂けるのではないかと思います。


「GlassFish v3 で実感!! エンタープライズ Java の進化」プレゼン資料 (PDFの入手)

Java EE 6 のかんたん開発デモビデオの入手

GlassFish v3 のかんたんインストールデモビデオの入手

2010年5月30日 at 8:33 PM コメントする

Java Hot Topic セミナー緊急開催決定

今日は Java の勉強会開催に関する緊急告知をいたします。

本セミナーの受付は大変好評につき締め切りました。
ご登録頂いた皆様、誠にありがとうございました。

キャンセル待ちの手順:


件名を「ホットトピックセミナー キャンセル待ち」として本文に
「お名前」「ご所属」をご記入の上、以下までご連絡ください。
Mail: hottopics-seminar-japan@sun.com
※ キャンセル待ちの受付については確認メールはお送りしません。
※ 空きが出ましたら、個別にメールをお送りします。キャンセル状況
のお問い合わせには対応できませんのでご注意ください。


来る 2010 年 5 月 29 日 (今週土曜日) に Java の Hot Topic セミナーを緊急開催する事にしました。今回の Java Hot Topic セミナーはご参加頂いた皆様に、もれなく何らかの Sun ノベルティグッズをプレゼントする予定です。
(例:GlassFish Tシャツ、Java リング、Duke マウス、Sun ノート、Sun 時計等先ほどまで色々と大量に見つけ出してきましたので、かならず何かお渡しできると思います。)
今週末の開催という事で直前のご案内となり誠に申しわけございませんが、どうぞスケジュールをご調整の上ご参加頂ければ幸いです。

発表内容の詳細は後ほど決まり次第ご連絡いたします。


開催概要■ 3時間で学ぶ Java Hot Topic 2010
■ 日程2010 年 5 月 29 日 (土)
13:00 開場、13:30 セミナー開始、16:30 頃終了予定
発表内容
1. クロージャあらため、Project Lambda
Java in the Box 主筆
櫻庭 祐一 氏
2.Scala 入門 (仮)
町田 修一 氏
3.GlassFish v3 で実感!!エンタープライズ Java の進化
GlassFish エバンジェリスト
寺田 佳央
4. NetBeans 最新情報
Java エバンジェリスト
片貝 正紀
■ 会場サン・マイクロシステムズ株式会社 用賀本社27階セミナールーム田園都市線用賀駅改札を出てすぐ右側がSBS ビルの入り口です。ビルと駅は地下でつながっています。エレベーターにて27階まで直接お越しください。
■ 費用無料(事前登録制)

■ 主催
サン・マイクロシステムズ株式会社
■ お申込み 
件名を「ホットトピックセミナー参加」として本文に「お名前」「ご所属」をご記入の上、以下までお申し込み下さい。Mail: hottopics-seminar-japan@sun.com


今回はできるだけ多くの方に参加していただきたいと考えておりますが、会場規模の都合上、定員になり次第締め切らせていただきます。
一度申し込みをした後仮に、スケジュールの都合上どうしても参加ができなくなった場合、他の方を繰り上げ当選にしたいと考えておりますので、大変恐れ入りますが欠席される際は上記アドレスまで欠席のご連絡を頂けないでしょうか。

最後に余談ではありますが、私にとって「 Sun 」のエンジニアとして最後の発表になるかと思います(会社を辞めるわけではありませんが)。Sun の Java エバンジェリストとして活動して来た数年間を思い出すと色々感慨深いものがありますが、今回は Sun/Java/GlassFish を応援してくださった皆様へ感謝とお礼を込めて開催したいと考えております。

ちなみに、日本では Oracle と正式統合が完了していない為、私の口から今後の Oracle 製品と既存 Sun 製品に関する話題については申し上げる事ができませんので、どうぞご了承ください。

2010年5月24日 at 3:41 PM コメントする

EJB 3.1 の新機能概要

EJB 3.1 の新機能をプレゼン形式でまとめてみました。
かんたんに概要を紹介します。

EJB 3.0 から EJB 3.1 になり、かんたん開発に向けて多くの改善が施されています。まず、パッケージの簡略化が挙げられます。今までアプリケーションの種類に応じて .ear, .war 等のアーカイブにまとめる必要がありましたが、EJB コンポーネントも .war に含めることができるようになったため開発時の手間が大幅に削減されます。また、EJB 3.1 Lite が提供されフル Java EE の機能の一部の機能だけを利用できるようになったため、フル Java EE の機能が必要ないお客様にとっては不要なメモリリソースを消費せずに運用できる等のメリットがあります。

次のポイントはローカルビジネスインタフェースの実装が必要なくなった点です。これは開発者の生産性が向上するだけではなく、修正の手間も大幅に削減してくれます。例えば、過去に実装したクラスにおいて、特定のメソッドに対する引数や返り値の変更が必要になった場合を想定してください。今まではインタフェースのメソッド定義と実装クラスのメソッド定義を両方変更しなければなりませんでしたが、インタフェースの定義が必要がなくなったため、実装クラスのメソッド定義を変更するだけでよくなります。

次に、移植可能な Global JNDI 名では、今までベンダー独自に実装していた Global の JNDI 名が仕様の中で標準化されましたので、今後アプリケーションを他のアプリケーションサーバへ移行したいような場合、Global JNDI 名を変更する必要がなくなり移植性が高まります。

また、Java SE に組み込み可能な EJB コンテナ は開発時におけるテストの手間を大幅に削減してくれるようになります。今までは EJB のアプリケーションをテストする際、アプリケーションサーバにデプロイして Global 経由でアクセスする等の必要がありました。これは別の Java VM のプロセスとして稼働するためデバッグ等も困難でしたが、EJB 3.1 では Java SE のプロセス内に EJB コンテナをロードして実行する事ができるようになるため、同一 Java プロセス内で処理ができる他、EJB の単体テスト等がしやすくなります。

その他の追加機能として、Singleton Session Beans が追加された事が挙げられます。これはアプリケーション間で同一の情報を扱いたい場合に有効です。今までは独自に Singleton のクラスを作成して運用しなければなりませんでしたが、クラスタ環境のように複数台で実現するためには苦労していたかと思います。なぜなら異なる JVM プロセスの間で Sigleton のインスタンスを共有させる事は面倒だったからです。しかしEJB 3.1で提供する Singleton Session Bean はコンテナを跨ぐ環境においても唯一のインスタンスが保障されるため、こういった実装の手間が必要なく、アノテーションの追加だけで利用できるようになります。その他、タイマーサービスや非同期処理もそれぞれアノテーションを利用して簡単に実装できるようになっています。

最後に、
EJB といえば実装が難しい、設定も面倒という時代は今や過去の事で、今では実装がとてもかんたんになっています。また便利な機能をデフォルトで数多く持っている便利なフレームワークですので、今一度EJB を見直し利用をご検討ください。



























2010年4月7日 at 8:32 PM コメントする

GlassFish の今後のロードマップ

GlassFish の今後のロードマップが発表されています。発表資料

この資料中では、直近でリリース予定の GlassFish v2.1.1, v3.0.1の他、GlassFish v3.1 、v3.2 、v4 についても触れらてています。

この資料の中で特に興味深いのは、GlassFish v4 という名前が初登場した事で、次期 Java EE である Java EE 7 に対応する製品になるようです。資料中に記載されているスケジュールはあくまでも予定ですので(今までの経験から)今後変更される事が予想できますが、今後も GlassFish が継続してオープンソースのアプリケーションサーバとして提供されていく事をご確認いただけるかと思います。
ぜひ、この資料をご確認ください。

2010年3月26日 at 3:03 PM 1件のコメント

Servlet 3.0 web-fragment.xml による設定

Web アプリケーションの開発者は Apache Wicket や Spring 等 Servlet とは異なる別の外部フレームワークを開発時に利用する事があるかと思います。これらの外部フレームワークを使用するためには、これらのフレームワーク特有の設定 (Servlet, Filter 等)を web.xml に設定する必要があります。しかし複数の外部フレームワークを同一アプリケーション内で使用する場合、単一の web.xml ファイル内に全ての設定が含まれファイルが肥大化します。また web.xml ファイルが肥大化すると、各フレームワーク毎の設定を管理する際に可読性も低下しているため、管理が困難となります。

そこで、Web Fragment はフレームワーク毎に独自に設定を登録、管理できるようなメカニズムを提供しています。このWeb Fragment は Servlet 3.0 に導入された新しい技術で、配備記述子をモジュール化し、コンテナがモジュール化した配備記述子を認識する事ができるようになり、上記のような問題を解決しています。
一つの、web-fragment.xml ファイルは web.xml の一部として認識され、利用する外部フレームワーク毎に複数の web-fragment.xml を作成することもできます。

それでは、web-fragment.xml をどこに作成するか確認してみましょう。まず、Web アプリケーションのプロジェクトを作成します。この際、WEB-INF/lib ディレクトリ配下に、web-fragment.xml を含む jar ファイル (下記の例ではExternalLib.jar) をコピーします。

> jar tvf FragmentSample.war
0 Sun Mar 14 14:36:00 JST 2010 META-INF/
95 Sun Mar 14 14:35:58 JST 2010 META-INF/MANIFEST.MF
0 Sun Mar 14 14:36:00 JST 2010 WEB-INF/
0 Sun Mar 14 14:36:00 JST 2010 WEB-INF/classes/
0 Sun Mar 14 14:36:00 JST 2010 WEB-INF/lib/
2076 Sun Mar 14 14:36:00 JST 2010 WEB-INF/lib/ExternalLib.jar
515 Sun Mar 14 14:36:00 JST 2010 WEB-INF/sun-web.xml
469 Sun Mar 14 14:36:00 JST 2010 index.xhtml


ExternalLib.jar には、META-INF ディレクトリ配下に web-fragment.xml を作成します。
> jar tvf ExternalLib.jar
0 Sun Mar 14 14:36:00 JST 2010 META-INF/
109 Sun Mar 14 14:35:58 JST 2010 META-INF/MANIFEST.MF
995 Sun Mar 14 14:36:00 JST 2010 META-INF/web-fragment.xml


web-fragment.xml には下記のような内容を記載します。下記の例では JSF 2.0 の設定を web-fragment.xml に記載していますが、web.xml に記載する内容とほぼ同様の内容が記載されている事が分かります。
<?xml version=”1.0″ encoding=”UTF-8″?>
<web-fragment xmlns=”http://java.sun.com/xml/ns/javaee” 
              xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
              xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee 
              http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd”
         version=”3.0″>

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-fragment>

web.xml の記載は、Servlet 3.0 からオプション化されていますので、web.xml が無くても上記は動作しますが、web.xml を記載する場合は、<metadata-complete> に true が設定されていないことを確認してください。この<metadata-complete> はアノテーションの利用を許可したり、外部リソースをコンテナが自動的に検出するかどうかを指定する設定ですが、true に設定されていると、アノテーションの利用が不可になる他、web-fragment.xml 等のリソースの自動検出ができなくなります。このタグが記述されていない場合、もしくは false に設定されている場合は、アノテーションも、リソースの自動検出も有効になりますので確認してください。

<web-app version=”3.0″ xmlns=”http://java.sun.com/xml/ns/javaee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd” metadata-complete=”false”>
(例:Servlet 3.0 でアノテーション、web-fragment.xml の有効化)

また、複数の外部フレームを利用する場合、フレームワーク毎にそれぞれの web-fragment.xml を作成する事もできます。また、設定を読み込む順番を指定するため2種類の方法を提供しています。

● Absolute Ordering
  web.xml ファイルに、<absolute-ordering> を指定して順番を設定します。

● Relative Ordering
  web-fragment.xml ファイルに <ordering> を指定して順番を設定します。

例えば、2つの外部フレームワークを2つの Web Fragment(Fragment1, Fragment2) にそれぞれ設定した場合を想定します。この時、web.xml に順番を指定する場合、下記のように記載します。web.xml の設定が最初に読み込まれた後、Fragment2→Fragment1の設定が読み込まれます。

   <web-app>
       <name>MyApp</name>
       <absolute-ordering>
          <name>Fragment2</name>
          <name>Fragment1</name>
       </absolute-ordering>
       …
   </web-app>


最後に、web-fragment.xml の設定は外部フレームワークやリソースをモジュール化して読み込ませる事が可能になる他、web.xml の肥大化を防ぎ、可読性も向上するため設定管理が楽になります。是非お試しください。

備考:
最初は、上記 web-fragment.xml の設定を Wicket 1.4 を使用して試しましたが動作させる事ができませんでした。調査した結果、現在の Wicket 1.4 は WicketFilter 中で web.xml ファイルを直接参照するように実装されているため、web-fragment.xml の設定ファイル中から設定を読み込む事ができないためでした。今後 WicketFilter 側で修正が施されれば、Wicket の設定も web-fragment.xml に含める事ができるようになるかもしれません。

WicketFilter.java のソースコード

実装部分:
InputStream is = filterConfig.getServletContext().getResourceAsStream(“/WEB-INF/web.xml”);

2010年3月14日 at 4:04 PM コメントする

Servlet 3.0 の新機能概要

Servlet 3.0 の新機能をプレゼン形式でまとめてみました。個々の機能に関する詳細は別途記載する予定ですが、ここでかんたんに概要を説明します。

Servlet 3.0 は Servlet 2.5 からかなり多くの改良が施されています。
Java SE 5 から利用可能になった、アノテーションを利用し、今まで web.xml に記載していた Servlet や Filter 等の設定をアノテーションで記載できるようになり開発生産性が大幅に向上しました。
また、プラガビリティの向上として、外部のフレームワークやライブラリの設定を web.xml 以外のファイル (web-fragment.xml) に記載できるようになったため、web.xml の肥大化を抑制でき、またフレームワークの設定管理が容易になっています。
その他では Servlet API 自身でマルチパートを扱えるようになったため、Servlet API だけでファイルをアップロードすることができるようになっています。
さらに、Servlet 3.0 から非同期処理を実現できるようになっています。この非同期処理機能は、Comet/Reverse Ajax 等のアプリケーションを実装できる他、DB アクセス等とても処理に時間がかかるような処理を非同期で処理する事ができるようになります。例えば、HttpServlet のスレッドとは別のスレッドで非同期に実現する事で DB が高負荷時に HttpServlet の最大スレッド数に到達し Web のアクセスが不可になる状態を防ぐ事もできます。
その他では、HttpServletRequest に login/logout/authenticate のメソッドが含まれ、プログラムを利用しログイン/ログアウト処理を実装できるようになった他、@ServletSecurity を使用して web.xml に記載していた < security-constraint > の設定をプログラム中で宣言できるようになっています。

改良された、Servlet 3.0 を是非お試しください。


web.fragment.xml に関する詳細は 「Servlet 3.0 web-fragment.xml による設定」 のエントリをご参照ください。


マルチパートの詳細は 「Servlet 3.0 File Upload 機能」 のエントリをご参照ください。

2010年3月14日 at 2:26 AM コメントする

ここから始める Java EE 6

2009年12月に Java EE 6 がリリースされて、約3ヶ月経ちました。Java EE 6 にはかなり多くの改善がみられますが、どこから始めればいいのかわからない方に、JSF2,JPA2,EJB 3.1を使ったかんたんな Java EE 6 アプリケーションの書き方を紹介します。

Java EE 6 には非常にたくさんの技術が含まれているので一度に全てを理解することは大変だと思いますが、まずはこのサンプルを通じて、JSF,JPA,EJB にどのような変更が加わったのか、またどのような点が楽になったのか等を理解して頂ければと思います。

開発/実行環境:
開発環境:NetBeans 6.8
実行環境:Oracle GlassFish Server v3

(上記は別途インストールしておいてください。)

サンプルアプリケーションの概要:

コードを書く前にこれから作成するサンプルアプリケーションの概要について説明します。このアプリケーションはとても簡単なアプリケーションでユーザ(データ)を登録して参照するだけという、いたってかんたんなアプリケーションです。また処理フローもとてもシンプルです。

サンプルアプリケーションの処理フロー

アプリケーションの完成予想イメージは下記です。ユーザ登録画面で「作成」ボタンを押下しデータを登録した後、一覧表示画面が表示されます。また一覧表示画面中の「新規作成」のリンクを押下すると登録画面に遷移します。

サンプルアプリケーションの完成イメージ

1.新規プロジェクトの作成

それでは早速プロジェクトを作成していきます。今回作成するアプリケーションは、EJBを含んでいますが新規プロジェクトの作成時「Web アプリケーション」を選択して作成することにします。

補足:
Java EE 6 におけるパッケージ構成の変更点を紹介します。過去の Java EE のバージョンでは下記のように EJB を ear にまとめたり、JSF/Servlet 等を war にまとめたりといったようにパッケージ構成が面倒でした。Java EE 6 からはこのようなパッケージ化の必要はなくなり、EJB も war に含めてデプロイできるようになりました。 

パッケージの簡略化

それでは、メニューから「ファイル」→「新規プロジェクト(W)…」→「Java Web」→「Web アプリケーション」を選択し、「次へ>」ボタンを押下してください。

新規プロジェクトの作成

プロジェクト名に「PersonManagement」を入力し「次へ>」ボタンを押下します。

新規プロジェクト作成

次に、「サーバと設定」で配備するアプリケーションサーバとJava EE のバージョンを選択します。ここでは、「GlassFish v3 ドメイン」と「Java EE 6 Web」を選択し「次へ>」ボタンを押下します。

稼働サーバとフレームワークの選択

次に、使用するフレームワークを選択します。今回は、「JavaServer Fcaces」を使用しますのでこれにチェックを付け「完了(F)」ボタンを押下します。

フレームワークの選択

プロジェクトを作成すると下記のような画面が表示されます。

プロジェクト作成完了

2. JPA 2.0:Entity Bean の作成

新規プロジェクトを作成後、Entity Bean を作成します。Java EE 5 から Entity CMP 2.x に代わり JPA 1.0 が登場し、DBに対する持続性のコード記述がかなり楽になりました。JPA 2.0 ではさらに扱いやすくなり、機能面でも改善が施されています。(JPA 2.0 の新機能の詳細は別途記載する予定です。また今回はとても簡単なサンプルのためJAP 2.0の新機能はあまり使用していません。JPA 1.0と同等レベルの記述内容)

それでは、実際に Entity Bean を作成してみましょう。メニューから「ファイル」→「新規ファイル(N)…」→「持続性」を選択してください。

NetBeans を利用すると既存のデータベースのテーブルから Entity クラスを自動的に生成する事ができます。既に DB テーブルを作成している場合は「データベースからのエンティティークラス」を選択して作成してください。NetBeans を使う上で、この機能は大変便利です。私も普段は先に DB のテーブルを作成して、Entity クラスは NetBeans で自動生成しますので一から Entity クラスを作成する事はあまりしません。是非お試しください。

今回、私は DB のテーブルが作成されていない状態で新規にエンティティークラスを生成しますので「エンティティークラス」を選択し「次へ>」ボタンを押下します。この方法では、エンティティークラスを先に作成した後、エンティティクラスに該当するテーブルを DB 上に後から構築します(Entity クラスを元にテーブルを自動生成することもできます)。

エンティティークラスの作成

ここで新しいエンティティークラス名「Person」、パッケージ名「ent」を入力します。「主キー型」はこのテーブルの主キーの型を選択します。Person を ID で管理しますので、そのまま、「Long」型を設定します。

エンティティクラスの作成

「完了(F)」ボタンを押下する前に1点注意してください。ワーニングで「プロジェクトに持続性ユニットがありません。エンティティークラスを持続さ…」というメッセージが表示されています。これはこのエンティティクラスに対する持続性ユニットが存在していない事を意味しています。そこで「持続性ユニットを作成…」ボタンを押下し、このエンティティクラスに紐づく持続性ユニットを作成します。ボタンを押下すると下記の画面が表示されます。

持続性ユニットの作成

持続性プロバイダとして JPA 2.0 の参照実装である「EclipseLink(JPA 2.0)(デフォルト)」と、データソースを選択します。また表生成の方針ですが、「作成」を選択すると自動的に DB にテーブルを作成します。全ての入力が完了した後、最後に「作成」ボタンを押下します。
この時、後のプログラミング時に使用しますので、入力した持続性ユニット名(PersonManagementPU)を覚えておいてください。

「作成」ボタンを押下すると、「新規エンティティ作成画面」に戻ってきますが、持続性ユニットに関するワーニングが消えたことを確認した後、最後に「完了(F)」ボタンを押下してください。ボタンを押下すると入力された情報を元に ID のみを持つ Person エンティティのひな形が自動生成されます。また同時に、構成ファイル配下に、持続性ユニットの設定ファイル persistence.xmlが自動生成されます。

作成された Entity クラス(Person)のひな形を編集していきます。

ソースコードを確認すると @Entity のアノテーションが自動的に付加されている事に気づきます。このアノテーションを付加することによりコンパイラや、EJB コンテナが本クラスをエンティティクラスと解釈してくれるようになります。

名前、住所、電話番号、年齢をあつかえるようにフィールドを追加し、それぞれに対するセッタ、ゲッタメソッドを記載してください。また、@NamedQuery で JPQL を記載し、DBに登録されている全ての Person を取得できるようにします。

package ent;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;&nbsp;

@Entity
@NamedQuery(name="findAllPerson", query="SELECT p FROM Person p")
public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable=false,length=256)
    private String name;

    @Column(nullable=false,length=256)
    private String address1;

    @Column(nullable=false,length=12)
    private String telephone;

    @Column(nullable=false)
    private Long age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Person)) {
            return false;
        }
        Person other = (Person) object;
        if ((this.id == null &amp;&amp; other.id != null) || (this.id != null &amp;&amp; !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entity.Person[id=" + id + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress1() {
        return address1;
    }

    public void setAddress1(String address1) {
        this.address1 = address1;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public Long getAge() {
        return age;
    }

    public void setAge(Long age) {
        this.age = age;
    }
}

以上で、このサンプルアプリケーションに必要なエンティティクラスはできました。

3.EJB 3.1:ステートレスセッション Bean の作成

エンティティクラスを生成したので、次に EJB (ステートレス・セッション Bean) を作成します。「ファイル」→「新規ファイル(N)…」→「Java EE」→「セッション Bean」を選択し、「次へ>」ボタンを押下してください。

EJB セッション Bean の作成

ボタンを押下すると下記の画面が表示されます。ここで「EJB 名(N)」、「パッケージ(K)」を入力し「完了(F)」ボタンを押下します。

ステートレスセッション Bean の作成

補足:
上記画面を確認するとローカルインタフェース、リモートインタフェースが選択できるようになっています。
EJB 3.1 からローカルインタフェースがオプション化されインタフェースを作成する必要がなくなりました。EJB 3.0 では下記の例のようにインタフェースを定義し、それを実装しなければなりませんでしたが、EJB 3.1 からはアノテーションを付加するだけでコンテナが理解してくれるようになります。 

EJB 3.0 でのローカルインタフェースの実装例

EJB 3.0

実際にコードで書くと下記のようになります。

public interface Hello {
    public String sayHello();
}

@Stateless
public class HelloBean implements Hello {
    public String sayHello() { return "hello"; }
}

EJB の利用時

@EJB Hello helloRef;
    ...
    helloRef.sayHello();

これが、EJB 3.1 では下記のようにインタフェースを定義する必要はなくなります。

 

EJB 3.1

EJB 3.1 を利用する時のコードは下記となります。

EJB 3.1

 

それではコードを編集していきましょう。今回は、データの検索と追加を行いますので、それぞれの処理を行う2つのメソッドを実装しています。まず、@PersistenceContextのアノテーションで、(JPA Entity クラスを作成した時に作成した持続性ユニット名。persistence.xml に記載されている。)持続性ユニット名(“PersonManagementPU”)を記載します。これにより持続機能を持った EntityManager のオブジェクト(em)がセットされます。

package pejb;

import ent.Person;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class PersonEJB {

    @PersistenceContext(unitName="PersonManagementPU")
    private EntityManager em;

    public List<Person> findAllPersons(){
    //Entity(Person)クラスの @NamedQuery の記載に基づき検索
        Query query = em.createNamedQuery("findAllPerson");
        return (List<Person>) query.getResultList();
    }

    public Person createPerson(Person person){
        em.persist(person);
        return person;
    }
}

4.JSF:Managed Bean の作成

EJBと、Entity を作成したので、JSF から利用する Managed Bean を作成しましょう。「ファイル」→「新規ファイル(N)…」→「JavaServer Faces」→「JSF 管理対象 Bean」を選択し「次へ>」ボタンを押下してください。

「クラス名(N)」、「パッケージ(K)」を入力し「完了(F)」ボタンを押下します。

補足:
JSF 2.0 からは下記のような faces-config.xml の設定ファイルがオプション化されました。そこで Managed Bean の設定や画面遷移を XML ファイルに記載する必要はなく、アノテーションを利用しプログラム上で実現することができるようになりました。 

JSF1.2 までの faces-confg.xml の設定例:

<managed-bean>
<managed-bean-name>PersonController</managed-bean-name>
<managed-bean-class>PersonController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/foo.jsp</from-view-id>
<navigation-case>
<from-outcome>ok</from-outcome>
<to-view-id>/bar.jsp</to-view-id>
</navigation-case>
</navigation-rule>

 

 

コードを編集していきましょう。作成するクラスが Managed Bean であることをコンテナに理解させるため、@ManagedBean のアノテーションを利用します。アノテーションを指定する際、”name” 属性は必須で Managed Bean を識別する名前を入力します。

package mbean;

import ent.Person;
import pejb.PersonEJB;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.ejb.EJB;

@ManagedBean(name="PersonController")
@RequestScoped
public class PersonController {

    public PersonController() {
    }

    @EJB
    private PersonEJB personEJB;

    private Person person = new Person();
    private List<Person> personList = new ArrayList<Person>();

    //Facelets の action="#{PersonController.doNew} により画面遷移
    public String doNew(){
        return "createPerson.xhtml";
    }

    //Facelets の action="#{PersonController.doCreatePerson} により画面遷移
    public String doCreatePerson(){
        //画面から入力された Person を DB に登録
        setPerson(personEJB.createPerson(getPerson()));
        //DB に登録されている全 Person を personList に設定
        setPersonList(personEJB.findAllPersons());
        return "listPersons.xhtml";
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }
}

5.JSF 2.0: ベージの作成

最後に、表示画面を作成します。JSF 2.0 から facelet を xhtml で記載できるようになりました。

「ファイル」→「新規ファイル(N)…」→「JavaServer Faces」を選択し「次へ>」ボタンを
押下してください。

JSF 表示画面の作成

ファイル名 (createPerson.xhtml) を入力すると自動的に .xhtml の拡張子が付加されます、最後に「完了(F)」ボタンを押下します。

JSF 表示画面の作成

自動生成されたひな形を編集して下記のコードを記載してください。Facelets で扱えるタグ等は別途紹介する予定ですが、みていただければわかるとおり、HTML も記載する事ができますし、スタイルシート等を記載することも可能です。また、JSF 2.0 から Ajax をサポートしていますので、Ajax のコードを利用してサーバと通信する事もできるようになります。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
      <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <table>
                <tr>
                    <td>
                <h:outputLabel value="名前:"/>
                </td>
                <td>
                <h:inputText value="#{PersonController.person.name}"/>
                </td>
                </tr>
                <tr>
                    <td>
                <h:outputLabel value="住所"/>
                </td>
                <td>
                <h:inputText value="#{PersonController.person.address1}"/>
                </td>
                </tr>
                <tr>
                    <td>
                <h:outputLabel value="電話番号"/>
                </td>
                <td>
                <h:inputText value="#{PersonController.person.telephone}"/>
                </td>
                </tr>
                <tr>
                    <td>
                <h:outputLabel value="年齢"/>
                </td>
                <td>
                <h:inputText value="#{PersonController.person.age}"/>
                </td>
                </tr>
            </table>
            <h:commandButton value="作成" action="#{PersonController.doCreatePerson}"/>
        </h:form>
    </h:body>
</html>

最後に、登録された一覧を表示する画面を作成します。
「ファイル」→「新規ファイル(N)…」→「JavaServer Faces」を選択し「次へ>」ボタンを
押下してください。

JSF 表示画面の作成

ファイル名(listPersons)を入力し「完了(F)」ボタンを押下します。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
      <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body> 

        <h:dataTable value="#{PersonController.personList}" var="psn" border="1">
            <h:column>
                <f:facet name="header">
                    <h:outputText value="名前"/>
                </f:facet>
                <h:outputText value="#{psn.name}"/>
            </h:column>

            <h:column>
                <f:facet name="header">
                    <h:outputText value="住所"/>
                </f:facet>
                <h:outputText value="#{psn.address1}"/>
            </h:column>

            <h:column>
                <f:facet name="header">
                    <h:outputText value="電話番号"/>
                </f:facet>
                <h:outputText value="#{psn.telephone}"/>
            </h:column>

            <h:column>
                <f:facet name="header">
                    <h:outputText value="年齢"/>
                </f:facet>
                <h:outputText value="#{psn.age}"/>
            </h:column>
        </h:dataTable>
        <h:form>
            <h:commandLink action="#{PersonController.doNew}">
                新規作成</h:commandLink>
        </h:form>
    </h:body>
</html>

以上で、このアプリケーションの実装は完了です。

NetBeans のメニューより「実行(R)」→「主プロジェクトを実行(R)」を選択してください。実行すると自動的にブラウザがオープンしアプリケーションのデフォルトのコンテンツが表示されます。

コンテキストルートでアクセスされた時のデフォルトページを変更したい場合は、web.xml ファイルを編集する必要があります。下記のように welcome-file-list を編集してください。

web.xml の編集

<welcome-file-list>
<welcome-file>faces/createPerson.xhtml</welcome-file>
</welcome-file-list>

設定を変更した後、もう一度プロジェクトを実行してください。すると下記のように自動的に登録画面が表示されるようになります。

データを入力して「作成」ボタンを押下してみましょう。下記のように一覧表示画面が表示されれば問題はありません。

最後に、エラーハンドリングについて紹介します。例外が発生した際に特定のエラーページにリダイレクトさせるようにweb.xml の<error-page> タグを記載する必要があります。<exception-type>で、ハンドリングした例外毎にエラーページを表示させる事が可能です。本番環境においては、少なくとも JSF で発生する例外の親である javax.servlet.ServletException を記載してください。

web.xml の編集

<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/error.xhtml</location>
</error-page>

 

以上で、今回の Java EE 6 のアプリケーション作成は終了です。NetBeans を利用するとウィザードを使って、コードのひな形を作成してくれたり、また設定も極力 XML ファイルを手動で編集しなくても済むようになります。是非お試しください。今回紹介したサンプルは Java EE 6 を利用する上で最も基本的な構成と思います、上記の例を元に色々と修正を加え、DI/CDI や Bean Validation 等を加えて Java EE 6 の機能を是非色々と試してみてください。

最後に、私の環境で作成したNetBeans 6.8 のプロジェクトを下記から入手できるようにしました。
(※ Sun の mediacast.sun.com サイトにファイルをアップロードしていますので、
仮にこのサイトが閉鎖してしまった場合は申し訳ありませんがご了承ください。)

● NetBeans 6.8 のプロジェクト(ソース、設定ファイル等を含む)
● GlassFish v3 配備用 WARファイル

2010年2月26日 at 3:33 PM 2件のコメント

GlassFish データベースの設定

GlassFishはデータベースとの接続にデータベースベンダーが提供するJDBCドライバを使用します.

GlassFishにはインストール時デフォルトで Java DBが付属しており,あらかじめJava DBに対するJDBCリソースと接続プールの設定がされています.そして GlassFish の監視系の機能の一つである,「呼び出しフロー」のデータ保存先として使用されています.
ここでは,新たにMySQL 5.1との接続設定方法について紹介します.MySQLと接続するためには,MySQLのJDBCドライバを事前に入手しておいてください.
また以降の手順ではMySQLが既にインストールされていることを前提に説明します.

JDBCドライバに対するクラスパスを設定

dashost > asadmin get “cluster1-config.java-config.server-classpath”
cluster1-config.java-config.server-classpath =

dashost > asadmin set “cluster1-config.java-config.server-classpath=/sun/glassfish-v2.1.1/lib/mysql-connector-java-5.1.5-bin.jar”
cluster1-config.java-config.server-classpath = /sun/glassfish-v2.1.1/lib/mysql-connector-java-5.1.5-bin.jar

クラスパスの設定は,管理コンソールから左ペインの「設定」→「対象のコンフィグ(cluster1-config)」→「JVM 設定」を選択し右ペインの「サーバクラスパス」内に記載し設定できます.


次に JDBC の接続プールを作成します.

dashost > asadmin create-jdbc-connection-pool –datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlDataSource –restype=javax.sql.DataSource –property user=root:password=password:DatabaseName=MySQL:ServerName=localhost:port=3306:URL=”jdbc\:mysql\://localhost\:3306/test” MySQL-Pool
コマンド create-jdbc-connection-pool は正常に実行されました。


分散トランザクションが必要な場合,リソースタイプ,データソースにそれぞれ下記を使用してください.
javax.sql.XADataSource
com.mysql.jdbc.jdbc2.optional.MysqlXADataSource

管理コンソールからは下記の手順に従い設定してください.
まず、左ペインの「リソース」→「JDBC」→ 「接続プール」を選択し右ペインの「新規 …」ボタンを押下します.

次に,「接続プール名」,「リソースタイプ」,「データベースベンダー」を選択し「次へ」ボタンを押下します.

最後に,JDBC の各種詳細な設定項目を選択/入力し「完了」ボタンを押下します.






JDBCドライバ等の設定項目一覧が数多くリストされますが,ここでは最低限下記の項目のみ編集して設定を完了します.

名前
user root
password password
DatabaseName MySQL
ServerName localhost
port 3306
URL jdbc:mysql://localhost:3306/test


「完了」ボタンを押下すると下記の画面が表示されます.

ここで、作成した JDBC 接続プールが有効か否か疎通確認を行います.

成功時:

dashost > asadmin ping-connection-pool MySQL-Pool
コマンド ping-connection-pool は正常に実行されました。


失敗時:

dashost > asadmin ping-connection-pool MySQL-Pool
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
CLI137 コマンド ping-connection-pool は失敗しました。


また,管理コンソールから左ペインの「リソース」→「 JDBC」→「 接続プール」より対象の接続プールを選択し「Ping」ボタンを押下し確認できます.
成功時:

失敗時:

次に、作成した JDBC 接続プールに対して,リソース設定を行います.
アプリケーションはここで設定する JNDI 名を利用して DB にアクセスできるようになります.

dashost > asadmin create-jdbc-resource –connectionpoolid MySQL-Pool jdbc/mysql
コマンド create-jdbc-resource は正常に実行されました。


管理コンソールからは下記の手順に従い設定してください.
まず、左ペインの「リソース」→「JDBC」→ 「 JDBCリソース」を選択し右ペインより「新規 …」ボタンを押下します.


続いて,「JNDI 名」,「プール名」,有効状態のチェックをつけ「利用可能なターゲット」に対象のクラスタ(cluster1)を追加して「了解」ボタンを押下します.


「了解」ボタンを押下すると下記の画面が表示され JDBC リソースの設定は完了します.以降アプリケーションはここで設定した “jdbc/mysql” を利用して DB
に対して接続ができるようになります.

DBの設定情報の取得
ここで,DB の設定可能な項目の一覧をリストしてみます.asadmin の get コマンドを実行して確認ができます.各設定項目は asadmin set コマンドで設定変更を更新できますので必要に応じて設定変更を行ってください.

dashost > asadmin get “domain.resources.jdbc-connection-pool.MySQL-Pool.*”
domain.resources.jdbc-connection-pool.MySQL-Pool.allow-non-component-callers = false
domain.resources.jdbc-connection-pool.MySQL-Pool.associate-with-thread = false
domain.resources.jdbc-connection-pool.MySQL-Pool.connection-creation-retry-attempts = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.connection-creation-retry-interval-in-seconds = 10
domain.resources.jdbc-connection-pool.MySQL-Pool.connection-leak-reclaim = false
domain.resources.jdbc-connection-pool.MySQL-Pool.connection-leak-timeout-in-seconds = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.connection-validation-method = auto-commit
domain.resources.jdbc-connection-pool.MySQL-Pool.datasource-classname = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
domain.resources.jdbc-connection-pool.MySQL-Pool.description =
domain.resources.jdbc-connection-pool.MySQL-Pool.fail-all-connections = false
domain.resources.jdbc-connection-pool.MySQL-Pool.idle-timeout-in-seconds = 300
domain.resources.jdbc-connection-pool.MySQL-Pool.is-connection-validation-required = false
domain.resources.jdbc-connection-pool.MySQL-Pool.is-isolation-level-guaranteed = false
domain.resources.jdbc-connection-pool.MySQL-Pool.lazy-connection-association = false
domain.resources.jdbc-connection-pool.MySQL-Pool.lazy-connection-enlistment = false
domain.resources.jdbc-connection-pool.MySQL-Pool.match-connections = false
domain.resources.jdbc-connection-pool.MySQL-Pool.max-connection-usage-count = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.max-pool-size = 32
domain.resources.jdbc-connection-pool.MySQL-Pool.max-wait-time-in-millis = 60000
domain.resources.jdbc-connection-pool.MySQL-Pool.name = MySQL-Pool
domain.resources.jdbc-connection-pool.MySQL-Pool.non-transactional-connections = false
domain.resources.jdbc-connection-pool.MySQL-Pool.pool-resize-quantity = 2
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AllowLoadLocalInfile = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AllowMultiQueries = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AllowNanAndInf = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AllowUrlInLocalInfile = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AlwaysSendSetIsolation = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AutoClosePStmtStreams = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AutoDeserialize = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AutoGenerateTestcaseScript = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AutoReconnectForPools = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.AutoSlowLog = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.BlobSendChunkSize = 1048576
domain.resources.jdbc-connection-pool.MySQL-Pool.property.BlobsAreStrings = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CacheCallableStatements = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CacheCallableStmts = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CachePrepStmts = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CachePreparedStatements = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CacheResultSetMetadata = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CacheServerConfiguration = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CallableStatementCacheSize = 100
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CallableStmtCacheSize = 100
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CapitalizeTypeNames = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ClientInfoProvider = com.mysql.jdbc.JDBC4CommentClientInfoProvider
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ClobberStreamingResults = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ConnectTimeout = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ContinueBatchOnError = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.CreateDatabaseIfNotExist = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DatabaseName = MySQL
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DefaultFetchSize = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DontTrackOpenResources = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DumpMetadataOnColumnNotFound = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DumpQueriesOnException = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.DynamicCalendars = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ElideSetAutoCommits = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.EmptyStringsConvertToZero = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.EmulateLocators = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.EmulateUnsupportedPstmts = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.EnablePacketDebug = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.EnableQueryTimeouts = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ExplainSlowQueries = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.FailOverReadOnly = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.FunctionsNeverReturnBlobs = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.GatherPerfMetrics = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.GatherPerformanceMetrics = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.GenerateSimpleParameterMetadata = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.HoldResultsOpenOverStatementClose = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.IgnoreNonTxTables = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.IncludeInnodbStatusInDeadlockExceptions = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.InitialTimeout = 2
domain.resources.jdbc-connection-pool.MySQL-Pool.property.InteractiveClient = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.IsInteractiveClient = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.JdbcCompliantTruncation = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.JdbcCompliantTruncationForReads = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LoadBalanceStrategy = random
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LocatorFetchBufferSize = 1048576
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LogSlowQueries = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LogXaCommands = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Logger = com.mysql.jdbc.log.StandardLogger
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LoggerClassName = com.mysql.jdbc.log.StandardLogger
domain.resources.jdbc-connection-pool.MySQL-Pool.property.LoginTimeout = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.MaintainTimeStats = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.MaxQuerySizeToLog = 2048
domain.resources.jdbc-connection-pool.MySQL-Pool.property.MaxReconnects = 3
domain.resources.jdbc-connection-pool.MySQL-Pool.property.MaxRows = -1
domain.resources.jdbc-connection-pool.MySQL-Pool.property.MetadataCacheSize = 50
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NetTimeoutForStreamingResults = 600
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NoAccessToProcedureBodies = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NoDatetimeStringSync = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NoTimezoneConversionForTimeType = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NullCatalogMeansCurrent = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.NullNamePatternMatchesAll = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.OverrideSupportsIntegrityEnhancementFacility = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PacketDebugBufferSize = 20
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PadCharsWithSpace = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Paranoid = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Password = password
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Pedantic = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PinGlobalTxToPhysicalConnection = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PopulateInsertRowWithDefaultValues = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Port = 3306
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PortNumber = 3306
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PrepStmtCacheSize = 25
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PrepStmtCacheSqlLimit = 256
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PreparedStatementCacheSize = 25
domain.resources.jdbc-connection-pool.MySQL-Pool.property.PreparedStatementCacheSqlLimit = 256
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ProcessEscapeCodesForPrepStmts = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ProfileSQL = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ProfileSql = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.QueriesBeforeRetryMaster = 50
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ReconnectAtTxEnd = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RelaxAutoCommit = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ReportMetricsIntervalMillis = 30000
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RequireSSL = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ResultSetSizeThreshold = 100
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RewriteBatchedStatements = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RollbackOnPooledClose = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RoundRobinLoadBalance = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.RunningCTS13 = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SecondsBeforeRetryMaster = 30
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ServerName = localhost
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SlowQueryThresholdMillis = 2000
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SlowQueryThresholdNanos = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SocketFactory = com.mysql.jdbc.StandardSocketFactory
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SocketFactoryClassName = com.mysql.jdbc.StandardSocketFactory
domain.resources.jdbc-connection-pool.MySQL-Pool.property.SocketTimeout = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.StrictFloatingPoint = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.StrictUpdates = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TcpKeepAlive = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TcpNoDelay = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TcpRcvBuf = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TcpSndBuf = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TcpTrafficClass = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TinyInt1isBit = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TraceProtocol = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TransformedBitIsBoolean = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.TreatUtilDateAsTimestamp = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.URL = jdbc:mysql://:3306/
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UltraDevHack = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.Url = jdbc:mysql://localhost:3306/test
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseBlobToStoreUTF8OutsideBMP = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseCompression = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseCursorFetch = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseDirectRowUnpack = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseDynamicCharsetInfo = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseFastDateParsing = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseFastIntParsing = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseGmtMillisForDatetimes = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseHostsInPrivileges = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseInformationSchema = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseJDBCCompliantTimezoneShift = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseJvmCharsetConverters = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseLocalSessionState = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseNanosForElapsedTime = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseOldAliasMetadataBehavior = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseOldUTF8Behavior = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseOnlyServerErrorMessages = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseReadAheadInput = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseSSL = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseSSPSCompatibleTimezoneShift = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseServerPrepStmts = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseServerPreparedStmts = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseSqlStateCodes = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseStreamLengthsInPrepStmts = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseTimezone = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseUltraDevWorkAround = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseUnbufferedInput = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseUnicode = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.UseUsageAdvisor = false
domain.resources.jdbc-connection-pool.MySQL-Pool.property.User = root
domain.resources.jdbc-connection-pool.MySQL-Pool.property.YearIsDateType = true
domain.resources.jdbc-connection-pool.MySQL-Pool.property.ZeroDateTimeBehavior = exception
domain.resources.jdbc-connection-pool.MySQL-Pool.res-type = javax.sql.DataSource
domain.resources.jdbc-connection-pool.MySQL-Pool.statement-timeout-in-seconds = -1
domain.resources.jdbc-connection-pool.MySQL-Pool.steady-pool-size = 8
domain.resources.jdbc-connection-pool.MySQL-Pool.transaction-isolation-level =
domain.resources.jdbc-connection-pool.MySQL-Pool.validate-atmost-once-period-in-seconds = 0
domain.resources.jdbc-connection-pool.MySQL-Pool.validation-table-name =
domain.resources.jdbc-connection-pool.MySQL-Pool.wrap-jdbc-objects = false


コネックションプールのモニタリング
最後に、JDBC の接続プールに対してモニタリングの設定を行う方法を紹介します.モニタリングを有効にするために下記の手順に従い設定を行い,確認してください.

dashost > asadmin list “*monitor*”
server.monitoring-service
server.monitoring-service.module-monitoring-levels
dashost > asadmin set “server.monitoring-service.module-monitoring-levels.jdbc-connection-pool=HIGH”
server.monitoring-service.module-monitoring-levels.jdbc-connection-pool = HIGH
dashost > asadmin get “server.monitoring-service.module-monitoring-levels.*”
server.monitoring-service.module-monitoring-levels.connector-connection-pool = OFF
server.monitoring-service.module-monitoring-levels.connector-service = OFF
server.monitoring-service.module-monitoring-levels.ejb-container = OFF
server.monitoring-service.module-monitoring-levels.http-service = OFF
server.monitoring-service.module-monitoring-levels.jdbc-connection-pool = HIGH
server.monitoring-service.module-monitoring-levels.jms-service = OFF
server.monitoring-service.module-monitoring-levels.jvm = OFF
server.monitoring-service.module-monitoring-levels.orb = OFF
server.monitoring-service.module-monitoring-levels.thread-pool = OFF
server.monitoring-service.module-monitoring-levels.transaction-service = OFF
server.monitoring-service.module-monitoring-levels.web-container = OFF
dashost > asadmin list –monitor=true “*MySQL*”
server.resources.MySQL-Pool
dashost > asadmin get –monitor=true “server.resources.MySQL-Pool.*”

2010年2月8日 at 12:21 PM コメントする

GlassFish SSLの設定(クライアント認証)

GlassFish のドメイン管理サーバ上でHTTP リスナーの設定をクライアント認証対応に変更

dashost > asadmin set “cluster1-config.http-service.http-listener.http-listener-2.ssl.client-auth-enabled = true”

クライアント証明書の秘密鍵を作成

ca-admin > openssl genrsa -des3 -out /tmp/client-private-key 2048
Generating RSA private key, 2048 bit long modulus
……….+++
………………………………….+++
e is 65537 (0×10001)
Enter pass phrase for /tmp/client-private-key:
Verifying – Enter pass phrase for /tmp/client-private-key:


クライアント証明書用のCSRを作成

下記の例では便宜上,認証局(CA)上で CSR を生成していますが,CSRの生成はどの環境で構築しても問題ありません.

ca-admin > openssl req -new -days 365 -key /tmp/client-private-key -out /tmp/clientcsr.pem
Enter pass phrase for /tmp/client-private-key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Setagaya
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sun Microsystems
Organizational Unit Name (eg, section) []:Software Practice
Common Name (eg, YOUR name) []:Tarou Yamada
Email Address []:Tarou.Yamada@Sun.COM

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:


認証局(CA)でクライアント証明書を署名

クライアント証明書のCSRを認証局(CA)で署名します。

ca-admin > openssl ca -config ./openssl-client.cnf -in /tmp/clientcsr.pem -out /tmp/signed-clientcert.pem
Using configuration from ./openssl-client.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signatureSignature ok
Certificate Details:
Serial Number:
cd:ea:db:f4:c8:e3:93:92
Validity
Not Before: Dec  4 08:27:14 2009 GMT
Not After : Dec  4 08:27:14 2010 GMT
(省略)


署名されたクライアント証明書をGlassFishのキーストアにインポートするため,X.509形式に変更

ca-admin > openssl x509 -in /tmp/signed-clientcert.pem -out /tmp/signed-clientcert.x509


GlassFishのキーストアに対してクライアント証明書をインポート

dashost > keytool -import -alias yamada -file /tmp/signed-clientcert.x509
キーストアのパスワードを入力してください:[changeit]
新規パスワードを再入力してください:[changeit]
所有者: EMAILADDRESS=Tarou.Yamada@Sun.COM, CN=Tarou Yamada, OU=Software Practice, O=Sun Microsystems, ST=Tokyo, C=JP
発行者: EMAILADDRESS=caadmin@Sun.COM, CN=ca-server.sun.com, OU=Software Practice, O=Sun Microsystems, ST=Tokyo, C=JP
シリアル番号: cdeadbf4c8e39392
有効期間の開始日: Fri Dec 04 17:27:14 JST 2009 終了日: Sat Dec 04 17:27:14 JST 2010
証明書のフィンガープリント:
MD5:  59:06:3C:95:79:5D:31:D7:A3:92:0E:AA:A2:23:73:6D
SHA1: 26:00:30:F1:15:DB:20:D4:8E:AF:99:AB:96:13:CB:17:DA:E5:71:15
署名アルゴリズム名: SHA1withRSA
バージョン: 3
(省略)
この証明書を信頼しますか? [no]:  yes
証明書がキーストアに追加されました。


クライアント証明書をブラウザにインポートするためPKCS12形式に変換

ca-admin > openssl pkcs12 -export -in /tmp/signed-clientcert.pem -inkey /tmp/client-private-key -certfile ./demoCA/cacert.pem -out /tmp/clientcert.p12
Enter pass phrase for /tmp/client-private-key:
Enter Export Password:
Verifying – Enter Export Password:
ca-admin > ls -l /tmp/clientcert.p12
-rw-r–r–   1 root     root        3525 12月  4日  17:29 /tmp/clientcert.p12


最後にブラウザにPKCS12形式のクライアント証明書をインポートします.

上記で設定は完了です,ブラウザからアクセスしてみてください.

2010年2月8日 at 11:44 AM コメントする

GlassFish ドメイン管理サーバのバックアップとリストア

※ GlassFish のドメイン管理サーバのバックアップとリストアは
管理コンソールからは行えません.コマンドを使用してください.

ドメイン管理サーバが稼働するサーバが何らかの障害により起動できなくなった場合,ドメインの管理ができなくなります.ドメイン管理サーバが稼働していない状態でもサーバインスタンスを稼働させることはできますが,ドメイン管理サーバが壊れている状態ではアプリケーションの更新やリソースの設定変更等ができなくなります.このような場合、ドメイン管理サーバの設定をバックアップしておくことで,他のサーバをドメイン管理サーバの代替えとして利用することができます.バックアップはドメイン管理サーバ上で何らかの設定変更を行った際,その都度取得しておくことを推奨します.

バックアップを取得する前に,ドメイン管理サーバを停止してください.ドメイン管理サーバを停止しても提供しているサービスに影響は及びませんのでこの作業は本番稼働中に行っても問題ありません.

dashost > asadmin stop-domain clusterDomain
ドメイン clusterDomain が停止しました。


次にドメイン管理サーバのバックアップを行います.–domaindirには対象のドメインが含まれるディレクトリを指定します.

dashost > asadmin backup-domain –domaindir /export/home/appserv/domains clusterDomain
ドメインを正常にバックアップしました
説明: 1259776406949
バックアップファイル名: /export/home/appserv/domains/clusterDomain/backups/sjsas_backup_v00001.zip
バックアップを実行した日付と時刻: Thu Dec 03 02:53:26 JST 2009
ドメインディレクトリ: /export/home/appserv/domains
ドメインディレクトリ: /export/home/appserv/domains/clusterDomain
ドメイン名: clusterDomain
バックアップを実行したユーザーの名前: appserv


バックアップコマンドを実行すると,sjsas_backup_vXXXXX.zipと名付けられたバックアップファイルが作成されます.このファイルをドメイン管理サーバのバックアップ用のサーバにFTP等を利用してコピーしておきます.ここではドメイン管理サーバのバックアップ用のサーバとしてnodeagent1を使用します.本番環境ではノードエージェントとは別のマシン上に構築することを推奨します.

nodeagent1 > asadmin restore-domain –filename ./sjsas_backup_v00001.zip clusterDomain
ドメイン clusterDomain の /export/home/appserv/domains/clusterDomain への復元に成功しました
説明: 1259776406949
バックアップファイル名: /export/home/appserv/domains/clusterDomain/backups/sjsas_backup_v00001.zip
バックアップを実行した日付と時刻: Thu Dec 03 02:53:26 JST 2009
ドメインディレクトリ: /export/home/appserv/domains
ドメインディレクトリ: /export/home/appserv/domains/clusterDomain
ドメイン名: clusterDomain
バックアップを実行したユーザーの名前: appser


展開したファイル中よりドメイン管理サーバ名が記載されている箇所を手動で編集します.domains/clusterDomain/config /domain.xml中より修正する必要のある該当箇所を表示し,dashostからnodeagent1に変更します.

nodeagent1 > grep dashost domain.xml
<property name="client-hostname" value="dashost“/>
<jms-host admin-password="admin" admin-user-name="admin" host="dashost” name=”default_JMS_host” port=”5076″/>
<property name="client-hostname" value="dashost“/>
<jms-host admin-password="admin" admin-user-name="admin" host="dashost” name=”default_JMS_host” port=”${JMS_PROVIDER_PORT}”/>
<property name="client-hostname" value="dashost“/>
<jms-host admin-password="admin" admin-user-name="admin" host="dashost” name=”default_JMS_host” port=”${JMS_PROVIDER_PORT}”/>


新しい環境上で再度環境変数を設定した後,ドメインを起動します.

nodeagent1 > setenv AS_ADMIN_HOST nodeagent1.japan.sun.com
nodeagent1 > env |grep AS
AS_ADMIN_USER=clusterAdmin
AS_ADMIN_PASSWORDFILE=/export/home/appserv/.passwordfile
AS_ADMIN_HOST=nodeagent1.japan.sun.com
AS_ADMIN_PORT=5048
nodeagent1 > asadmin start-domain clusterDomain
ドメイン clusterDomain を起動しています。お待ちください。
デフォルトのログの場所は /export/home/appserv/domains/clusterDomain/logs/server.log です。
出力を /export/home/appserv/domains/clusterDomain/logs/server.log にリダイレクトしています
ドメイン clusterDomain が起動しました。
ドメイン [clusterDomain] はその設定で [Sun GlassFish Enterprise Server v2.1.1 ((v2.1 Patch06)(9.1_02 Patch12)) (build b31g-fcs)] を実行しています。ログは [/export/home/appserv/domains] にあります。
管理コンソールは [http://localhost:5048] で使用できます。
“asadmin” コマンドにも同じポート [5048] を使用します。
ユーザーの Web アプリケーションは次の URL で使用できます:
[http://localhost:5080 https://localhost:5081 ]。
次の web-contexts を使用できます:
[/web1 /__wstx-services ]。
標準の JMX クライアント (JConsole など) はドメイン管理のために JMXServiceURL:
[service:jmx:rmi:///jndi/rmi://nodeagent1.japan.sun.com:5086/jmxrmi]
に接続できます。
ドメインは少なくとも次のポートで接続を待機しています:
[5080 5081 5048 5037 5038 5039 5086 ]。
ドメインはアプリケーションサーバークラスタおよびその他のスタンドアロンインスタンスをサポートします。


上記で,ドメインのリストアは完了です.仮にドメイン管理サーバにアクセスするためにSSLを有効にしている場合にドメイン管理サーバのホスト名が変わる場合,サーバ証明書の更新も必要です.デフォルトでインストールされている自己署名サーバ証明書は変更前のドメイン管理サーバ名が記載されていますので更新の必要があります.
最後に,念のためノードエージェントが保持するドメイン管理サーバへの参照情報が更新されているか確認してください.全てのノードエージェントはagentディレクトリ中にconfigディレクトリが存在しています.このディレクトリ配下にdas.propertiesファイルが存在しており,ドメイン管理サーバへ接続するための接続情報などが記載されています.そこでファイルの内容を確認しdashostからnodeagent1に変更されていることを確認してください.仮に変更されていない場合は手動で変更してください.

nodeagent1 > pwd
/export/home/appserv/nodeagents/nodeagent1/agent/config
nodeagent1 > grep das.host das.properties
agent.das.host=nodeagent1
nodeagent2 > pwd
/export/home/appserv/nodeagents/nodeagent2/agent/config
nodeagent2 > grep das.host das.properties
agent.das.host=nodeagent1

2010年2月5日 at 4:35 PM コメントする

過去の投稿 新しい投稿


ご注意

このエントリは個人の見解であり、所属する会社の公式見解ではありません

カレンダー

2012年5月
« 4月    
 123456
78910111213
14151617181920
21222324252627
28293031  

カテゴリー

最近の投稿

Twitter

  • @boochnich センター棟で開催致しますので、センター棟(セミナーホール、402, 403, 405)までお越し頂けないでしょうか。 #jjug_ccc3 hours ago
  • JavaQne にご参加の皆様、今日はどうぞ宜しくお願いします。お土産も持ってまいりましたので是非楽しみにしてください!!#java #javaqne 3 hours ago

ブログ統計情報

  • 210,041 hits

RSSフィード


フォロー

Get every new post delivered to your Inbox.

現在1,361人フォロワーがいます。