SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

【デブサミ2014】セッションレポート (AD)

【デブサミ2014】14-D-6 レポート
「WebSocket」「JAX-RS」などJava EE 7の新機能・拡張機能を一挙紹介

  • このエントリーをはてなブックマークに追加

 「45分間で、Java EE 7に追加された45の新機能をすべて紹介する」と宣言して始まったこのセッション。スピーカーは、日本オラクル株式会社 Fusion Middleware事業統括本部 ビジネス推進本部 担当マネジャーの寺田佳央氏。途中「これはあまり使われていないから」と飛ばす場面はあったが、サン・マイクロシステムズ時代からWeb関連製品のエバンジェリストとして活躍する同氏である。Java EE 7で追加された新機能や拡張機能が、簡潔にわかりやすく解説された(スライドはこちらから参照可能)。

  • このエントリーをはてなブックマークに追加
日本オラクル Fusion Middleware事業統括本部 ビジネス推進本部 担当マネジャー 寺田佳央氏
日本オラクル Fusion Middleware事業統括本部 ビジネス推進本部 担当マネジャー 寺田佳央氏

開発者注目のWebSocket。JAX-RSには大きな変更点も

 Java EE 7は、下図のような構成になっている。図中の色分けの意味は次のとおりだ。

  • グリーン:ビューに関わるテクノロジー
  • オレンジ:Java EE全般に使えるテクノロジー
  • イエロー:ビジネスロジックやデータサービスにアクセスするテクノロジー
  • ブルーの線で囲まれたもの:Java EE 7で追加された新機能
Java EE 7に含まれる機能一覧
Java EE 7に含まれる機能一覧
WebSocket 1.0

 セッションで最初に取り上げられたのは、新機能「WebSocket」である。「日本を含む世界の開発者に『Java EE 7の中でどの機能を使いたいか』というアンケートをとったところ、多くの人がWebSocketと回答した」と寺田氏が語るように、開発者が最も注目している技術だ。WebSocketを使うと、TCPベースの双方向・全二重の通信を簡単に実現できるからである。

 例えば、WebSocketのアノテーションを使うと、サーバーが次のように簡単に実装できる。

@javax.websocket.server.ServerEndpoint("/chat")
public class ChatServer {

  @OnMessage
  public String chat(String name, Session session) {
    for (Session peer : session.getOpenSessions()) {
      peer.getBasicRemote().sendObject(message);
    }
  }
}

 また、「WebSocketには、セッションのライフサイクルに沿ったコールバックメソッドがある」と寺田氏は説明を続ける。クライアントとの接続をオープンあるいはクローズした、エラーが発生した場合の処理を、次のようにOnOpen、OnClose、OnErrorというアノテーションを実装するだけで追加できる。

@javax.websocket.OnOpen
public void open(Session s) { …… }

@javax.websocket.OnClose
public void close(CloseReason c) { …… }

@javax.websocket.OnError
public void error(Throwable t) { …… }

 さらに、「Java EE 7のWebSocketのライブラリは、クライアントの実装も可能となっている」と寺田氏。先述のサーバーの実装にはServerEndpointというアノテーションを付加したが、クライアント実装では、次のようにClientEndpointというアノテーションを付加する。それ以外はサーバーの実装とほぼ同じだ。

@javax.websocket.ClientEndpoint
public class MyClient {
  @javax.websocket.OnOpen
  public void open(Session session) { …… }
  // Lifecycle callbacks
}

 もちろん、クライアント側は、それに加えてサーバーへ接続しにいくコードも必要である。

ContainerProvider
  .getWebSocketContainer()
  .connectToServer(
    MyClient.class,
    URI.create("ws://localhost:8080/ws/hello"));

 ところで、Java EE 7のWebSocketが扱えるデータは、テキストとバイナリの2種類だけである。しかし、エンコーダ(encoder)とデコーダ(decoder)を実装すると、Javaオブジェクトをメッセージとして送受信可能になる。クライアント側に情報を送る場合は、Encoder.Textを使う。これで、JavaオブジェクトからJSONなどの送信用データを生成できる。逆に、受信したデータをJavaオブジェクトへ変換するには、Decoder.Textを使う。

 「このように、WebSocketを使用した実装はとても簡単。しかも標準のテクノロジーなので、GlassFishやWildFly 8など、Java EE 7に対応したアプリケーションサーバーであれば同じコードでどこでも動かすことができる。便利に使ってほしい」(寺田氏)

JAX-RS 2.0

 次に寺田氏が取り上げたのは、Java EE 7で大きな変更が加わったJAX-RSである。バージョン2.0になり、スタンドアロンのアプリケーション上でもJAX-RSクライアントを作れるようになった。JAX-RSクライアントは、次のように短縮して書くことができる。

Response response = ClientBuilder.newClient()
  .target("http://www.foo.com/book")
  .request(MediaType.TEXT_PLAIN)
  .get();

 なお、上記の実装では、レスポンスをResponseオブジェクトとして受け取る。ResponseオブジェクトからStringオブジェクトなどに変換するのが面倒なときには、次のように、getメソッドの引数にレスポンスの型を指定して受け取ることもできる。

String body = ClientBuilder.newClient()
  .target("http://www.foo.com/book")
  .request()
  .get(String.class);

 JAX-RS 2.0では「非同期クライアント」という機能も追加された。asyncという新メソッドにより、非同期でリクエストし、その結果を非同期で受けることができる。そのメリットについて寺田氏は、「レスポンスに時間のかかる通信を行っている裏側で、別の処理を実行したいときに使える。また、サーバー側でもサスペンドとレジュームで非同期の機能を作ることができる」と説明。さらに「これにLambda式を使えば、今までより短いコードで書けるようになる」(寺田氏)。Lambda式とは、Java EE 7で追加されたExpression Language(式言語)の拡張機能である(後述)。

 そのほか、JAX-RSについては、リクエスト/レスポンスのヘッダとメッセージボディに対するインターセプタ(フィルタ)が紹介された。これを使うと、例えば「If-Modified-Sinceで.getLastModifiedを指定して送り出すと、最新の情報だけを取得する」という実装が容易にできるという。ヘッダ用のインターセプタはクライアント実装用、サーバー実装用のインターフェイスが定義されている。メッセージボディ用のインターセプタは「エンティティインターセプタ」といい、Read/Write処理を実装するためのインターフェイスが定義されている。

追加されたConcurrencyで新規スレッドの生成などが可能に

 セッションは進み、Java EE 7の目玉であるWebSocketとJAX-RSのほかにも、新機能や拡張機能が続々と紹介された。

JSON-P 1.0

 「JSON-P」は、Java EE 7になって加えられたJava EE新機能の1つである。Json.createObjectBuilderにより、JSONオブジェクトが生成可能になった。また、JSONオブジェクトを解析するためにJsonParserも提供されているが、これは「まだ低レベルなので、次のバージョンまで使用は待ったほうがよい」(寺田氏)とのことだ。

JSF 2.2

 JSF(JavaServer Faces)はバージョン2.2になり、さまざまな機能が加わった。大きなところでは、HTML5に対応したこと。これにより、既存のHTMLにJSFの要素を追加するだけで、JSFのコードとして認識されるようになった。「パススルー」という機能も、HTML5との親和性を高めている。パススルーを利用すると、HTML5で追加されたHTMLタグや属性に対し、対応するJSFコンポーネントがなくてもフレームワーク内で扱えるように、(その名のとおり)データを“素通し”できる。これにより、HTML5で追加されたHTMLタグや属性、さらにはユーザー独自定義のデータ属性を柔軟に扱うことが可能になった。

 そのほか、JSFについては、画面と画面遷移、バックエンド処理をモジュール化できる「Facesフロー」や、同一フローの中だけで有効な値を参照・取得できるための「フロースコープの定義」と「リソースライブラリの契約」といった新機能を紹介。Servlet 3.0で追加されたAPIにより、ファイルのアップロードも標準で扱えるようになったことも説明された。

Expression LanguageのLambda式

 Expression Language(式言語)では、Lambda式を扱えるようになったことが新しい。Lambda式は、「コレクションの要素を1つずつ取り出して操作する」といった処理を記述するのに便利である。ただし、「ビューの部分にロジックが入り込むので、多用しすぎるとコードの可読性が悪くなる」(寺田氏)ので注意してほしいとのことだ。

Servlet 3.1

 Servlet 3.1では、ノンブロッキングI/O(NIO)用のメソッドとインターフェイスが追加された。追加されたメソッドはServletInputStream.setReadListener()や、ServletOutputStream.setWriteListener()など。追加されたインターフェイスは、ReadListenerとWriteListenerである。

 また、セキュリティ面も改善された。一つはFixation Attackからの防御である。「ログイン後にセッションIDを変更することで、セッションハイジャックを防御できる」と寺田氏。そのために、changeSessionIdというメソッドが追加された。

 もう一つが<deny-uncovered-http-methods>が追加されたこと。これにより<http-method>で指定されていないメソッドは一切、接続できなくなった。

CDI 1.1

 寺田氏いわく、「CDI(Contexts and Dependency Injection)は以前ほど大きな変更はないが、標準で利用可能になった」 ただし、デフォルトのannotatedではCDIのアノテーションが付加したものしかインジェクトできない。Java EE 6のときと同じように、すべてのものを対象にしたい場合は「all」という属性をbean-discovery-modeで指定する。CDI以外のDIコンテナを使いたい場合は、noneを指定すると、CDI自体を無効化することも可能。またall指定時に、インジェクション対象から除外したいときに@Vetoedアノテーションを使う。「クラス、パッケージ単位で指定ができる」(寺田氏)。

Bean Validation 1.1

 Bean Validationの変更点は「メソッド引数、メソッドの返り値に対するバリデーションも実装できるようになったことぐらい」(寺田氏)。また、Interceptorも「それほど大きな変更はない」と前置きした上で、コンストラクタに対するインターセプタが可能になったこと、@Priorityアノテーションによる複数のインターセプタを実行したときに、優先順位を指定できるようになったことを変更点として紹介した。

Concurrency 1.0

 Concurrencyも、Java EE 7で追加された新機能である。ManagedExecutorServiceを使用すると、これまで禁止されてきたJava EE環境でのスレッド生成が可能で、並列処理用のデザインパターンも適用できる。さらに、「Java SE 8の新機能であるLambda式と組み合わせると、並列処理の実装を短く簡潔に書くことができる」と寺田氏。その例が次のコードである。

@Resource
ManagedExecutorService exec;

 public void foo(){
   exec.submit(() -> {doSomething();});
 }

 ManagedExecutorServiceの代わりにManagedScheduledExecutorServiceを使用すると、スケジューリング可能な並列処理が実装できる。例えば、「2秒後に有効化し、以降、3秒間隔で指定したタスクを実行する」という処理はscheduleAtFixedRate()メソッド、「2秒後に有効化し、以降、前タスクが完了するたび3秒後に指定したタスクを実行する」という処理はscheduleWithFixedDelay()メソッドで実行できる。「Java SEにも同等のメソッドがあるのでそのまま使うことができる」(寺田氏)

 そのほかにも、Concurrencyではプログラム上でコネクションプールが作れるManagedThreadFactory、Java SE 8と同様のDynamicProxyなどの機能が提供されている。

JTA 1.2

 JTA(Java Transaction API)では、@TransactionScopedアノテーションが追加され、トランザクションの中だけで有効な値を定義できるようになった。「普通のCDIにもトランザクション設定ができるのはもちろん、特定の例外が発生したときにロールバックする、しないという設定も明示できるようになる」(寺田氏)

JPA 2.1

 JPA(Java Persistence API)2.1では、開発時やテスト時に有効なDBスキーマを自動的に生成する機能が標準化されたほか、@Indexアノテーションにより、任意カラムのインデックス化が可能に。また、非同期のPersistenceContextが追加され、明示的にトランザクションをジョインするまでは同期しないということが可能になった。そして、「皆さん待望のストアドプロシージャが標準で入った」(寺田氏)

JMS 2.0

 JMS(Java Message Service)は、JMSContextの提供と、Java SE 7構文への対応により、送受信用の実装がかなり容易になった。特に送信用のコードは、以前のバージョンで記述した場合よりも、大幅に記述を削減できるという。また、従来アプリケーションサーバー上でしか行えなかったJMSのリソース設定が、プログラム上からも行えるようになっている。

デフォルトデータソース

 デフォルトデータソースについて、寺田氏は「開発環境では、ぜひデフォルトのリソースを使うことを推奨したい」と強調。デフォルトのリソースを使うと、開発者によるリソース設定を省略でき、リソース設定も簡単に統一できるからだという。Java EE 7からはデータベースだけでなく、コンカレンシーユーティリティ、JMS全てにデフォルトのリソース設定が用意されているため、「@Resource のアノテーション内で個別のJNDI名を指定しなくて済む」(寺田氏)。

 セッションの最後に、寺田氏から1つ告知があった。「5月下旬にJavaのお祭り*1の開催を予定している。非常に面白いイベントを企画しているので、ぜひ、そのあたりの日程を空けておいてほしい」 どんなイベントか楽しみである。

*1 後日、「Java Day Tokyo 2014」の開催が告知された(5月22日 東京・品川プリンスホテル)。

お問い合わせ

日本オラクル株式会社

〒107-0061 東京都港区北青山2-5-8 オラクル青山センター

TEL: 0120-155-096(Oracle Direct)

URL: http://www.oracle.com/jp/

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7680 2014/04/08 16:43

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング