Posts Tagged ‘Java EE’

JSTL こういうこともできるのか

日曜日, 6 月 28th, 2009

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

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
    “http://www.w3.org/TR/html4/loose.dtd”>
<%@ taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>
<html>
    <head>
        <title>偶数? 奇数?</title>
    </head>
    <body>
        <h2>偶数? 奇数?</h2>
        <hr/>
        <c:set var=”miniValue” value=”2″/>
        <c:set var=”maxValue” value=”12″/>
        <c:forEach var=”i” begin=”2″ end=”${maxValue}”>
            <c:choose>
                <c:when test=”${i%2 == 0}”>
                    <c:out value=”${i} は偶数です。”/><br/>
                </c:when>
                <c:otherwise>
                    <c:out value=”${i} は奇数です。”/><br/>
                </c:otherwise>
            </c:choose>
        </c:forEach>
    </body>
    <hr/>
    <i>ビット演算は使えない\${i&1 == 0}</i>
</html>

2

ビット演算は使えないようです。

1

読むことのできない英語の本を買ってしまった。

パラパラとめくっていたらこんなことができるようなので早速試してみたしだいです。

Hatena タグ:

Singleton Session Beans の並行処理 その3

日曜日, 6 月 28th, 2009

この前のサンプルはちょっとあれでしたので Sun のチュートリアルとほぼ同じコードを載せておきます。

package counter.web;

import counter.ejb.CounterBean;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class Count {

    @EJB
    private CounterBean counterBean;
    private int hitCount;

    public Count() {
        this.hitCount = 0;
    }

    public int getHitCount() {
        hitCount = counterBean.getHits();
        return hitCount;
    }

    public void setHitCount(int newHits) {
        this.hitCount = newHits;
    }
}

——————————————————————————————————————————————

package counter.ejb;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.AccessTimeout;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;

@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) // デフォルトで適用されるので無くてもOK
@Singleton
@AccessTimeout(value = 20000)
public class CounterBean {

    private int hits = 1;

    @Lock(LockType.WRITE) // デフォルトで適用されるので無くてもOK
    public int getHits() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(CounterBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return hits++;
    }
}

—————————————————————————————————————————————

<?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”>
    <body>
        <h:outputText value=”This page has been accessed #{count.hitCount} time(s).”/>
    </body>
</html>

以上です。

CounterBean をこのように変更することも可能です。

@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
@Singleton
@AccessTimeout(value = 20000)
public class CounterBean {

    private int hits = 1;

    public synchronized int getHits() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(CounterBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return hits++;
    }
}

このような便利な機能を使わない場合は

@ConcurrencyManagement(ConcurrencyManagementType.CONCURRENCY_NOT_ALLOWED) とすればいいみたい。

う~ん・・・ いまいちこの機能のありがたさが解らない。

JEE6 が正式リリースされたら誰かが解りやすいサンプルと解説をしてくれるだろうからそれまで気長に待つとしよう(^^;

Hatena タグ:

Singleton Session Beans の並行処理 その2

金曜日, 6 月 26th, 2009

この前調べたのをもとにサンプルを組んで動かしてみました。

アノテーションの表記が若干上手くいかないところがあったがなんとか動きました。

何故かは調べてないのですが動いたから良しとします。(^^;

サンプルコードは下記のとおりです。

素人が組んだコードですので間違い等ございますでしょうがおおらかな心でご覧ください。

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.AccessTimeout;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;

/**
*
* @author Yucchi
*/
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Singleton
@AccessTimeout(value = 20000)
public class Question {

    @AccessTimeout(value = 5000)
    @Lock(LockType.READ)
    public String getshoulderMessage() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Question.class.getName()).log(Level.SEVERE, null, ex);
        }
        return “肩が痛くてたまらん(><)”;
    }

    @AccessTimeout(value = 19000)
    @Lock(LockType.WRITE)
    public String getWaistMessage() {
        try {
            Thread.sleep(15000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Question.class.getName()).log(Level.SEVERE, null, ex);
        }
        return “腰が痛くてたまらん(><)”;
    }
}

———————————————————————————————————————————————-

import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author Yucchi
*/
@WebServlet(urlPatterns = “/Shoulder”)
public class Shoulder extends HttpServlet {

    @EJB
    private Question question;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType(“text/html;charset=UTF-8″);
        PrintWriter out = response.getWriter();
        try {
            out.println(“<html>”);
            out.println(“<head>”);
            out.println(“<title>Servlet Shoulder</title>”);
            out.println(“</head>”);
            out.println(“<body>”);
            out.println(“Servlet Shoulder at ” + request.getContextPath());
            out.println(“<br>”);
            out.println(question.getshoulderMessage());
            out.println(“</body>”);
            out.println(“</html>”);

        } finally {
            out.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return “肩の調子はどうだい?”;
    }// </editor-fold>
}

————————————————————————————————————————————————-

import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
*
* @author Yucchi
*/
@WebServlet(urlPatterns = “/Waist”)
public class Waist extends HttpServlet {

    @EJB
    private Question question;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType(“text/html;charset=UTF-8″);
        PrintWriter out = response.getWriter();
        try {
            out.println(“<html>”);
            out.println(“<head>”);
            out.println(“<title>Servlet Waist</title>”);
            out.println(“</head>”);
            out.println(“<body>”);
            out.println(“Servlet Waist at ” + request.getContextPath());
            out.println(“<br>”);
            out.println(question.getWaistMessage());
            out.println(“</body>”);
            out.println(“</html>”);
        } finally {
            out.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return “腰の調子はどうだい?”;
    }// </editor-fold>
}

———————————————————————————————————————————————

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

<!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>
        <h1>JSP Page</h1>

        <a href=”/ConcurrencyManagementTest/Shoulder” target=”_blank”>肩の調子はどう?</a>
        <br>
        <br>
        <a href=”/ConcurrencyManagementTest/Waist” target=”_blank”>腰の調子はどう?</a>

    </body>
</html>

——————————————————————————————————————————————

以上お粗末なサンプルです。

実行結果はこのようになります。

JSP のリンクを「腰の調子はどう?」、「肩の調子はどう?」の順番で開きます。

getWaistMessage() が実行されてる間はロックされ getshoulderMessage() メソッドが実行待ちになります。

しかしタイムアウト設定が働き getshoulderMessage() メソッドは実行されずに終了してしまいます。

getWaistMessage() の処理が終わり Waist サーブレットの処理が完了します。

1

もし、興味があるようでしたら @Lock アノテーションの属性を変えてみたり、処理時間とタイムアウト設定を変更してグリグリしてみると楽しい結果がまっているでしょう。(たぶん)

私の場合、想像していた動作じゃなくてちょっと焦りました。(勉強不足です。)

やはり、実際に動かして確かめないと解らないことってありますね。

 

[ 追記 ]  ちょっとあまりにも不親切な内容だったので(^^; 

ちなみに @Lock(LockType.WRITE) アノテーションのついてるメソッドへのアクセスはただ一つだけ許されます。

よって「腰の調子はどう?」のリンクを複数開いた場合順番に一つずつ処理されていきます。

対して @Lock(LockType.READ) アノテーションのついたメソッドは同時に複数のアクセスを許します。

よって「肩の調子はどう?」のリンクを複数開いた場合順番待ちにならず同時に処理されます。

Hatena タグ:

JNDI ポータブル名

火曜日, 6 月 16th, 2009

ちょっと気になってたこと

java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>]

と言うように記述することにより GlassFish や JBoss でも問題ないようになるらしい。

Hatena タグ:

Singleton Session Beans の並行処理

日曜日, 6 月 14th, 2009

javax.ejb.ConcurrencyManagementType.CONTAINER あるいは javax.ejb.ConcurrencyManagementType.BEAN を使用すればいいようだ。

@ConcurrencyManagement(CONTAINER)
@Singleton
public class ExampleSingletonBean {
  private String state;

  @Lock(READ)
  public String getState() {
    return state;
  }

  @Lock(WRITE)
  public void setState(String newState) {
    state = newState;
  }
}

@ConcurrencyManagement(CONTAINER) アノテーションによってコンテナによって並行処理を管理する。

ちなみにデフォルトで @ConcurrencyManagement(CONTAINER) が設定されるようなのです。

これを利用することによって、@Lock(READ) @Lock(WRITE) アノテーションによって排他制御を可能とする。

 

タイムアウトの設定方法

@AccessTimeout アノテーションによって可能となります。

下記コードでは Singleton Session Bean のデフォルトタイムアウトの設定時間は 120000 ミリ秒となってます。

doTediousOperation メソッドのタイムアウト設定時間は Singleton Session Bean のデフォルトタイムアウト時間より優先され 360000 ミリ秒となります。

@Singleton
@AccessTimeout(value=120000)
public class StatusSingletonBean {
  private String status;

  @Lock(WRITE)
  public void setStatus(String new Status) {
    status = newStatus;
  }

  @Lock(WRITE)
  @AccessTimeout(value=360000)
  public void doTediousOperation() {
    ...
  }
}
ちなみに TimeUnit.SECONDS 定数を使えばこのように解りやすくなります。
@Singleton
@AccessTimeout(value=60, timeUnit=SECONDS)
public class StatusSingletonBean { ... }
 
@ConcurrencyManagement(BEAN) による並行処理は全てのビジネスメソッド及びタイムアウトメソッドの並行処理を可能とします。
ただし、それらは開発者によりすべてのクライアントへの同期化を保証する責任があります。
Java の並行処理技術を駆使して高レベルなプログラミング技術が必要とされるようです。
@ConcurrencyManagement(BEAN)
@Singleton
public class AnotherSingletonBean { ... }
 
Java EE 6 Tutorial の Singleton Session Bean の並行処理をざっと目を通してる最中ですがなかなか凝ってますね。
最後にこの内容は英語が駄目な素人が勝手に解釈したメモ書き程度のものですから詳しく知りたい方は本家のチュートリアルをご参照くださいませ。
Hatena タグ:
 

Singleton Session Bean Initialization

日曜日, 6 月 14th, 2009

The Java EE 6 Tutorial より Singleton Session Bean の初期化にはこんなのもありだ。

@Singleton
public class PrimaryBean { ... }

SecondaryBean depends on PrimaryBean:

@Singleton
@DependsOn("PrimaryBean")
public class SecondaryBean { ... }

これで EJB コンテナが SecondaryBean の前に PrimaryBean を初期化することを保証するらしい。

φ(..)メモメモ

Hatena タグ:

javax.ejb.Schedule その2

火曜日, 6 月 9th, 2009

昨日のつづきです。

@Schedule(dayOfMonth = “1″, hour = “7″, minute = “30″)
    public void hoge() {
    // …
}

とすると、毎月午前7 時 30 分に hoge() メソッドが実行される。

@Schedules({@Schedule(hour = “5″),@Schedule(hour = “15″, dayOfWeek = “Wed”)})
    public void hogehoge() {
    // …
}

は二つのタイマーを持つ。

一つは、毎日午前 5 時に、もう一つは毎週水曜日の午後 3 時に hogehoge() メソッドを実行させます。

@Schedule アノテーションによってカレンダーを基本にタイマーを設定しているようです。

これらの機能はデフォルトでサーバーがシャットダウンし、再起動しても実行されるようです。

オプションで無効にするには下記のように persistent = false を設定します。

@Schedule(minute = “*/15″, hour = “*”, persistent = false)
    public void hogehogehoge() {
    // …
}

これで 15 分毎に hogehogehoge() メソッドを実行します。

ただし、サーバーがダウンし、再起動した場合は実行されません。

ちなみに stateful beans ではこのタイマーサービスを使えない(使わない方がいい)ようです。

Hatena タグ:

javax.ejb.Schedule

月曜日, 6 月 8th, 2009

@Schedule の API ドキュメント見たけど Optional Element Summary の設定値のなかに * ってあるけど意味が解らない。

@Schedule(second=”*/3″, minute=”*”, hour=”*”, info=”@Schedule の * ってなんだ?”)

上記のコードの場合 3 秒ごとにスケジュールされていると思う。

info の項目はただの情報だとしても時間、分、秒の設定が良く解らない。

minute=”*” と hour=”*” は設定無しの無限大というところでしょうか?

ちなみに時間、分、秒のデフォルト設定値は 0 となってました。

second=”3″ じゃなくて何故 second=”*/3″ とするんだろう?

根本的に考え方を間違っているのだろうか?

 

追記

second=”*/3″ の*はワイルドカードと呼ばれるものらしい。

で、second=”30/10″ とすれば、30 , 40 , 50 秒と実行されるようだ。

つまり、 / の前がスタート時間で後ろがインターバル時間ってこと?かも(^^;

Hatena タグ:

startup/shutdown callbacks

月曜日, 6 月 8th, 2009

Java EE 6 良く解らないけど動かしてみました。

コードはこのようになってます。

1

2

3 

@Startup アノテーションによって @PostConstruct アノテーションの付加された startup() メソッドが Web アプリケーションを配備完了後にすぐに呼ばれるようだ。

配備取り消しの場合は @PreDestroy アノテーションの付加された shutdown() メソッドが呼ばれるみたい。

@Startup アノテーションがなければ @PostConstruct アノテーションの付加された startup() メソッドと @PreDestroy アノテーションの付加された shutdown() メソッドは呼ばれない。

とりあえず @Startup アノテーションによってこのように動作するようだ。

12

13

11

@Startup アノテーションによって Web アプリケーションの準備と後始末をすませようとしているような気がする。

Hatena タグ:

First Cup を試してみた

日曜日, 6 月 7th, 2009

Your First Cup: An Introduction to the Java EE Platform Chapter 3 を試してみました。

製品バージョン: NetBeans IDE 6.7 RC2 (Build 200906042131)
Java: 1.6.0_14; Java HotSpot(TM) 64-Bit Server VM 14.0-b16
システム: amd64 上で動作する Windows Vista バージョン 6.0; MS932; ja_JP (nb)
ユーザーディレクトリ: C:\Users\Yucchi\.netbeans\6.7rc2

上記の環境にて GlassFish V3 Preview にてさくさくっとチュートリアルの指示にしたがってあっさりとできてしまいました。

NetBeans 6.7 RC2 で GlassFish V3 Preview を使う方法はこちらにあります。

チュートリアルを進めていくと NetBeans 6.7 ではとりあえず Java EE 6 が試せますよってのが解る。

Java EE 6 対応の GlassFish V3 Preview を選択しても Java EE 6 のバージョンが選べなかったりします。

でも、Java EE 5 で Java EE 6 も対応してます。

細かいところでは GlassFish V3 Preview 側にライブラリがあるので NetBeans が親切に用意してくれるライブラリの中には不要なものがあります。

下図の二つのライブラリも必要ありません。

1

2

最初に JAX-RS RESTful web service を利用した Web アプリケーションを作ります。

作ったプログラムを動かすとデューク君の年齢が表示されます。

3

チュートリアルを進めていくとまた不要なものに出会います。

指示に従い不要なものは削除していきます。

また、Java EE 6 のバージョン仕様に従い各ファイルを編集しなくてはいけないようです。

NetBeans 6.7 がデフォルトで作成する Facelets のバージョンは 1.2 なので faces-config.xml をバージョン 2.0 の仕様に手動で編集しなければなりません。

web.xml ファイルにも必要のないエレメントがあるので編集、削除します。

Facelets Simple File にいたってはほぼ手動編集作業となります。

ちょっと面倒なことをしなければいけないけど Java EE 6 正式版がリリースされれば NetBeans が完全対応してくれるのに期待しましょう。

チュートリアルの指示にしたがってプログラムを完成させれば下図のように動作します。

12 

13

私のようなうっかり者は[ Back ] ボタンを押すとエラーを表示させてしまいます。

14

この原因はこのインポートを誤ったからです。orz

55

このチュートリアルを含んだドキュメントは英語なので詳しい内容はわかりませんが無いよりはいいですね。

久しぶりにサーバーサイドジャバに触れてみたって感じです。

もう、すっかり忘れてしまった(^^;

そう言えば、昔は「サーバーサイドジャバ」とか言って何やらカッコイイと思ったけど今では死語なんだろうか?

Hatena タグ: ,