リリース間近!Java EE 7の気になるところ
やっとやっと待ちに待ったJava EE 7のリリースが近づいて来ましたね。
予定では5/13(日本だと14日?)にFinal Releaseのようです。
https://java.net/projects/javaee-spec/pages/Home#Java_EE_7_Schedule
リリースに備えて軽く自分の備忘録も兼ねて予習しておきます。
あんまり追っかけているわけではないので間違ってたらすみません。
各テクノロジーのバージョンはこんな感じ。
Java EE 7で新規で追加されるもの
テクノロジー | バージョン |
---|---|
Java API for JSON Processing (JSR-353) | 1.0 |
Java API for WebSocket (JSR-356) | 1.0 |
Batch Application for the Java Platform (JSR-352) | 1.0 |
Concurrency Utilities for Java EE (JSR-236) | 1.0 |
アップデートされるもの
テクノロジー | EE6バージョン | EE7バージョン |
---|---|---|
Enterprise JavaBeans (EJB) | 3.1 | 3.2 |
Servlet | 3.0 | 3.1 |
JavaServer Pages (JSP) | 2.2 | 2.3 |
Expression Language (EL) | 2.2 | 3.0 |
Java Messaging Service (JMS) | 1.1 | 2.0 |
Java Transaction API (JTA) | 1.1 | 1.2 |
JavaMail API | 1.4 | 1.5 |
Java Connector Architecture (JCA) | 1.6 | 1.7 |
Web Services | 1.3 | 1.4 |
Java API for XML-based Web Services (JAX-WS) | 2.2 | 2.2 |
Java API for RESTful Web Services (JAX-RS) | 1.1 | 2.0 |
Java Architecture for XML Binding (JAXB) | 2.2 | 2.2 |
Java EE Management | 1.1 | 1.1 |
Java Authorization Service Provider Contract for Containers (JACC) | 1.4 | 1.5 |
Java Authentication Service Provider Interface for Containers (JASPIC) | 1.0 | 1.1 |
JSP Debugging | 1.0 | 1.0 |
JavaServer Pages Standard Tag Library (JSTL) | 1.2 | 1.2 |
Web Services Metadata for the Java Platform | 2.1 | 2.1 |
JavaServer Faces (JSF) | 2.0 | 2.2 |
Common Annotations | 1.1 | 1.2 |
Java Persistence API (JPA) | 2.0 | 2.1 |
Bean Validation | 1.0 | 1.1 |
Managed Beans | 1.0 | 1.0 |
Interceptors | 1.1 | 1.2 |
Contexts and Dependency Injection for Java EE (CDI) | 1.0 | 1.1 |
Dependency Injection for Java | 1.0 | 1.0 |
あと削除ものとしてJAX-RPCのような既に使われないであろう仕様は
外されている感じです。
JCache (JSR-107)は残念ながらEE7には間に合わなかったようですね。
まだ標準化は難しいんでしょうか。
注目どころ
注目どころというよりは私が気になっているところをまとめます。
・WebSocket
WebSocketもEE7で導入になります。
これでリアルタイム系のWebアプリも増えてきたりするかもしれないですね。
アノテーションベースでサーバ実装がとても簡単のようです。
・Batch
やっぱり企業系だとバッチ処理系のニーズは多いんでしょうかね。
Springのバッチ機能を踏襲しているようなので
ファーストリリースにしては結構使いやすい感じに
落ち着いているのではないかと思っています。
・JTA
仕様の中に@Transactionalっていうアノテーションがあるようなのですが、
これってSessionBeanもういらないんじゃない的な
POJOにトランザクション指定できる機能なのでしょうか。
そうだとしたらアプリケーションがよりシンプルに
開発出来るようになるのではないかと思っています。
JSF2.0で一覧表示
JAX-RSでデータの一覧表示を作成してみましたが今度は同じ画面をJSFで作成してみます。
JSFはサーバサイドのメモリーを多く使用するため不特定多数ユーザが利用するサービスには不向きですが、クライアントサーバ型のアプリケーションのようにWEBアプリケーションを作成する事ができるので社内アプリケーションや利用者が限定されているアプリケーションを簡単に作成&メンテナンスするにはとても良いアーキテクチャです。JSFはバージョン2.0よりテンプレートにFaceletsが導入されビューがとても簡単に作成できるようになりました。また、ajax対応等現状のWEBのアーキテクチャが多く取り入られています。
バッキングビーンの作成
JSFではバッキングビーンという画面の値や処理を記載するクラスを作成するのが一般的です。まずはそのクラスを作成します。
package com.den2sn.mavenproject1; import java.util.ArrayList; import java.util.List; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @Named @RequestScoped public class HelloBackingBean { private List<String> messages; public void init() { messages = new ArrayList<String>(); messages.add("message1"); messages.add("message2"); messages.add("message3"); } public List<String> getMessages() { return messages; } }
バッキングビーンは単純なJavaのクラスです。今回はinitという初期処理を行うメソッドとメッセージの値を返すgetMessagesメソッドを作成します。このクラスを画面側より参照するためにCDIの@Namedアノテーションをつけています。@Namedアノテーションを付加すると画面側よりデフォルトではバッキングビーンのクラス名でインスタンスを参照する事ができるようになります。またメッセージデータをリクエスト中は保持したいので@RequestScopedアノテーションを付加しています。
画面の作成
次に画面を作成してみます。画面にはFaceletsというものを使用しますが中身はxhtmlでJSPとほぼ変わらないようなイメージで画面開発ができます。
メニューの新規ファイルから
「JavaServer Faces」 > 「JSFページ」 を選択します。
ファイル名を設定します。今回はindexとします。
生成された画面を一覧を表示するように修正します。
<?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" xmlns:f="http://java.sun.com/jsf/core"> <h:head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Facelet Title</title> </h:head> <h:body> <h1>Hello World!</h1> <f:event type="preRenderView" listener="#{helloBackingBean.init}" /> <div id="list"> <ui:repeat var="row" value="#{helloBackingBean.messages}"> <div>#{row}</div> </ui:repeat> </div> </h:body> </html>
h:やf:やui:がついているものがFaceletsのカスタムタグです。まずはf:eventタグでinitの処理を呼び出し、ui:repeatタグでメッセージの一覧を表示しています。Netbeansで画面を作成するとわかりますが、カスタムタグやバッキングビーンの参照を自動補完してくれるためとてもスムーズにコーディング出来ます。
前回のJAX-RSのサンプルでは事後のajaxの部分更新を考慮して一覧部分のみ非同期で画面を取得していましたが、JSFではajaxの部分更新をJSF自体がサポートしているため初期画面表示時に一覧画面も一緒に描画しています。
設定ファイルの修正・作成
Faceletsを使用するにはweb.xmlにFacesServletの設定が必要です。Netbeansを使用して上記手順でFacelets画面を作成していれば自動的に必要な記載をNetbeansが追加してくれるので特に修正は不要です。またCDIを有効にするためにbeans.xmlをWEB-INFフォルダに配置する必要がありますがbeans.xmlが無い状態でCDIのアノテーションを使用すると下記のようにワーニングを表示してくれるので修正候補に沿ってbeans.xmlを生成すれば問題ありません。この辺りのJavaEE開発の利便性がNetbeansを使用するメリットでもあります。
JAX-RSとKnockout.jsでJSON連携
JavaEE Advent Calendar 2012のブログ記事で書いたJAX-RSのサンプルではjersyのViewableクラスを使用したJSPによる画面描画を紹介しました。今回はjsonデータを返却してクライアントサイドで描画する方法を紹介します。
今回はクライアントサイドの描画にシンプルで使い勝手の良いJavaScript MVVMフレームワークであるKnockout.jsを使用しました。
Knockout.jsのダウンロード
Knockout.jsのサイト(http://knockoutjs.com/)より最新版のKnockout.jsをダウンロードし(今回はknockout-2.2.1.jsを使用)プロジェクトのフォルダに配置します。
HTMLファイルの修正
HTMLをKnockout.jsのテンプレートに即して修正します。
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type='text/javascript' src='knockout-2.2.1.js'></script> </head> <body> <h1>Hello World!</h1> <div id="list" data-bind="foreach: list"> <div data-bind="text: $data"></div> </div> <script type="text/javascript"> var viewModel = { list: ko.observableArray() }; ko.applyBindings(viewModel); $(document).ready(function(){ $.getJSON("webresources/hello/list", function(data){ viewModel.list(data); }); }); </script> </body> </html>
knockout.jsのライブラリを読み込みviewModelの定義を行います。knockout.jsではJavaScript上のオブジェクトデータと画面上の表示をko.applyBindings()で紐づけることで双方向に同期を取る事ができます。JavaScriptの処理ではjQueryのgetJSONメソッドで取得したJSONデータをリストにセットしているだけですが、データのセットと同時に画面の再描画も行ってくれます。前回の記事ではlist.jspに一覧のテンプレート処理を記載していましたが<div id="list">タグに直接テンプレート処理を記載しています。
JAX-RSの修正
JAX-RSの処理をJSONを返却するように修正します。
package com.den2sn.mavenproject1; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.Produces; @Path("hello") public class HelloResource { @Context private UriInfo context; public HelloResource() { } @GET @Path("list") @Produces("application/json") public List<String> list() { List<String> messages = new ArrayList<String>(); messages.add("message1"); messages.add("message2"); messages.add("message3"); return messages; } }
@Producesのメディアタイプが"text/html"から"application/json"になり、戻り値がViewableからList<String>を返すように変更しています。JAX-RSはメディアタイプを見て戻り値を自動で適切なデータに変換してくれるためとてもシンプルに処理を記載する事ができます。
web.xmlの追加
JAX-RSのデフォルトではJAXBを使用してJSONデータの変換を行います。しかしJAXBを使用する場合、戻り値のオブジェクトに@XmlRootElementアノテーションをつける必要があるなどなにかとめんどくさい点があります。そこで今回はJSONのパーサにJacksonを使用したいと思います。パーサにJacksonを有効にするにはweb.xmlでinit-paramを指定します。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <servlet> <display-name>JAX-RS Servlet</display-name> <servlet-name>org.netbeans.rest.application.config.ApplicationConfig</servlet-name> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> </servlet> </web-app>
servlet-nameにはjax-rsのパスが定義されているjavax.ws.rs.core.Applicationを継承したクラスのクラス名を記載します。
実行
あとは実行すると前回と同様一覧画面が表示されます。
サーバでJSONを返すようにする事でサーバの処理と画面の処理をより疎結合に開発する事が出来るようになります。どちらが良いとは言えませんがJSONを返却する今回の方式の方がよりRESTサービス的ではあると言えると思います。
JSF2.0で一覧表示に続く
JSF2のf:eventでアクションが何度も呼び出されてしまう
JSF2のfaceletsでf:eventというレンダリングの初期処理を行うタグがあるのだけれど、なぜか処理がが2重に呼び出される問題が発生。
私が記載していた記述が以下。
<f:metadata> <f:event type="preRenderView" listener="#{bean.init}" /> </f:metadata>
正しくはこっち。
<f:event type="preRenderView" listener="#{bean.init}" />
f:eventタグはまったくf:metadataで囲む必要は無いのだけれどブックマーカブルやf:viewParam等のキーワードで調べるとJava EEのチュートリアルや諸所のブログのサンプルでf:metadataの内部に記載されているものがあってはまってしまった。
(f:metadataはf:viewParam用のタグ)
Javaを知らない世代が今からはじめるJava EE開発
JavaEE Advent Calendar 2012 の19日目の記事です。
昨日は@n_agetsuさんの JSF2.0でボタンの2度押しチェックをするでした。
明日は@hiranasuさんのNativeQueryじゃだめ?~JPAクエリ表現ごとのパフォーマンス比較です。
Java EEの何について書こうかなと思ったのですが、これからJavaを始めようと思っている若い世代が迷わず簡単に始めることができるJava EE開発のスタートについて書こうかなと思います。
Java EEの開発はRails等のフルスタックなフレームワークとは違いライブラリやフレームワーク、IDE、テスト等の情報が種類も多くいろんな場所に散らばっていてる為、初心者が全容を把握することはなかなか困難な状態です。
また長年のJava開発の中でWeb上の情報も古くなってしまっているものが多く、今からJavaを始めようとするユーザにとってなかなか理解でしづらいのではないかと思います。
そもそもJava EEってなに?
Java EEはJavaでWebアプリケーションを開発するための標準の仕様です。現在、Java EEのバージョンは6で以前のバージョンで冗長だった記載がだいぶスマートに書けるようになりました。来年には7のリリースが予定されています。
開発環境
Javaの開発には統合開発環境(IDE)を利用します。Java EEでWebアプリをするなら是非NetBeansをインストールして下さい。IDEでは他にEclipse等がありますが最新のJava EE開発を行うにはやや環境が整えにくい面があります。
実行環境
開発したアプリケーションを実行するにはGlassFishをオススメします。GlassFishはJava EEの参照実装サーバで無料で利用可能です。NetBeansをインストールするとGlassFishも自動的にインストールされます。
アーキテクチャ
Java EEというものは様々な仕様を取りまとめたもので、単にWebアプリケーションを開発するだけでもいろんな仕様の利用パターンがあり自由に選択する事が出来ます。簡単にWebアプリケーションを作成したいのであればJAX-RSをベースにアプリケーションの開発を行う事をオススメします。その他にもJSFやServletを利用する方法もありますがJSFはやや古い設計でURLのデザインが難しくサーバ側にクライアント側の画面情報を保有する仕組みのため最近のJavaScriptを利用した動的な画面開発にはやや不向きです。Servletについては最古のWebインターフェースの仕様のため現在ではフレームワークの内部等特別な所でしか利用されないのが現状です。さらにWebアプリにリレーショナルデータベースを利用するのであればEJBやJPAといった仕様を利用します。画面はJSPで作成しても良いですしJSONとしてデータを返してJavaScriptで描画しても良いと思います。
実際にJava EEアプリを作ってみる
Java EEを使用して実際にアプリケーションを開発してみましょう。流れは以下です。
Javaのインストール
まずはJavaをインストールしないと始まりません。Javaの開発環境であるJava Development Kit(JDK)を以下のサイトよりダウンロードしてインストールします。バージョンは7推奨。
http://www.oracle.com/technetwork/java/javase/downloads/index.html
NetBeansのインストール
次に統合開発環境のNetBeansをインストールします。下記のサイトにアクセスしてNetBeansをダウンロードしてインストールします。もちろんJava EE対応のものをダウンロードします。
http://netbeans.org/downloads/
プロジェクト作成
NetBeansを起動してプロジェクトを作成します。
「Maven」>「Webアプリケーション」を選択します。
プロジェクト名等を設定します。
Java EEのバージョンはもちろん6でサーバにはGlassFishを選択します。サーバが選択出来ない場合は「追加」ボタンでNetBeansをインストールした際に一緒にインストールされるGlassFishを追加して下さい。
プロジェクトが出来上がりました。
アプリ作成
次にアプリケーションを作成します。JAX-RSでアプリを作ります。
ファイルのタイプに「Webサービス」>「パターンからのRESTful Webサービス」を選択します。
パターンに「単純なルート・リソース」を選択します。
クラス名等を設定します。
JAX-RSのクラスが作成されました。
次にソースを修正して行きましょう。まずはindex.jspファイルを開いてJAX-RSを呼び出すソースを追加します。DOCTYPEの修正(なぜかデフォルトはhtml5ではないので)、jqueryライブラリの追加、JAX-RSの呼び出し等を追加します。
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> </head> <body> <h1>Hello World!</h1> <div id="list"></div> <script type="text/javascript"> $(document).ready(function(){ $("#list").load("webresources/hello/list"); }); </script> </body> </html>
次にHelloResource.javaを修正します。今回はJSPを返信するためにjersyのViewableクラスを使用しました。ソースのエラー解決でMavenリポジトリで検索を選びpom.xmlにjersy-serverを追加します。
package com.den2sn.mavenproject1; import com.sun.jersey.api.view.Viewable; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.Produces; @Path("hello") public class HelloResource { @Context private UriInfo context; public HelloResource() { } @GET @Path("list") @Produces("text/html") public Viewable list() { List<String> messages = new ArrayList<String>(); messages.add("message1"); messages.add("message2"); messages.add("message3"); return new Viewable("/list.jsp", messages); } }
ファイル名をlistとします。
作成されたlist.jspのソースを修正します。今回はJSTLで設定したリストを表示しました。Java側でセットした値がitで取得できます。
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <c:forEach var="message" items="${it}"> <div><c:out value="${message}"></c:out></div> </c:forEach>
実行
ではアプリケーションを実行してみましょう。プロジェクトを右クリックして「実行」を選択します。
ブラウザに呼び出された一覧が表示されれば完成です。
作ったアプリケーションをWeb上に公開したいのだけれども...
実はJava EEはエンタープライズ向けの重たい仕様のため近年利用されているGoogle App EngineやHerokuのようなPaaSサービスでは未対応で、そのままWebアプリケーションとして登録する事は残念ながらできません。ただしHerokuでJAX-RSをひとまず動作させることは出来ます。heroku のサインアップが終了していれば
にアクセスし、RESTful API with JAX-RSのCreate Appボタンを押せばjettyサーバを使用したひな形がアプリができあがるのでそのひな形を元にいろいろといじってみるのが良いかと思います。
参考書籍
まずは金魚本を一通り読めばJava EEの大まかに把握できると思います。
Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava (Programmer’s SELECTION)
- 作者: Antonio Goncalves,日本オラクル株式会社,株式会社プロシステムエルオーシー
- 出版社/メーカー: 翔泳社
- 発売日: 2012/03/09
- メディア: 大型本
- 購入: 5人 クリック: 147回
- この商品を含むブログ (24件) を見る
もっと細かい内容を知りたい人はマスタリングJava EE本で。
マスタリングJavaEE5 第2版 (DVD付) (Programmer’s SELECTION)
- 作者: 三菱UFJインフォメーションテクノロジー株式会社斉藤賢哉
- 出版社/メーカー: 翔泳社
- 発売日: 2009/11/28
- メディア: 大型本
- 購入: 5人 クリック: 29回
- この商品を含むブログ (10件) を見る
アジャイルにだいぶ慣れてきたので思うところまとめ
アジャイル開発を初めて3ヶ月くらいたちました。週1のイテレーションにもだいぶ慣れスムーズに開発が行えるようになってきたので、アジャイルについて感じた事をまとめてみます。
思っていたより品質は落ちない
ダブルチェックや品質評価をウォーターフォールほどは行わないので品質は落ちるんだろうなと思っていたのですが思っていたよりは落ちませんでした。アジャイルではシステムを小さく作って小さくテストするので、大きく作って大きくテストするよりもテストの見落とし等が少なくなり品質が安定するようです。また、継続的に利用されるので問題も比較的早く見つかり素早く対策できます。
開発者のスキルアップスピードが早い
アジャイルでは本当に1分1秒の無駄を省き開発時間に業務時間を割くため開発者の技術スキル向上がかなり早いです。Rubyを全く知らない開発者だとしても、RailsのActiveRecord周りの知識からJavaScriptやCSSのViewまわりの知識までかなり広い範囲の知識を3ヶ月程度でかなりマスターできています。開発期間の半分をExcelと格闘するウォータフォール開発ではこれほどのスピードでのスキル向上は難しいんじゃないかと思います。
プレッシャが無くなるわけではない
ウォータフォールでは品質や納期に対するプレッシャがありますが、アジャイルは品質や納期がウォーターフォールよりは寛容なのでプレッシャは無くなるのかなと思っていましたが全然そんなことはありませんでした。品質や納期に対するプレッシャが減る分、開発スピードに対するプレッシャがのしかかってきます。技術的なところでつまってしまい全然作業が進まない時のプレッシャたるや半端じゃありません。
慣れるまでは大変
アジャイルはプロセスをユーザのニーズに合わせて比較的柔軟に変化させるためしっくりくるプロセスに落ち着くまでに結構時間がかかりました。最初の1ヶ月くらいはお客さん毎にうまく行くプロセスを模索するような期間が必要かもしれません。
Railsでajaxリクエストが2回送信されてしまう
Railsではヘルパーのform_forメソッドで:remote => trueというパラメータを渡すとformタグにdata-remote=trueというHTML5の属性が追加されて後はRailsのJavaScriptがよろしくデータをAjax送信してくれるわけですが、何故か急にリクエストが2回送信されるようになって困ってしまいました。
どうやらネットで調べるとjQueryを2重に読み込んでしまうと発生するというところまでわかったのですがそんなことはやっていません。
が、よくよくJavaScriptのソースを確認してみるとapplication.jsのソース内に何故かjQueryの文字が。なんだこれと思って考えてみるとそういえばなんとなく動くかなとアセットプリコンパイルを実行したのを思い出しました。
結果コンパイル済みのJavaScriptと既存のJavaScriptを2重に読み込んでいたというオチでした。ということでpublic/assetsフォルダのプリコンパイルソースを消して無事解決。
事象から問題になかなかたどり着けなくてかなりはまってしまったよ...