Hiroyuki Wajima
H/W's Blogs about S/W
Profile
Hiroyuki Wajima
Sr. Technical Specialist
Sun Java Consulting
Sun Professional Services
アーカイブ
« 11月 2009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
     
       
今日
XML
Search

リンク
 

Today's Page Hits: 24

All | Java EE | Personal | SOA | Sun
20061225 2006年 12月 25日 月曜日
Java World : Final
Java World最終号を読みました。時代の流れとは言え寂しいですね。

posted by wajima 12月 25日 2006年, 06:00:00 午後 JST Permalink

20060926 2006年 9月 26日 火曜日
Comet and Grizzly, Glassfish
Comet=サーバからクライアント(Webブラウザ)にイベントドリブンでデータをpushする技術。Ajaxの周辺でHotです。

以下,アーキテクト必見の情報です。

posted by wajima 9月 26日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060902 2006年 9月 02日 土曜日
WSIT on Glassfish V2 b13 Promoted Build - Milestone 1
みなさんはWeb Services Interoperability Technologies (WSIT, a.k.a. Project Tango)をご存知でしょうか。これは,JavaプラットフォームとWindows Communication Foundation (WCF, a.k.a. Indigo)との間でのWebサービスの相互運用性を確立,検証するプロジェクトで,SOAでの課題であるプラットフォーム間の相互運用性の確保に重要な役割を果たします。

WSITには,JAX-WSとJAXBをベースとして,様々な追加機能が組み込まれています。
(概要については,Harold Carr's Blogや,Arun Guptaが一覧をまとめているJavaOne 2006での関連セッションを参照してください。JavaOneの資料はここからダウンロードできます。)

現在,WSITのページからバイナリをダウンロードして試すことが出来ます。前提となる環境は,Glassfish V2 b08以降,NetBeans 5.5 Beta 2です。インストール手順チュートリアルもありますのでお試しください。

私は,WSIT Milestone Release 1,Glassfish V2 Milestone 1Java EE 5 Tools Bundle (NetBeans 5.5 Beta 2対応に更新されている)の組み合わせで,NetBeansを使ったチュートリアルを試してみました。

なお,1箇所だけ不具合があったので回避策をメモしておきます。
WSITのライブラリを解凍し,
ant [ -Das.home= ] -f wsit-on-glassfish.xml install
のようにして,Glassfish V2 Milestone 1の環境にWSITをインストールすると,Glassfishが起動しなくなってしまいます。
これは,[glassfish_dir]/domains/domain1/config/domain.xmlの中で


<java-config classpath-prefix="${com.sun.aas.installRoot}/lib/jaxws-update.jar" classpath-prefix="${com.sun.aas.installRoot}/lib/webservices.jar${path.separator}${com.sun.aas.installRoot}/lib/webservices-tools.jar" ...>


のように,同じ名前classpath-prefixの属性が2つ指定されてしまっているのが原因のようです。
テキストエディタでdomain.xmlを開いて,以下のように1つの値に結合してください。
${path.separator}を間に挟むのをお忘れなく。


<java-config classpath-prefix="${com.sun.aas.installRoot}/lib/jaxws-update.jar${path.separator}${com.sun.aas.installRoot}/lib/webservices.jar${path.separator}${com.sun.aas.installRoot}/lib/webservices-tools.jar" ...>

ここさえクリアすれば,あとはチュートリアルどおりに動きます。

posted by wajima 9月 02日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060729 2006年 7月 29日 土曜日
Java framework in the age of Java EE 5 (2) : Spring vs Seam (Java EE 5)
Java EE 5の時代のJavaフレームワークの展開についてもう1つのヒントになるのが,Rod Johnson率いるSpring陣営と,Hibernateの開発者であり,現在,JBossでSeamの開発に携わっているGavin Kingの間でやり取りされたディスカッションです。

Springは軽量コンテナの代名詞ともいえるフレームワークで,POJOベースの開発,Devendency Injection (Inversion of Control),AOPのサポートを特徴としています。JBoss Seamは,Java EE 5 (JSF, EJB 3.0)をベースに開発されたフレームワークです。

SpringのJava EE 5 (EJB 3.0)に対するスタンスは,SpringをWebLogicのJava EE 5実装のベースとして利用するためのオープンソースプロジェクトPitchforkFAQで明記されています。
Gavin Kingはこれに対する以下のような意見を,上記のディスカッションで述べています。
今後,各社からJava EE 5準拠のアプリケーションサーバが次々とリリースされると思われます。本当の意味で可搬性を確保する(ベンダーロックインを回避する)には,やはり標準仕様への準拠というのが有効なソリューションだと思います。

posted by wajima 7月 29日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060726 2006年 7月 26日 水曜日
Java framework in the age of Java EE 5 (1) : Struts and/or/vs Shale (JSF)
Java EE 5の時代のJavaフレームワークはどのように展開していくのでしょうか?その一つのヒントとなるのが,StrutsとShaleに関する最近の動きです。

StrutsとShaleについて簡単に解説すると,Strutsは言わずと知れたJSP/ServletベースのMVCフレームワーク(SunのCraig McClanahanが開発),ShaleはStrutsのサブ・プロジェクトとして発足したJSF(JavaServer Faces)ベースのフレームワーク(Strutsと同じくCraigが開発)です。ちなみにCraigはJSFのSpec Leadも務めています。

Shaleは最近,Strutsのサブ・プロジェクトから離脱して,Apache直下のプロジェクトに移りました。その理由として,
などが挙げられています。
(その際の経緯はこちらのスレッドに詳しいので興味のある方は読んでみてください。)

JSFはUIコンポーネントの利用,可搬性を重視したフレームワークで,開発生産性の向上を念頭において仕様策定されています。普通にコーディングしても良いのですが,Sun Java Studio Creator 2NetBeans等のツールを使えば,ほとんどコーディングすることなく開発できます。今後,Javaをアプリケーション開発プラットフォームとして幅広く展開させていこうと考えている方には,有力な選択肢になると思います。

posted by wajima 7月 26日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060722 2006年 7月 22日 土曜日
Java frameworks' name must start with "S" ?
ふと思ったのですが,Javaフレームワークには"S"で始まる名前のものが多いですね。
Struts, Shale, Seam, Spring, Seasar…これって偶然ですか?

posted by wajima 7月 22日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060708 2006年 7月 08日 土曜日
Ajax4jsf on Glassfish
前回までのエントリで,以下のような順序でリクエストが処理されるアプリケーションを構築できました。
  1. Webブラウザ
  2. JSF
  3. BPEL on OpenESB (JBI)
  4. Web Service (EJB 3.0)
  5. Stateless SessionBean (EJB 3.0)
  6. Entity Object (EJB 3.0)
  7. Java DB
ついでにといっては何ですが,WebブラウザとJSFの間でAjaxを使ってみたいと思います。

各種のAjaxライブラリ,ツール等が提供されているようですが,今回使うのはAjax4jsfです。
これは,JSFで構築したサーバサイドのプログラムに全く手を入れることなく,プレゼンテーション(JSP)の修正だけでAjaxを用いた非同期更新の仕組みを組み込むことが出来るスグレモノです。

ソースコードを見てもらうと分かり易いと思いますので,前回のエントリで作成したJSPにAjax4jsfを適用したものを見ていただきましょう。

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="a4j" uri="https://ajax4jsf.dev.java.net/ajax"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <f:view>
            <h1><h:outputText value="Java Server Faces" /></h1>
            <h:form>
                <h:inputText value="#{PricingManagedBean.productId}"/>
                <a4j:commandButton reRender="productId,productName,price" value="Submit" action="#{PricingManagedBean.findBooksData}"/>
          </h:form>
            <hr>
            <table border="1">
                <thead>
                    <tr>
                        <th>Product Id</th>
                        <th>Product Name</th>
                        <th>Price</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><h:outputText id="productId" value="#{PricingManagedBean.productId}"/></td>
                        <td><h:outputText id="productName" value="#{PricingManagedBean.productName}"/></td>
                        <td><h:outputText id="price" value="#{PricingManagedBean.price}"/></td>
                    </tr>
                </tbody>
            </table>

        </f:view>
    </body>
</html>


ソースコードで修正した箇所は,太字の部分だけです。
(*) 他には,web.xmlの修正や,ライブラリの修正が必要です。詳細についてはアーカイブ(本日現在の最新はv1.0rc1)に含まれるreadmeを参照してください。Glassfishで動かす場合には,さらにApache Commonsが必要なようです。私の場合,BeanUtils 1.7.0, Collections 3.2, Digester 1.7, Logging 1.1のjarをライブラリに追加すると動きました。

commandButtonをAjax4jsfが提供するcommandButtonに変更し,更新を反映するコンポーネントのidをreRender属性で指定するだけで,Ajaxアプリになってしまいます。つまり,
というふうに挙動が変わります。

他のAjaxライブラリやツールだと,サーバサイドの仕組みが独自になってしまい,既存のJ2EE/Java EEアプリケーションのアーキテクチャと整合性をとるのが難しくなってしまいそうなのですが,Ajax4jsfの場合は,JSFのモデルを崩すことなく,簡単にAjaxの要素を取り入れることが出来ますし,JavaScriptのコードを記述する必要も一切ありません。現在はまだコンポーネントの種類も少なく,思ったような処理を実現できない場合もあるようですが,今後の展開に期待したいと思います。

posted by wajima 7月 08日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060624 2006年 6月 24日 土曜日
Java EE 5 looking ahead to the future SOA

以前のエントリで,SOAにはレイヤ構成が重要だと書きました。例えば,現在は一般的なエンタープライズJavaの開発を行っていたとしても,将来的にSOAを実施する可能性があるようであれば,SOAのレイヤ構成を想定した開発を行っておけば,スムーズに移行できるようになります。


今回は,最近リリースされたNetBeans Enterprise Pack 5.5を使って,SOAのレイヤ構成に従ったJava EE 5開発を試して見ましょう。(チュートリアル風に手順を追っていきますので,Java EE 5やNetBeansを使われたことのない方も是非試してみてください。とても簡単です。)


以下のような雰囲気のアプリケーションを作りたいと思います。


【0. 前提条件】

NetBeans Enterprise Pack 5.5 EA版をダウンロードしてインストールしてください。それだけでO.K.です。


【1. Java DBの準備】

NetBeansにはデータベースとして,Java DBであるDerbyがバンドルされています。今回はこれを使います。


(1) Java DB起動

NetBeansのメニューで,[Tools]-[Java DB]-[Java DB Database]-[Start Java DB Server]を選択します。コンソール"Java DB Database Process"が開始され,以下のようなメッセージが表示されます。


サーバーは、ポート 1527 で接続を受け入れる準備ができました。
接続番号: 1。



(2) 接続の設定

左側のペインで[Runtime]タブを選択,[Databases]-[Drivers]-[Java DB(Net)]を右クリックして,[Connect Using ...]を選択すると,"New Database Connection"ダイアログが開きます。ここで,

を入力すると,あらかじめ構築済みのサンプルDBに接続できるようになります。


(3) テーブル,データの作成

接続先DBの[Tables]-[Execute Command]を選択すると,SQLコマンドを実行するコンソールが立ち上がります。ここで,3つのテーブルを作成します。


create table books_data(
product_id varchar(8) CONSTRAINT book_data_pk PRIMARY KEY,
product_name varchar(64),
price numeric(6,2)
);
insert into books_data values('SUNW-001', 'Java EE and .NET Interoperability',49.99);
insert into books_data values('SUNW-002', 'Core Security Patterns',           59.99);
insert into books_data values('SUNW-003', 'NetBeans IDE Field Guide',         44.99);
insert into books_data values('SUNW-004', 'Core JavaServer Faces',            54.99);
insert into books_data values('SUNW-005', 'Java? Studio Creator Field Guide', 39.99);


create table foo_price_list(
product_id varchar(8) CONSTRAINT foo_price_pk PRIMARY KEY,
price numeric(6,2)
);
insert into foo_price_list values('SUNW-001', 44.99);
insert into foo_price_list values('SUNW-002', 49.99);
insert into foo_price_list values('SUNW-003', 39.99);
insert into foo_price_list values('SUNW-004', 44.99);
insert into foo_price_list values('SUNW-005', 34.99);


create table bar_price_list(
product_id varchar(8) CONSTRAINT bar_price_pk PRIMARY KEY,
price numeric(6,2)
);
insert into bar_price_list values('SUNW-001', 39.99);
insert into bar_price_list values('SUNW-002', 54.99);
insert into bar_price_list values('SUNW-003', 34.99);
insert into bar_price_list values('SUNW-004', 49.99);
insert into bar_price_list values('SUNW-005', 29.99);


作成されたテーブルのアイコンを右クリックして[View Data]を選択して,データの一覧を確認してください。


【2. エンティティ,サービスの開発】

(1) プロジェクトの作成

[File]-[New Project]を選択すると,"New Project"ダイアログが起動します。カテゴリ"Enterprise"から"EJB Module"を選択して,プロジェクト"PricingService"を作成してください。


(2) エンティティの作成

プロジェクト"PricingService"を右クリック,[New]-[Entity Classes from Database]を選択します。
Data Sourceとして"jdbc/sample"を選択します。(もし存在しないようなら,[New Data Source]から作成しましょう。)
"Available Tables"から"BOOKS_DATA"をADDして[Next],Package: persistを入力します。
[Create Persistence Unit]を押して,Persistence Unitを作成します。今回は,テーブルをcreateする必要は無いので,Table Generation Strategy: Noneを選択して[OK]を押します。
[Finish]でエンティティクラスが作成されます。


以下のように,Java EE 5のアノテーションを使ったEntity Objectが生成されます。


@Entity
@Table(name = "BOOKS_DATA")
@NamedQueries(
{@NamedQuery(name = "BooksData.findByProductId", query = "SELECT b FROM BooksData b WHERE b.productId = :productId"), @NamedQuery(name = "BooksData.findByProductName", query = "SELECT b FROM BooksData b WHERE b.productName = :productName"), @NamedQuery(name = "BooksData.findByPrice", query = "SELECT b FROM BooksData b WHERE b.price = :price")})
public class BooksData implements Serializable {

    @Id
    @Column(name = "PRODUCT_ID", nullable = false)
    private String productId;

    @Column(name = "PRODUCT_NAME")
    private String productName;

    @Column(name = "PRICE")
    private BigDecimal price;
   
    /** Creates a new instance of BooksData */
    public BooksData() {
    }

    public BooksData(String productId) {
        this.productId = productId;
    }

    public String getProductId() {
        return this.productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getProductName() {
        return this.productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public BigDecimal getPrice() {
        return this.price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public int hashCode() {
        int hash = 0;
        hash += (this.productId != null ? this.productId.hashCode() : 0);
        return hash;
    }

    public boolean equals(Object object) {
        if (object == null || !this.getClass().equals(object.getClass())) {
            return false;
        }
        BooksData other = (BooksData)object;
        if (this.productId != other.productId && (this.productId == null || !this.productId.equals(other.productId))) return false;
        return true;
    }

    public String toString() {
        //TODO change toString() implementation to return a better display name
        return "" + this.productId;
    }
   
}



(3) サービスの生成

プロジェクト"PricingService"を右クリック,[New]-[Session Facade]を選択します。
"Available Entity Classes"から"BooksData"をADDして[NEXT],Package: serviceを入力します。
[Finish]でセッションファサードが生成されます。


こちらも,Java EE 5のアノテーションを使ったStateless SessionBeanです。


@Stateless
public class BooksDataFacade implements BooksDataFacadeLocal {

    @PersistenceContext
    private EntityManager em;
   
    /** Creates a new instance of BooksDataFacade */
    public BooksDataFacade() {
    }

    public void create(BooksData booksData) {
        em.persist(booksData);
    }

    public void edit(BooksData booksData) {
        em.merge(booksData);
    }

    public void destroy(BooksData booksData) {
        em.merge(booksData);
        em.remove(booksData);
    }

    public BooksData find(Object pk) {
        return (BooksData) em.find(BooksData.class, pk);
    }

    public List findAll() {
        return em.createQuery("select object(o) from persist.BooksData as o").getResultList();
    }
   
}



(4) 他のテーブルに対するサービスの作成

上記(1)-(3)の手順を,FOO_PRICE_LISTテーブル,BAR_PRICE_LISTテーブルに対しても同様に実施します。


(*)ここまで,ソースコードは一行も編集していません。


【3. プロセスの開発】

(1) ビジネスプロセスを実行するSession Beanの生成

プロジェクト"PricingService"を右クリックして,[New]-[Session Bean]を選択,以下のような値を入力します。


(2) Dependency Injectionの設定

クラスが生成されたら,ソースコードエディタ上で右クリック,[Enterprise Resources]-[Call Enterprise Bean]を選択します。BooksDataFacade, FooPriceListFacade, BarPriceFacadeをそれぞれ選択すると,Injectionされるメンバー変数が生成されますので,以下のようにアノテーションを追記します。


従来のDDに記述していたejb-refと,ソースコードに記述していたInitialContext#lookupをまとめて記述しているとイメージしてください。このように記述するだけで,メンバー変数にEJB参照が自動的に設定された状態でメソッドからアクセスできるようになります。


@EJB(name="ejb/BooksDataFacade", beanInterface=BooksDataFacadeLocal.class)
private BooksDataFacadeLocal booksDataFacade;

@EJB(name="ejb/FooPriceListFacade", beanInterface=FooPriceListFacadeLocal.class)
private FooPriceListFacadeLocal fooPriceListFacade;

@EJB(name="ejb/BarPriceListFacade", beanInterface=BarPriceListFacadeLocal.class)
private BarPriceListFacadeLocal barPriceListFacade;



(3) ビジネスメソッドの追加

ソースコードエディタ上で右クリック,[EJB Methods]-[Add Business Method]を選択します。

としてメソッドを生成します。


生成したメソッド内で実装を行います。ようやくJavaプログラミングの出番ですが,以前のJ2EEに比べると,とても素っ気無いプログラムです。


public BooksData findBookPrice(String productId) {
        
  // 3つのサービスにアクセスします。
  BooksData booksData = booksDataFacade.find(productId);
  FooPriceList fooPriceList = fooPriceListFacade.find(productId);
  BarPriceList barPriceList = barPriceListFacade.find(productId);

  // 戻り値用のインスタンスにBooksDataをコピー
  BooksData to_return = new BooksData();
  to_return.setProductId(booksData.getProductId());
  to_return.setProductName(booksData.getProductName());
  to_return.setPrice(booksData.getPrice());

  // Foo, Barのうち,安い方の価格を設定します。
  if(to_return.getPrice().doubleValue() > fooPriceList.getPrice().doubleValue())
    to_return.setPrice(fooPriceList.getPrice());
       
  if(to_return.getPrice().doubleValue() > barPriceList.getPrice().doubleValue())
    to_return.setPrice(barPriceList.getPrice());
        
  return to_return;
}



(4) Webサービス化

それでは,このプロセスをWebサービスとして呼び出せるようにしましょう。


プロジェクト"PricingService"を右クリック,[New]-[Web Service]を選択します。

を入力,選択,[Finish]でWebサービスが生成されます。


ただし,ただし,このWebサービスにはpublicメソッドが一切定義されていません。
"BooksPricingProcessWebServiceBean.java"のソースコードエディタ上で右クリック,
[Web Service]-[Add Operation]を選択します。

としてメソッドを生成します。そして,3(2)と同様の手順で,Dependency Injectionの設定した上で,BooksPricingProcessBean#findBookPriceに処理を委譲するように実装します。


(5) Webサービスによる呼び出しテスト

[PricingService]-[Web Services]-[BooksPricingProcessWebServiceBean]を右クリック,[Test Web Service]を選択すると,テスト用のWebページが開きます。


プロダクトID(例えば,SUNW-001)を入力,送信すると結果が表示されます。

 


posted by wajima 6月 24日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060520 2006年 5月 20日 土曜日
The Aquarium Japanese Edition

The Aquarium日本語版Java EE 5アプリケーションサーバのOpen Source開発プロジェクトGlassfishに関するブログ)が登場しています。本家と併せてどうぞ。


posted by wajima 5月 20日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]

20060511 2006年 5月 11日 木曜日
CORBA and SOA

昔かなりお世話になったCORBAサーバ製品VisiBrokerにSOA対応した新バージョンが出たというニュースを見て,懐かしさも含めてちょっと情報収集してしまいました。

CORBAに関しては,CORBA Component Modelという,EJBのプラットフォーム非依存版スーパーセットのような仕様が出た時点で個人的な興味としても離れてしまいましたし,おそらく商用版が出てないことからも分かるように業界的にもメインストリームから離れてしまったと思うのですが,IIOP, Naming Service, Transaction Service等についてはJava EEのベースとして活用されて現在も生き残っています。
OMGとしても,分散オブジェクトから,UML, MDA, BPMNといったモデリング分野に方向転換しているようです。

話を元に戻して,VisiBrokerのSOA対応というのは,Apache AxisをSOAPエンジンとして内蔵して,OMGのCORBA to WSDL/SOAP Interworkingという仕様に準拠してCORBAのIDL/IIOPとWSDL/SOAPのマッピングを行うような機能を提供していることを指しているようです。

ということは,EJBもRMI/IIOPですので,Session Facadeとして作られたサービス型の機能をWebサービスとして公開することも理論的には簡単にできそうです。ただし,CORBA to WSDL/SOAP Interworking仕様には制約があり,rpc/encodedとrpc/literalしかサポートしていません。(document/literalについては触れられていません)。SOAでプラットフォーム間の相互運用性を考慮するとdocumentスタイルがお奨めですので,一筋縄には行きませんね。


posted by wajima 5月 11日 2006年, 12:00:00 午前 JST Permalink 投稿されたコメント [0]