https://blogs.oracle.com/arungupta/entry/jms_2_0_early_draft
Java Message Service (JSR 343) はJava EE 7の一部として改訂される作業が進んでいます。仕様の早期ドラフトは数週間前から利用可能になっており、オンラインのJavaDocも利用できます。その他の仕様(Java EE 7に含まれるJPA 2.1、JAX-RS 2.0、EJB 3.2、JavaServer Faces 2、CDI 1.1など)の早期ドラフトもリリースされています。仕様の一部を以下のリンクで詳細に説明してくれています。
- JAX-RS 2.0 Early Draft Explained - Java EE 7 Making Progress
https://blogs.oracle.com/arungupta/entry/jax_rs_2_0_early - JPA 2.1 Early Draft Explained - Java EE 7 making progress
http://blogs.oracle.com/arungupta/entry/jpa_2_1_early_draft - What's new in JSF 2.2?
http://jdevelopment.nl/jsf-22/
JMS 1.1は2003年12月にリリースされました。その当時からこれまでに、Javaの世界ではたくさんの変更がありました。annotation、generics、auto-closeable、dependency injection、その他たくさんの変化がありました。Java EEプラットフォーム自体が、それ以来広範囲に進化してきましたが、特にJava EE 6は"ゲームチェンジャー"と呼ぶべき存在です。いまなお開発されている複数のJMS実装があり、開発・デプロイの実績もたくさんあります。
そのすべてを維持しつつ、JMS2.0の主な目標は以下のとおりです。
- 開発を容易にする変更
- JMSと他のJava EE仕様間の関係の明確化
- 新しい必須APIを定義し、任意のJMSプロバイダがJava EEアプリケーションサーバと統合可能にする
- Java EE 7をサポートする拡張
- コミュニティより要求があったその他の機能強化
以下は既存のJMS APIを使ってメッセージを送信する場合のコード例です。
@Resource(lookup = "jms/connectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup="jms/inboundQueue")
Queue inboundQueue;
public void sendMessageOld (String payload) {
Connection connection = null;
try {
connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(inboundQueue);
TextMessage textMessage = session.createTextMessage(payload);
messageProducer.send(textMessage);
} catch (JMSException e) {
// do something
} finally {
try {
if (connection != null)
connection.close();
} catch (JMSException e2) {
// do something else
}
}
}
問題なく動作しますが、いくつか問題があります。- メッセージ送信のために複数の中間オブジェクト(
Connection、Session、MessageProducerなど)の作成が必要。こうしたオブジェクトには全て目的があるが、JMSアプリケーションが複雑になってしまう。また、お作法のような決まり切ったコードがたくさん必要になる。
createSessionの引数がわかりづらい。第1引数はセッションがトランザクショナルか否かを指定する。第2引数は、メッセージ受信のセッションの場合、メッセージのACKを返す方法について指定する。これらの2個の引数は独立していないので、第1引数をtrueとする場合、第2引数は無意味になり、第1引数のみが必要。
その他、このメソッドがEJBに存在する場合トランザクションはコンテナが管理する。Bean-Managed Transactionを使っている場合、トランザクションはJMS APIではなく、UserTransactionで開始し、コミットする。実のところ、EJBの仕様によると、このコードがトランザクション内にある場合、createSessionへの引数は完全に無視されてしまうが、いくつかの引数を指定してコントラクトを満足させる必要がある。Connectionは明示的にfinallyブロック内でクローズし、サーバ上のリソースを適切にリリースする必要がある。コードにはMessageProducerとSessionのクローズがないので、finallyブロックがネストした例外処理で見苦しくなっている。
@Resource(lookup = "jms/connectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup="jms/inboundQueue")
Queue inboundQueue;
public void sendMessageNew (String payload) {
try (JMSContext context = connectionFactory.createContext();){
context.send(inboundQueue,payload);
}
}
シンプルでしょう?大きな変更点は以下の通りです。
- 全ての定型コードがなくなっている。その代わりに、
ConnectionFactoryを作成し、そこからコンテキストを作成し、コンテキストのsendメソッドを呼び出している。 - 送り先(inboundQueue)を
MessageProducerではなく、sendメソッドで指定している。 Connectionは自動的にクローズされるので、tryブロックは自動的にクローズする。- 新しいメソッドはランタイム例外を送出するのでコードが非常にすっきりする。
@Inject
@JMSConnectionFactory("jms/connectionFactory")
private JMSContext context;
@Resource(mappedName = "jms/inboundQueue")
private Queue inboundQueue;
public void sendMessageNew(String payload) {
context.send(inboundQueue, payload);
}
ここで特記しておくと、Some clean ups to note here are ...- アプリケーションによる
JMSContextの初期化は不要 - 同一CDIスコープであれば、injectされた同一の
JMSContextを他の場所でも利用可能。
次はシンプルになったAPIでメッセージを同期受信する例です。
@Inject
@JMSConnectionFactory("jms/connectionFactory")
private JMSContext context;
@Resource(lookup="jms/inboundQueue")
Queue inboundQueue;
public String receiveMessageNew() {
JMSConsumer consumer = context.createConsumer(inboundQueue);
return consumer.receivePayload(String.class);
}
JMS 2.0早期ドラフトの11.4には、標準API(もしくは既存のAPI)とシンプル(もしくは新しい)APIを使ったサンプルがたくさんあります。JMS 2.0専門家グループが向いている方向を好ましく思っていますか?フィードバックをしたり、貢献したいと思いませんか?
JMS 2.0に関する最新の進捗は以下のリソースから追跡できます。
- JSR 343: JMS 2.0 - the next version of the JMS Specification
http://jms-spec.java.net/ - JSR 343 専門家グループメーリングリストのアーカイブ
http://java.net/projects/jms-spec/lists/jsr343-experts/archive - ユーザメーリングリストでのディスカッション
http://java.net/projects/jms-spec/lists/users/archive - JSR 343: JavaTM Message Service 2.0
http://jcp.org/en/jsr/detail?id=343
0 件のコメント:
コメントを投稿