Java EE 8でエンタープライズJava開発はどう変わるのか?--リンダ・デミケル氏が語る

Oracle Java & Developers編集部
2015-06-30 11:00:00
  • このエントリーをはてなブックマークに追加

2017年前半に正式リリースが予定されている「Java EE 8」では、どのような機能強化が行われ、それによってエンタープライズJava開発はどう変わるのか? スペック・リードのリンダ・デミケル氏が解説する。

米国オラクル Java EEスペック・リードのリンダ・デミケル氏
米国オラクル Java EEスペック・リードのリンダ・デミケル氏

 Java EEの最新版であるJava EE 7がリリースされたのは2013年7月のこと。それから2年が経過した現在、JCP(Java Community Process)では次期バージョンとなるJava EE 8のリリースに向けた作業が進められている。Java EE 8は2014年8月に「JSR 366」として正式に仕様策定がスタートし、最初の提案(JSR Review)は満場一致で承認された。果たしてJava EE 8ではどのような機能追加や拡張が検討されているのか? 米国オラクルで長年に渡ってJava EEの開発を牽引し、JSR 366のスペック・リードも務めるリンダ・デミケル氏による解説をお届けする。

※ 本記事は、日本オラクルが2015年4月に開催した「Java Day Tokyo 2015」におけるデミケル氏のセッション「Java EE 8 - direction and new features」、「CDI and EJB - Java EE Alignment and strategy」の内容を基に構成しています。

Java EE 8の3つの開発テーマ

 Java EE 8で取り組むべき課題については、Javaコミュニティからのフィードバックに加えて、4500人以上の開発者にアンケート調査を行い、機能別に優先順位が検証されたという。その結果、最も関心が高いのはJSON Binding(JSON-B)であることがわかり、次いでセキュリティの簡素化、そしてJCache、Security Interceptors、MVCと続いた。


※クリックすると拡大画像が見られます

 デミケル氏らは、この調査結果と業界の動向を踏まえて、Java EE 8の主要な開発テーマとして次の3つを据えた。

  • HTML5/Web層に対する機能強化
  • 開発容易性のさらなる向上とCDI(Contexts and Dependency Injection)の強化
  • クラウド・インフラとしての機能強化

 これらのテーマについて、具体的にどのような機能が検討されているのかを見ていこう。

HTML5/Web層に対する機能強化──JSONの拡張やHTTP/2のサポート

 まず「HTML5/Web層に対する機能強化」については、次のようなことが予定されている。

  • JSON Bindingのサポート
  • JSON Processingの強化
  • サーバ・サイド・イベントのサポート
  • アクション・ベースのMVCのサポート
  • HTTP/2のサポート

JSONサポートの強化

 JSONのサポートはJava EE 7においても主要なテーマの1つであったが、Java EE 8でも引き続き大幅な機能強化が行われる。特に大きな修正となるのは「JSON Binding(JSON-B)」のサポートだ。

 JSON-Bは、JavaオブジェクトとJSONオブジェクトのバインディングを実現するためのAPIであり、「JSR 367」として標準化が進められている。「XMLに対するJAXBのような位置付けのAPIであり、これを使えばJavaプログラム内で、より自然にJSONオブジェクトを取り扱えるようになります」とデミケル氏は語る。

【リスト1:JSON-Bを用いてJSONドキュメントを処理するコードの例】
@Entity public class Person { @Id String name; String gender; @ElementCollection Map<String,String> phones; …略…(ここにgetter/setterメソッドを定義) } Person duke = new Person(); duke.setName("Duke"); duke.setGender("M"); phones = new HashMap<String,String>(); phones.put("home", "650-123-4567"); phones.put("mobile", "650-234-5678"); duke.setPhones(phones); Marshaller marshaller = new JsonContext().createMarshaller().setPrettyPrinting(true); marshaller.marshal(duke, System.out); { "name":"Duke", "gender":"M", "phones":{ "home":"650-123-4567", "mobile":"650-234-5678"} }

 既存のJSONライブラリである「JSON Processing(JSON-P)」についても、いくつかの機能追加が検討されている。その1つが「JSON-Pointer」だ。JSON-Pointerは「RFC 6901」として標準化されている機能で、これによってJSONドキュメントに対する参照を表現することができる。JSON-Pointerを使ったコードの例は次のようになる。


※クリックすると拡大画像が見られます

 このコードでは、クラスJsonPointerがJSON-Pointerを表し、メソッドgetValueで指定位置の値を取得している。

 「JSON-Patch」も興味深い新機能の1つだ。JSON-Patchは「RFC 6902」として標準化されており、JSONドキュメントに対してパッチを当てるかたちで値の追加や削除、置換、コピー、移動などの編集が行える。パッチ・データは、実行する操作を表すopフィールドと、操作対象のパスを表すpathフィールドを使ったJSONドキュメントとして定義する。

【リスト2:JSON-Patchの使用例】
(1)パッチ用のJSONドキュメント
[ { "op":"replace", "path":"/0/phones/mobile", "value":"650-111-2222"}, { "op":"remove", "path":"/1"} ]
(2)パッチの適用対象となるドキュメント
[ { "name":"Duke", "gender":"M", "phones":{ "home":"650-123-4567", "mobile":"650-234-5678"}}, { "name":"Jane", "gender":"F", "phones":{ "mobile":"707-555-9999"}} ]
(3)(2)のドキュメントに(1)のパッチを適用した結果
[ { "name":"Duke", "gender":"M", "phones":{ "home":"650-123-4567", "mobile":"650-111-2222"}} ]

 これらのほかに、Java SE 8のラムダ式を利用したJSONクエリなども新機能として検討されているという。

サーバ・サイド・イベントの追加

 サーバ・サイド・イベントはHTML5で追加された新機能であり、サーバからクライアントに向けた、いわゆるプッシュ型の通信を可能にする。このイベントにより、サーバはクライアントからのリクエストを待つことなくデータを送り出し、そのことをクライアントに通知することが可能となる。

 デミケル氏は現在、このサーバ・サイド・イベントをどのように実現すべきかをJava ServletやWebSocket、JAX-RSなどのエキスパートらと検討しており、現時点ではJAX-RSが有望だと考えているという。JAX-RSでは、すでにHTTPを使ったストリーム通信がサポートされているほか、サーバ/クライアントともにAPIの変更が小規模で済みそうなこと、参照実装である「Jersey」がすでにサーバ・サイド・イベントをサポートしていることなどがその理由である。

 具体的なAPIについてはこれから議論していく段階だが、現時点では次のようなものが検討されている。

【リスト3:JAX-RSによるサーバ・サイド・イベントの実装例】
●JAX-RSのリソース・クラス
@Path("tickers") public class StockTicker { @Get @Produces("text/event-stream") public EventOutput getQuotes() { EventOutput eo = new EventOutput(); new StockThread(eo).start() return eo; } }
●JAX-RSのクラスStockThread
class StockThread extends Thread { private EventOutput eo; private AtomicBoolean ab = new AtomicBoolean(true); public StockThread(EventOutput eo) { this.eo = eo; } public void terminate() { ab.set(false); } @Override public void run() { while (ab.get()) { try { …略… eo.send(new StockQuote("...")); …略… } catch (IOException e) { …略… } } } }
●JAX-RSクライアント
WebTarget target = client.target("http://example.com/tickers"); EventSource eventSource = new EventSource(target) { @Override public void onEvent(InboundEvent inboundEvent) { StockQuote sq = inboundEvent.readData(StockQuote.class); …略… } }; eventSource.open();

アクション・ベースのMVC

 MVCは現在、フレームワーク側に用意されたコンポーネントがControllerの役割を担うコンポーネント・ベース方式が主流となっている。これに対して、アプリケーション側(開発者側)で独自にControllerを定義するアクション・ベースのMVC方式もある。前者の方式を取っているのがJSF(JavaServer Faces)であり、Struts 2やSpring MVCなどは後者の方式を採用している。

 Java EE 8では、JSFに加えて、このアクション・ベースのMVCも標準となる予定だ。アクション・ベースのMVCに関する仕様は「JSR 371」として標準化が始まっており、その実装にはJAX-RSを利用する。つまり、JAX-RSのメソッドがControllerの役割を担うわけである。アクション・ベースのMVCフレームワークの例は次のようになる。

【リスト4:アクション・ベースのMVCフレームワークの例】
●Model
@Named("greeting") @RequestScoped public class Greeting{ private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
●Controller
@Path("hello") public class HelloController { @Inject private Greeting greeting; @GET @Controller public String hello() { greeting.setMessage("Hello there!"); return "hello.jsp"; } }
●View
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Hello</title> </head> <body> <h1>${greeting.message}</h1> </body> </html>

HTTP/2のサポート

 HTTP/2は、2015年2月にW3C勧告となったHTTP/1.1の後継となる新しい通信仕様だ。通信の高速化や帯域の効率的な利用を追求した設計となっており、主な変更点として、通信の多重化や並列化のサポート、サーバ・プッシュ通信のサポート、バイナリ・フレームの採用、ヘッダの圧縮などが挙げられる。Java EE 8では、「Java Servlet 4.0」において、このHTTP/2の機能をサポートする予定である。