Java EE 7 メンテナンス・レビュー・ドラフトの変更リスト一覧

自分用メモ

Java EE 7 Maintenance Review: Proposed Changes
————-
Section EE.5.2.2. [Clarify rules for default namespace.]

Replace the first sentence of the sixth paragraph on p. 69, section
5.2.2, with the following:

The default JNDI namespace for resource references and resource
definitions must always be “java:comp/env”. Note that this applies to
both the case where no name has been supplied so the rules for
choosing a default name are used, and the case where a name has been
supplied explicitly but the name does not specify a java: namespace.
Since the java:comp namespace is not available in some contexts, use
of that namespace in such a context should result in a deployment
error. Likewise, the java:module namespace is not valid in some
contexts; use of that namespace in such contexts should result in a
deployment error.

———-

Section 5.3.3. [Clarify the requirements for the specification of
the lookup and lookup-name elements.]

Add the following to the end of the second paragraph of section
EE.5.3.3, p. 77:

Deployment should fail if the lookup element of an annotation or the
lookup-name element in a deployment descriptor entry does not specify
a name with an explicit java: namespace.

——————-

Section EE.5.18.6.1 [Correct editorial error in the second paragraph]

Change the following text on page 140:
If a mail session resource has been previously provisioned for the
application (e.g., by administrative action), it is the
responsibility of the Application Component Provider to specify
the mail server host name.
to:
If a mail server resource has been previously provisioned for the
application (e.g., by administrative action), it is the
responsibility of the Application Component Provider to specify
the mail server host name.

——

Sections EE.5.19, EE5.20, EE5.21. [Correct editorial error in third
paragraph of each of these sections to correctly reflect Application
Assembler role.]

In EE.5.19, change:
The Application Component Provider or Deployer may explicitly bind
a DataSource resource reference to the default data source using
the lookup element of the Resource annotation or the lookup-name
element of the resource-ref deployment descriptor element.
to:
The Application Component Provider or Application Assembler may
explicitly bind a DataSource resource reference to the default data
source using the lookup element of the Resource annotation or the
lookup-name element of the resource-ref deployment descriptor
element.

In EE.5.20, change:
The Application Component Provider or Deployer may explicitly bind
a JMS ConnectionFactory resource reference to the default
connection factory using the lookup element of the Resource
annotation or the lookup-name element of the resource-ref
deployment descriptor element.
to:
The Application Component Provider or Application Assembler may
explicitly bind a JMS ConnectionFactory resource reference to the
default connection factory using the lookup element of the Resource
annotation or the lookup-name element of the resource-ref
deployment descriptor element.

In EE.5.21, change:
The Application Component Provider or Deployer may explicitly bind
a resource reference to a default Concurrency Utilities object
using the lookup element of the Resource annotation or the
lookup-name element of the resource-ref deployment descriptor
element.
to:
The Application Component Provider or Application Assembler may
explicitly bind a resource reference to a default Concurrency
Utilities object using the lookup element of the Resource
annotation or the lookup-name element of the resource-ref
deployment descriptor element.

——

Sections EE.5.19.1, EE.5.20.1, EE.5.21.1 [Correct editorial error in
second paragraph of each of these sections to reflect role of
Application Assembler.]

In EE.5.19.1, change:
If a DataSource resource reference is not mapped to a specific data
source by the Application Component Provider or Deployer, it must be
mapped by the Java EE Product Provider to a preconfigured data
source for the Java EE Product Provider’s default database.
to:
If a DataSource resource reference is not mapped to a specific data
source by the Application Component Provider, Application Assembler,
or Deployer, it must be mapped by the Java EE Product Provider to a
preconfigured data source for the Java EE Product Provider’s default
database.

In EE.5.20.1, change:
If a JMS ConnectionFactory resource reference is not mapped to a
specific JMS connection factory by the Application Component
Provider or Deployer, it must be mapped by the Java EE Product
Provider to a preconfigured JMS connection factory for the Java EE
Product Provider’s default JMS provider.
to:
If a JMS ConnectionFactory resource reference is not mapped to a
specific JMS connection factory by the Application Component
Provider, Application Assembler, or Deployer, it must be mapped by
the Java EE Product Provider to a preconfigured JMS connection
factory for the Java EE Product Provider’s default JMS provider.

In EE.5.21.1, change:
If a Concurrency Utilities object resource environment reference is
not mapped to a specific configured object by the Application
Component Provider or Deployer, it must be mapped by the Java EE
Product Provider to a preconfigured Concurrency Utilities object for
the Java EE Product Provider.
to:
If a Concurrency Utilities object resource environment reference is
not mapped to a specific configured object by the Application
Component Provider, Application Assembler, or Deployer, it must be
mapped by the Java EE Product Provider to a preconfigured
Concurrency Utilities object for the Java EE Product Provider.

——
Sections EE.8.1.3., EE.5.19, EE.5.20, EE.5.21, EE.5.3.3.
[Clarify the rules for the binding of unmapped resources.]

In EE.8.1.3, add the following new paragraphs:

Every resource reference should be bound to a resource of the
required type.

Some resources have default mapping rules specified; see sections
EE.5.19, EE.5.20, and EE.5.21. By default, a product must map
otherwise unmapped resources using these default rules. A product
may include an option to disable or override these default mapping
rules.

Once a resource reference is bound to a resource in the target
operational environment, and deployment succeeds, that binding is
not expected to change. A product may provide administrative
operations that change the resource bindings that are used by
applications. A product may notify applications of changes to
their resource bindings using JNDI events, but this is not
required.

If deployment succeeds, in addition to binding resource references
as specified above, every resource definition (see Section EE.5.18)
specified by the application or specified or overridden by
the deployer must be present in the target operational environment.

In EE.5.19, change the following text:
In the absence of such a binding, the mapping of the
reference will default to the product’s default data source.
to:
In the absence of such a binding, or an equivalent
product-specific binding, the mapping of the reference will
default to the product’s default data source.

In EE.5.20, change the following text:
In the absence of such a binding, the mapping of the
reference will default to a JMS connection factory for the
product’s JMS provider.
to:
In the absence of such a binding, or an equivalent
product-specific binding, the mapping of the reference will
default to a JMS connection factory for the product’s JMS
provider.

In EE.5.21, change the following text:
In the absence of such a binding, the mapping of the
reference will default to the product’s default managed
executor service.
to:
In the absence of such a binding, or an equivalent
product-specific binding, the mapping of the reference will
default to the product’s default managed executor service.

In section EE.5.3.3, add the following to the end of the second paragraph:
The Deployer may also use product-specific resource mapping
tools, deployment descriptors, rules, or capabilities to
bind resource reference entries to resources in the target
operational environment.

——

Section EE.6.2.2.6 [Clarify requirements for support of custom
permissions]:

Add the following to the end of paragraph 3:
The Java EE product is not required to support permissions.xml
files that specify permission classes that are packaged in the
application.

——

Section EE.6.7. [In the list in paragraph 3, correct the interface
shown for the third and fourth items. This should be
javax.jms.JMSConsumer, not javax.jms.JMSContext].

Replace:
javax.jms.JMSContext method getMessageListener
with
javax.jms.JMSConsumer method getMessageListener

Replace:
javax.jms.JMSContext method setMessageListener
with
javax.jms.JMSConsumer method setMessageListener

——

Section EE.6.7. [In the list in paragraph 3, add missing methods for
consistency with JMS spec.]

Add:
javax.jms.JMSProducer setAsync
javax.jms.MessageProducer send(Message message, CompletionListener completionListener)
javax.jms.MessageProducer send(Message message, int deliveryMode, int priority, long timeToLive,
CompletionListener completionListener)
javax.jms.MessageProducer send(Destination destination, Message message,
CompletionListener completionListener)
javax.jms.MessageProducer send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener)

——
Section EE.8.5. [Clarify the rules regarding whether an application
is attempted to be started during deployment].

Replace the first full paragraph on p. 215 with the following:

Deployment may provide an option that controls whether or not an
application is attempted to be started during deployment. If no such
option is provided or if the option to start the application is
specified, and if deployment is successful, the application modules
must be initialized as specified in section EE.8.5.4 and the
application must be started.

If the application is attempted to be started during deployment, the
Servlet and EJB containers must be initialized during deployment.
Such initialization must include CDI initialization. If
initialization fails, deployment must fail.

If the application is not attempted to be started during deployment,
these containers must not be initialized during deployment.

In all cases, the deployment and initialization of a Java EE
application must be complete before the container delivers client
requests to any of the application’s components. The container must
first initialize all startup-time singleton session bean components
before delivering any requests to enterprise bean
components. Containers must deliver requests to web components and
resource adapters only after initialization of the component has
completed.

——
Section EE.8.5. [Clarify the requirements for annotation scanning and
processing.]

Replace the *first* paragraph of section EE.8.5 on p. 216 with the
following pragraphs (i.e., break it up as follows and include
the new text):

Some deployment descriptors are optional. The required deployment
information is determined by using default rules or by annotations
present on application class files. Some deployment descriptors that
are included in an application may exist in either complete or
incomplete form. A complete deployment descriptor provides a complete
description of the deployment information; a deployment tool must not
examine class files for this deployment information. An incomplete
deployment descriptor provides only a subset of the required
deployment information; a deployment tool must examine the application
class files for annotations that specify deployment information.

If annotations are being processed (as required by table EE.10-1,
Servlet table 8-1, and EJB tables 16 and 17), *at least* all of the
classes specified in table EE-5.1 must be scanned for annotations that
specify deployment information. As specified in section EE.8.5.2, all
classes that can be used by the application may optionally be scanned
for these annotations. (These are the annotations that specify
information equivalent to what can be specified in a deployment
descriptor. This requirement says nothing about the processing of
annotations that were defined for other purposes.) These annotations
may appear on classes, methods, and fields. All resources specified
by resource definition annotations must be created. All resource
reference annotations must result in JNDI entries in the corresponding
namespace. If the corresponding namespace is not available to the
class declaring or inheriting the reference, the resulting behavior is
undefined. Future versions of this specification may alter this
behavior.

Any deployment information specified in a deployment descriptor
overrides any deployment information specified in an application’s
class files. The Java EE component specifications, including this
specification, describe when deployment descriptors are optional and
which deployment descriptors may exist in either complete or
incomplete form. The attribute metadata-complete is used in the
deployment descriptor to specify whether the descriptor is complete.
The metadata-complete attribute in the standard deployment descriptors
effects *only* the scanning of annotations that specify deployment
information, including web services deployment information. It has no
impact on the scanning of other annotations.

——

Section EE.8.5.2. [Clarify the intended semantics by correcting the
ambiguity resulting from the use of “JAR” to refer to both modules and
.jar files referenced from modules.]

Change EE.8.5.2 item 1.d on page 218) from:

d.For all files in the application package with a filename extension
of .jar, but not contained in the lib directory, do the following:

i. If the JAR file contains a META-INF/MANIFEST.MF file with a
Main-Class attribute, or contains a META-INF/application-client.xml
file, consider the JAR file to be an application client module.

ii. If the JAR file contains a META-INF/ejb-jar.xml file, or
contains any class with an EJB component-defining annotation
(Stateless, etc.), consider the JAR file to be an EJB module.

iii. All other JAR files are ignored unless referenced by a JAR
file discovered above using one of the JAR file reference
mechanisms such as the Class-Path header in a manifest file.

to:

d.For all files in the application package with a filename extension
of .jar, but not contained in the lib directory, do the following:

i. If the .jar file contains a META-INF/MANIFEST.MF file with a
Main-Class attribute, or contains a META-INF/application-client.xml
file, consider the .jar file to be an application client module.

ii. If the .jar file contains a META-INF/ejb-jar.xml file, or
contains any class with an EJB component-defining annotation
(Stateless, etc.), consider the .jar file to be an EJB module.

iii. All other .jar files are ignored unless referenced by a JAR
file discovered above using one of the JAR file reference
mechanisms such as the Class-Path header in a manifest file.

——

Section EE.10.6 [Correct table to include missing entries for
application-client_6 and application-client_7. These should
be the same as for application-client_5.]

Add the following entries to Table EE.10-1:
application-client_6 Yes No
application-client_7 Yes No

Add the following to the paragraph above this table:
Whether or not to process annotations depends on the
presence and version of the deployment descriptor and
the setting of the metadata-complete attribute.

——-

Figures EE.8-3, EE.10-1 [Corrected inconsistencies with the XML
schemas.]
Replace “connector-resource*” with “connection-factory*” in
Figures EE.8-3 and EE.10-1.
Add “administered-object*” to Figure EE.10-1.

2015年5月9日 at 2:55 午前

CDI を理解する為に重要なレシピ

Java Day Tokyo 2015 で私が発表した内容を下記に公開しました。本セッションは、資料を作成する上で、今回ご紹介する内容を、より重点的に説明した方が良いと判断し、アジェンダに記載した若干内容を変更しお届けさせて頂きました。しかし本セッションは、日本でまだ不足している情報をお届けする内容であるため、皆様のご理解のお役に立てば誠に幸いです。

Java EE を利用して Web アプリケーション、企業アプリケーションを構築するためには、Webのデザイン、データ・アクセス部の実装、そしてそれらをつなぐビジネス・ロジックの3階層から構成する事が多いかと思います。これらの構成要素の中で、今回は、ビジネス・ロジックの実装部で重要な役割を担う CDI について焦点をあて、利用する上で重要な点について 14 点ご紹介しました。

本セッションは単に CDI の機能の紹介にとどめる事なく、何らかの処理を実装する上での課題を示し、今までの実装方法や各機能の利用上好ましくないやり方を 赤文字で “Yucky(まずい)” 示した上で注意点を促すと共に、解決策、改善方法を青い文字で説明するというやり方で説明しています。

また、CDI を正しく利用するために必要となる前提知識や、関連機能についても順に説明し、DI や CDI を理解する上で必要な情報を提供しています。今まで、CDI を限定的にしか利用していなかった開発者に対して、CDI にはこのような機能があったのか、このような使い方ができるのかといった事を理解して頂けると共に、何故 CDI が必要なのかを理解する事ができる内容になとしています。
今回、ご紹介する内容は下記になります。

問題1:リソースの参照について
問題2:ライフサイクル管理について
問題3:横断的関心事の分離方法について
問題4:値の検証方法について
問題5:依存性注入について
問題6:依存性注入対象の限定方法について
問題7:不変オブジェクトとしての注入方法について
問題8:文字で対象選択
問題9:CDI の有効化について
問題10:有効範囲の設定について
問題11:唯一の選択方法について
問題12:柔軟なインスタンスの生成方法について
問題13:アノテーションの整理
問題14:イベント処理

セッション内容を録画したビデオが下記に公開されていました。

今回、構成の都合上、アジェンダに記載しながらも扱う事ができなかった、Concurrency Utilities for Java EE や WebSocket 等につきましては、過去の資料でご紹介していますので、併せて下記もご参照ください。

2015年4月15日 at 1:19 午後 1件のコメント

Java Day Tokyo 2015 の御礼

2015 年 4 月 8 日(水) Java Day Tokyo 2015 を開催しました。イベントにご参加頂いた皆様、ご登壇者の皆様、スポンサー企業の皆様、そして事務作業からイベント運営まで裏方として支えていただいた多くの皆様、誠にありがとうございました。
当日は、あいにくの天気でございましたが、最後まで特に大きなトラブルもなく終わる事ができたのは、一重にご参加頂いたすべての皆様ご協力のおかげです。

下記の文章は、諸般の事情で記載する文面を「である調」で記載しているため内容が固くなっておりますが、基調講演で語られた様々な内容をまとめてみましたので、どうぞお時間のある時にご覧ください。また、本ブログの最後に、ニュース記事や、Toggetter、ブログ等のリンクも記載しています。併せてご覧下さい。

■ 日本オラクル社長からのご挨拶

冒頭、日本オラクル取締役 代表執行役 社長兼CEO 杉原 博茂より、オラクルにおける Java の重要性について語られた。
 杉原はオラクルが他の企業とオラクルは何が違うかについてラリー・エリソンに尋ねたという、その際ラリー・エリソンは「我々には Java がある」と語ったという。杉原もまた、オラクルにとって Java は重要なテクノロジーであり、今後「Digital Disruption(デジタルによる破壊)」が訪れる中で、Javaが重要な役割をもたらすと語った。例えば、企業においてソーシャル・ネットワークの影響はかつてない程大きくなっており、その影響はもはや無視できない所まできている。また新しい産業革命の波が訪れており、Java がこうした時代において何をもたらすのか、非常に興味深いと語った。さらに、2020年までに人口の約3割が 65歳以上になり、250万人の人口が減少すると統計学的に予想されている、このような将来において1人1人の生産性が今まで以上に重要になる。オラクルは今後、迎えるさまざまな時代の変革において、生産性の高いITの提供方法を考え、一つの解をだした。それが完全な「クラウド・シフト」である。もちろん、今まで同様にオラクルはオンプレミスの環境でのサービスも提供するが、それと同様にクラウド上でも同様に様々なサービスを提供する。現在のIT社会において、「IoT」、「Social」、「Big Data」、「Mobile」といったサービスが提供されているが、これらを実現するために、最も重要なのが「Java」であると語った。世界的視野でみると、様々なデバイスで Java が動作し、将来的には車も Java で制御されるような時代がおとずれ、今まで以上にさまざまな物がJava で動くようになると語る。世界にはJavaの開発者が900万人いると言われるが、Java Day Tokyo にお越し頂いた開発者が、世界の開発者の一員である事に対して誇りに思うと語った。
最後に杉原は、次の日に開催される、Oracle Cloud World Tokyo 2015 で発表予定の「Java クラウド・サービス」を、Javaの開発者に対して先がけて発表を行った。これは Java の技術をクラウド上でより簡単に使いやすく利用できる物であると語り、皆様とともにクラウドの社会を作っていきたいと強く語って挨拶を締めくくった。


■ Java 20 周年のハッピー・バースデー

 2015年は Java が世界に発表されて20周年を迎える記念の年で、Java Day Tokyo に参加した開発者と共に、ハッピー・バースデーを歌い祝った。さらに Java の生みの父と言われる「James Gosling 氏」より、来場する Java 開発者に向けてビデオ・メッセージが贈られた。

James Gosling は Java の20年を振り返りとても広範囲に利用される言語になった事、Java コミュニティの成長が素晴らしい事、特に日本は素晴らしい土地で、過去に何度も来日しお客様とお話をした事、数えきれない程のイベントを行った事を思い出した。その際、日本のお客様や、パートナー、Javaのゲーム・コミュニティなど、お会いした皆様はとても素晴らしい方々だった事を覚えていると語った。また、イベントでコンテストを開き審査員を務めた事も楽しい思い出だったと回想した。日本のJava開発者コミュニティの皆様が行ってきた事はとても素晴らしい事で、今後 20年をとても楽しみにしています。皆様本当にありがとう、といったメッセージを開発者に届けた。

■ Java 開発者コミュニティへの参加の呼びかけ貢献について

続いて、JavaOne Conference の委員長を務めるSharat Chanderより、Java コミュニティへの参加の呼びかけが行われた。そして開発者の皆様とオラクルが良好な関係を築くためにコミュニケーションを持つ事がとても重要だと語った。冒頭で、Sharatは、「我々オラクルの来日理由は、開発者の皆様と良好を築くためであり、それはとても重要な事」だといった。なぜなら、過去20年間にJavaコミュニティからの多大な貢献があり、もしコミュニティや開発者の皆様との良好な関係がなければ Java の品質を向上する事はできなかったと言う。日本には「日本Javaユーザ・グループ」、「関西Javaエンジニアの会」という大きな Java コミュニティがあるが、この日本のJavaコミュニティの貢献に対してぜひ感謝を送りたいと語り、会場の来場者と共に拍手を贈った。さらに日本から OpenJDK コミュニティへの参加者が増えている事にも感謝を述べたいとし、実際に参加されている、末永恭正氏、久保田祐史氏、吉田真也氏、大村忠史氏を紹介し同様に感謝の拍手を送った。また、Sharat はここで、Java SE 8 用の新しい資格試験の提供開始も発表した。

オラクルは、今後も継続した Java 開発者の皆様と良好な関係、強力な関係を構築したい、そのためにソーシャル・ネットワークを通じて情報交換を行いたいと言い下記をそれぞれ紹介した。

情報収集のため
* G+ : plus.google.com/+javaplatform
* Twitter : twitter.com/java
* YouTube : youtube.com/java
* Facebook : facebook.com/ilovejava
* Blog : blogs.oracle.com/java

Java コミュニティへの参加のため
* home.java.net/jugs
* java.net
* openjdk.java.net
* jcp.org

最後に、次の Java の 20年を作っていくために、フィードバックやアイディアを直接 Java コミュニティ経由で届けて欲しいと語り締めくくった。

■ Java SE 8 & ME 8 に関するアップデート

続いて、Java Platform Development の Vice President を務める、Georges Saab よりJava SE 8 と ME 8 に関するアップデートを行った。
 Georges は冒頭、自身の Java の経歴について語った、彼は1996年のJavaの提供開始当時、Sun Microsystems に在籍し Java のクライアント・ライブラリの開発業務に従事していた。その後、BEAに移動し JRockit の開発部門を率いた。JRockit は日本でも非常に多くのお客様に利用して頂き感謝を述べたいと語った。さらにOracle との統合後、Javaの開発部門を率いる事になり、自分にとってもこの20周年はとても感慨深いと語った。
 昨年、JDK 8 をリリースしたが、JDK 8 は非常に多くの機能を持っている。これら全てを語る事はできないが、オラクルの投資は今後も継続し、Java コミュニティと共にさらにより扱いやすい物を提供していきたいと考えていると語った。また、Java を近代的なプログラミング言語にするために導入したLambda 式(関数型プログラミング手法)について説明した。Lambda 式は言語仕様に対して大幅な変更を加えた他、Java仮想マシンにも手を加えてパフォーマンスの向上を図っていること、さらにコレクション・ライブラリをより効果的に分かりやすく記述できるように Stream API を提供したことについても紹介した。そしてこれらを適切に利用する事により、JDK 7 で実装したコードに比べ最大で40%のパフォーマンス向上が期待できる事を紹介した。さらにセキュリティ対応はオラクルにとって最も重要である事も付け加えた。
この Java SE 8 における変更は今までのJavaの歴史の中で、かつて無い程に大きな変更を行った事を紹介した。

■ Pepper の制御用 Java SDK の提供開始について

 Georges Saabより Aldebaran Robotics の Software Director である Laurent Lec 氏が壇上に招かれ、Laurent 氏より、「Pepper」の制御用 Java SDK が正式に発表された。また、あわせてデモンストレーションも行われた。(「Pepper」は最寄りの SoftBank ショップでご覧頂く事ができる)

Aldebaran(https://www.aldebaran.com/ja)はフランス企業でソフトバンク関連企業の1社でもある。Aldebaran は人間型のロボット(NAO,Romeo,Pepperなど)を提供している。Pepper はバッテリーや音声検知用のセンサー、タッチセンサーなど、様々なセンサーを内蔵しており、それらを検知して動作するようになっている、さらにスクリーン・モニターにはビデオやWebページ等を描画する事も可能だ。そして Pepper は自由にプログラミングが可能になっている。
デモンストレーションでは、声を発声するためのコンポーネントをドラッグ&ドロップで開発環境に配置しPepper で挨拶をさせた他、複数のコンポーネントを同様にドラッグ&ドロップでつなぎ合わせる事で複数の動作を連携して実行する事が簡単にできることを紹介した。その後、Java で制御するサンプル・コードを示し Java で動作させた。(ご興味ある方は、パッケージ名com.aldebaran.qi から検索頂きたい)

■ Java SE 8 のロードマップについて

Georges は、最後にJava SE 8 のロードマップを示した。現在提供されている Java SE 8 update 40は様々な新機能が組み込まれており素晴らしいできで、現在 update 60 の実装を進めている。また来年には JDK 9の提供も検討されている事が説明された。JDK 9 では Project Jigsaw として知られているモジュール化の機能が導入される予定で、アプリケーションのパッケージの仕組みが大きく変わる事を紹介した。モジュール化による恩恵はセキュリティや、パフォーマンス、起動時間の高速化などで期待ができる事だと語った。最後に、Georges は JDK 8 を是非本番環境で積極的にご利用いただきたいと語った。また、さらに Java SE 9 も、jdk9.java.net にアクセスし、早期お試し版をクオリティ改善のために試し頂きフィードバック、バグ報告などを行って頂きたいと語った。

■ Java ME 8について

Java ME は過去、Java SE と Java ME との間にあった大きなギャップを埋め、Java SE 8 で蓄えたノウハウが、そのまま Java ME でも利用できるように、言語仕様やライブラリの統合化を進めていると語った。これに対して業界は非常に好意的で、ダウンロード数も非常に多くなり、業界間におけるコラボレーションも行われている。これにより実装改善が行われ、パフォーマンス改善もされているという。また、Java SE 8 Embedded や Java ME Embedded 8.1 等新しい製品もリリースされ、様々な環境で利用可能になっている点を報告した。

■ Java ME 8 のデモンストレーション

ルネサス エレクトロニクス株式会社の米山氏を壇上に招き、オラクルと共に作成した Java ME 8 のデモを紹介した。米山氏によると、IoT 市場は今急激に拡大し、膨大なデータのやりとりを行っている。デバイス側の観点で考察すると、IoTゲートウェイはどのようにセンサーを管理しているか、サーバはどのように受信したデータを分析しているかが分からない。一方でサーバ側では、どのように IoT ゲートウェイとセンサーが通信しているのか、各種センサーでどういった事ができるのか、どのようなデータを取得できるのかを把握する事は困難であると語る。ルネサス エレクトロニクスは、デバイス・センサーの提供者側として、デバイス側であらゆるデータ処理加工を行い、IoT ゲートウェイに対して価値のある小さなデータを送る事がとても重要であり、そこに価値があると考えていると語る。その際に、Java が持つ資産はとても魅力的であり、デバイスが異なってもそのノウハウを流用できる事は、より効果的で新しい未来が訪れるだろうと語った。
今回、組み込みデバイスで実装された自動車をバスに見立て、バス停毎に容易されたツイッター・クライアントからバスの運行状況をリアルタイムに通知するデモンストレーションを行った。これを実装する際、Java ME は mbed を標準でサポートしているため、mbed 上で簡単にアプリケーションを作成する事ができ、デバイス上からクラウドに対して簡単に情報配信するための仕組みを実装、提供できるようになったと語った。Java と組み込みのデバイスは、アイディア次第で新たな価値を創造できる、Java の開発者の皆様と共に新しい物を創造していきたいと語った。

■ Java Car のデモンストレーション

続いて、Internet of Things のアーキテクトを務める Jasper Potts 氏より Java Car に関するデモが行われた。このデモは昨年のJavaOne 2014 サンフランシスコで世界中のJava開発者に披露したデモと同様で本場のデモを日本に持ってきた形となる。この車に見立てたデバイスのデモは様々なセンサー・デバイスが搭載されており、例えば重力センサーも搭載されており、車がカーブした際にかかる G(重力) の情報も画面に表示できるようになっている。また、音楽も聞く事ができるようになっている他、光を検知するためのライトセンサーも持つため、ライトセンサーが夜を検知した際に、モニター表示も自動的に夜の描画モードに変更可能だ。この車の各種デバイスは、各種センサー情報をIoTゲートウェイ通じて、センサー情報のデータをクラウド上にのサーバに対してリアルタイムで情報をアップデートできる。またバッテリーの使用状況も監視し、バッテリーの寿命が来た際に自動的にサーバ側から、車上のモニターに警告情報を通知し、併せてあらかじめ登録された携帯電話に対してメールで通知可能という。さらに車のディーラにも情報を通知する事でメンテナンスの予約情報なども通知できるようになっている。
JavaOne 2014 San Francisco の日本語字幕付きデモはコチラでも視聴可能。(https://www.youtube.com/watch?v=IK11x-Nr8Qs)

■ Java EE の現在と将来について

Java EE に関して、Cloud Application Foundation の Senior Vice President である Cameron Purdy より説明が行われた。Cameron は冒頭で、James Gosling のビデオに触れ、James Gosling といえば、JavaOne で T-シャツ投げをする事が有名で覚えている方もいるかと思うといい、同様にTシャツ投げをするといい壇上からTシャツ投げを行い、会場を盛り上げた。

Java EE は様々なアプリケーション・サーバ・ベンダーで対応されており、世界中のJavaコミュニティ・メンバーから多大な貢献を頂き提供をしていると語った。

Java EE 7 は様々な機能を新規追加したが中でも HTML 5 対応はより重点をおいて対応したと語った。HTML 5対応として新しく、WebSocket や JSON 対応等がある。また、開発生産性の向上は引き続き行われ、アノテーション・ベースの開発として CDI も継続して改良を行った。また企業アプリケーションの開発ニーズに対応するために、バッチ処理の標準化なども行った他、メッセージング・サービスの実装機能として、JMS 2.0 も大幅に開発生産性を向上したことなどを紹介した。
また、昨年、Java EE の参照実装である、GlassFish v4.1 をリリースしたが、このリリースでは数多くのバグ対応を行った他、Java SE 8 にも対応したと語った。

Java EE 8 の正式リリースに向けて我々はすでに検討を重ねており、現在の市場が求める技術トレンド等を調査している。検討中の内容として、例えば、新しい HTTP の仕様である HTTP/2があるという。また、RESTful Webサービスによる実装は現在多く行われているが、サーバとのデータ交換に JSON のデータ・フォーマットが利用される事が多いという。Java EE 8 では、この JSON データをより簡単に扱うため、Java オブジェクトと JSON を直接バインド(結びつけ)する、JSON-Binding の導入も検討している。もちろん、こうした技術においてセキュリティは非常に重要であるため、セキュリティに対する実装も改善を予定している他、サーバ側のイベントに応じてクライアントに対して通知をするための、Server-Sent Event の導入なども検討されているという。
その他、CDI 2.0 や JMS 2.1、JSF 2.3、MVC 1.0、Java EE Management 2.0 等も予定されているという。これらは全て Java EE 8 の仕様に含まれ、Java EE 8 のProposalドラフトは全会一致で承認されたことを報告した。また、オラクルのパブリック・クラウドのサービスについて Cloud Developer Outreach の Stephen Chin からライブのデモンストレーションが行われた。Steve は事前に用意した WebLogic が稼働する、Java Cloud Service のインスタンスと、Coherenceを連携し、大量データの効率的な処理を行うデモンストレーションを行った。

Cameron は最後に、Java EE のロードマップについて紹介した。Java EE 7 は2013年に正式リリースを行ったが、その後、Java EE 8 の提供に向けて動き始めた。まず、最初に行ったのが世界中の Java EE の開発者に対するアンケートだ。どのような機能が実際に必要とされるのかを開発者自らに問い合わせた。その結果を交え Java EE 8 に含む技術を検討し、昨年より Java EE 8 を開始した。来年末までには Java EE 8 と併せて参照実装である GlassFish を提供したいと考えていると語った。Java EE 8 の提供に対して、世界中の Java コミュニティが Adopt-A-JSR というプログラムを通じて貢献している。日本 Java ユーザ・グループも、JSR 371 : Model-View-Controller(MVC 1.0)に対する貢献の意向を表明していると聞いおり、JJUG に対して大変感謝していると述べた。Java EE では、まだ他にも様々な仕様が存在しており、是非エキスパート・グループ・メンバーに参加し Java EE 8 の標準化に対して参加して欲しいと語った。参加のご意向がある方は glassfish.org/contribute へアクセスをして欲しいと言いセッションを締めた。

■ Java への新たな取り組み – JCP への参加とコミュニティ参加

Cameron に代わり、基調講演最後のセッションをまとめたのは、日本オラクル Fusion Middleware 事業統括本部の伊藤 敬だ。
伊藤は冒頭、Java は20周年を迎え、これから新しい事を始める事に対して日本オラクルとして今後も貢献していきたいと語った。日本オラクルの取り組みとして、Java for Kids, Java for Students, 小学生、中学生、高校生に向けた Java の勉強会を開いている。
小学生でも、楽しみながら Java を勉強し、中学生以上になると本格的に Java を教えている。
学生に、早い時期からプログラミングを教える事は今後の時代を変えていける事でもありとても重要であると考え、今後も続けていきたいと語った。

オラクルの取り組みを紹介した後、伊藤は3名のゲストを壇上に招き入れた。

➢ 楽天株式会社 技術理事:      仲宗根 徹也氏
➢ 日本 Java ユーザ・グループ 会長: 鈴木 雄介氏
➢ 関西 Java エンジニアの会 会長:  阪田 浩一氏

楽天株式会社の仲宗根氏から、楽天における JCP 参加(2014年9月)の経緯について語られた。楽天では E-コマース、トラベル、金融、メディア、広告など様々なサービスを展開している。特に楽天会員、楽天スーパーポイントといったサービスを「楽天経済圏」と名付けて構築している。楽天のサービスは PHP や Ruby 等で構築されているサービスも存在するが、「楽天経済圏」のコアなサービスは全て Java で構築していると語った。JCP の参加は日本オラクル社員の紹介で、初めてその機関の存在を知り興味を持ちはじめたが、当初は加入に対して不安要素もあった。楽天はテクノロジーを売りにする企業ではなく、サービスを提供する企業であるため、サービス企業が Java の仕様策定に関わる事ができるのか、またそのような時間を割く事ができるのか不安だった。しかし、「楽天経済圏」のコア部分は全て Java でできているため、Java に対して貢献する事が、自分達の将来の開発に役に立つのではないかと考えた。エキスパート・グループへの参加や、参照実装を作るまでの事ができない場合も、Java の動向を正しく理解し、将来に対し意見が言える場にいる事は利点でないかと考えた。これらを総合的に判断し楽天は JCP への参加を決定したと語った。まず JCP の参加に辺り、JCPチームを作り、Java に興味のある社員を集めた、そこで参加者が興味のある JSR(仕様) を観察し、JCP チーム内で情報共有する所から始めている。そして将来的には世の中に対して情報発信をしていきたいと考えていると語った。また、実際の JCP への参加事例として JSR 372 : JavaServer Faces 2.3 の仕様に対する実際の貢献内容について報告した。JSF のスコープという機能に対して、ある楽天のエンジニアが新しいスコープを考え、その参照実装を作成し JSF のエキスパート・グループ・メンバーに提出した所、それが採用され、次期 JSF 2.3 の標準仕様内に取り込まれる事になったという。これにより自社のアプリケーション開発においても将来、自分が提案した技術を利用できるようになる日がくるという。そして、それが世界の開発者にとっても開発生産性を高める事になるのであれば、楽天という会社にとっても大きな社会貢献になるのではないかと考えていると語った。
自分たちが使う言語を自分たちが良くしていく事は、開発者自身のためであり、楽天が提供しているサービスのためでもあり、大きな社会貢献であると考えていると語った。仲宗根氏は最後に、自らの経験から来場者にむけて「スモール・スタートで JCP を始めては如何でしょうか?」と語った。

続いて、日本 Java ユーザ・グループ(JJUG)会長の鈴木雄介氏が登壇した。JJUGは現在会員数が約3000名で、Java の技術向上やエンジニアの地位の向上を目的として活動している。主な活動内容として年に2回開催するクロス・コミュニティ・カンファレンスのほか、毎月定例のナイトセミナーを開催している。さらに日本全国に存在する地方のJavaコミュニティに対して東京から講師派遣も行っているほか、国際会議へも参加していると語った。今年、JJUG として重点的に取り組みたい内容として、JSR への参加があるとした。Java は Java Community Process(JCP)の中で Java Specification Request(JSR)が登録され、いくつかのレビュー・プロセスを通じ最終版が確定するプロセスになっている。JSR に対する貢献は、楽天のような営利企業として参加する事も可能だが、ユーザ・グループのメンバーとして参加可能だと語った。ユーザ・グループ用に用意されているプログラムとして Adopt-A-JSR プログラムという物がある。このプログラムは比較的、緩い関わりを持ちながら参加ができる内容で、仕様のパブリック・レビューや各仕様の啓蒙活動を行う事が目的になっている。JJUGでは今回 JSR 371 : MVC 1.0 への参加を表明し、Struts に置き換わる軽量な MVC として期待される、新しい仕様を評価しフィードバックを行うほか、これを日本の開発者に伝えていきたいと語った。

最後に、関西 Java エンジニアの会(関ジャバ)会長の阪田浩一氏が登壇した。関ジャバは2009年設立で年3、4回のイベントを開催しており、2014 年日本では2例目となる java.net で公式な JUG として認められたという(https://java.net/projects/kanjava)。活動は地方コミュニティのため少数で行う事が多く、約 20〜70 名程の参加者で勉強会を開催している。そして阪田氏は、来場者にむけて「是非、ローカルのJUGに参加してください」と呼びかけた。大規模なイベントの場合、中々参加者同士交流を持つ事は難しい。しかしローカルの JUG であれば発表者と参加者の双方向なコミュニケーションが容易にでき、また参加者同士も人数が少ないため交流がやりやすくなるという。さらに地域特有の情報が得られるほか、転職活動を考えた場合も様々な情報を入手しやすいといい、こうした活動はエンジニアにとって重要なポイントだと語った。一方で地方の JUG はスピーカー不足に悩まされており、毎回同じ人がスピーカーになる事が多いため、継続してコミュニティ活動を行っていくためにも、参加者自らが積極的に登壇者になって頂きたいと語った。仮に自分がお住まいの地域に JUG が無いならば自らが JUG を作りましょうと熱く語った。関ジャバの設立のきっかけも、自らがブログを書いた事がきっかけだったという。阪田氏が「関西で Java のコミュニティを作りたい」とブログで書いた所、同様の考えを持つ方が現れ、興味を持つメンバーで集まって何ができるか考えた所から始まったという。最初から大きな事は考えず、まずはやりたいという事を表明する所から始めて、地域にいる Java の開発者同士が繋がっていけば、次第に新しいユーザ・グループができるのではないだろうかと語った。関ジャバとしては、今まで内輪のお友達感覚のユーザ・グループだったが、今後正式 JUG と認定されたため、コミュニティの質を向上していきたいと語った。具体的にはコミュニティの認知度をさらに向上させたいと考えている。またJJUG と同様に1つの JUG として JCP に加入しているため、JSR を通じて、模索しながらも Java に貢献していきたいと考えている。さらにコミュニティの運営方法についても改善していきたいと語った。日本全国でJUGがたくさんできた暁には、関ジャバも一緒にイベントを行いたいと語りまとめた。こうした活動は、全て特別な事ではなく誰でもがすぐにできる事であり、ぜひ日本の Java 開発者の皆様も積極的なコミュニティ参加を呼びかけた。

最後に、伊藤 敬より参加者に Java Day Tokyo で学んだ事、感じた事をSNSやブログ等に投稿して欲しい。そして積極的なコミュニティへの参加を呼びかけ Java Day Tokyo の基調講演を終えた。

★ Java Day Tokyo 後のニュース・メディアや Twitter 、ブログのまとめ記事など。

JSF の相関項目チェック by Bean Validation

このエントリは、半分以上お遊びですのであまり詳しくは説明しません。ご興味ある方はお試しください。JSF で複数入力項目がある場合の相関チェックをする場合、通常は JSF のコンポーネントにバインドさせてバリデーション・フェーズで検証を行っていましたが(ご参照:本エントリの一番下に例を記載してますがそちらの方が楽です)、今回、Bean Validation、カスタム Bean Validation さらに CDI と PhasesListner を駆使して複数入力項目がある場合の相関チェックをしてみました。

JSF では直接 Bean Validation のクラスレベルの検証ができないので、無理矢理クラスレベルでチェクをするために、PhasesListener 内で ValidatorFactory をインジェクトして、validateメソッドに渡す事で Person クラスをValidate しています。おもしろいのが、JSF のライフサイクルで「モデル値の適用」フェーズ後は Person に代入された値が @Inject Instance<Person> でインジェクトできるようになるので、直接 Person としていじくれるようになる事です。

JSF の Facelets の内容

<?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://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form prependId="false">
            <h:outputLabel id="birthDay" value="Input Birth Day"/>
            <h:inputText id="inputYear" value="#{personManaged.person.birthYear}"/>/
            <h:inputText id="inputMonth" value="#{personManaged.person.birthMonth}"/>/
            <h:inputText id="inputDay" value="#{personManaged.person.birthDay}"/><br/>
            <h:outputLabel id="age" value="Input Age"/>
            <h:inputText id="inputAge" value="#{personManaged.person.age}"/>
            <h:commandButton value="Check Multi Value" action="#{personManaged.execSubmitButton()}"/>
            <h:messages/>
        </h:form>
    </h:body>
</html>

faces-config.xml の内容

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
 <lifecycle>
        <phase-listener>jp.co.oracle.jdbcrealm.cdis.phaselisteners.ValiationPhaseListener</phase-listener>
    </lifecycle>
</faces-config>

Facelets のバッキング・ビーン

package jp.co.oracle.jdbcrealm.cdis;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import jp.co.oracle.jdbcrealm.customvalidations.Person;

@Named(value = "personManaged")
@RequestScoped
public class PersonBirthDayValidatorBackingBean {

    @Inject
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public void execSubmitButton() {
        System.out.println(person.getBirthYear() + "/" + person.getBirthMonth() + "/" + person.getBirthDay() + "\t" + person.getAge());
    }
}

Person クラス

package jp.co.oracle.jdbcrealm.customvalidations;
import java.math.BigDecimal;
import javax.enterprise.context.RequestScoped;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;

@RequestScoped
@PersonClassLevelValidator // <---- カスタム・バリデータ
public class Person {

    @NotNull 
    private Integer name;
    @NotNull @Digits(integer = 3,fraction = 0)
    private Integer age;
    @NotNull @Digits(integer = 4,fraction = 0)
    private Integer birthYear;
    @NotNull @Digits(integer = 2,fraction = 0)
    private Integer birthMonth;
    @NotNull @Digits(integer = 2,fraction = 0)
    private Integer birthDay;

    /**
     * @return the name
     */
    public Integer getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(Integer name) {
        this.name = name;
    }

    /**
     * @return the age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * @param age the age to set
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * @return the birthYear
     */
    public Integer getBirthYear() {
        return birthYear;
    }

    /**
     * @param birthYear the birthYear to set
     */
    public void setBirthYear(Integer birthYear) {
        this.birthYear = birthYear;
    }

    /**
     * @return the birthMonth
     */
    public Integer getBirthMonth() {
        return birthMonth;
    }

    /**
     * @param birthMonth the birthMonth to set
     */
    public void setBirthMonth(Integer birthMonth) {
        this.birthMonth = birthMonth;
    }

    /**
     * @return the birthDay
     */
    public Integer getBirthDay() {
        return birthDay;
    }

    /**
     * @param birthDay the birthDay to set
     */
    public void setBirthDay(Integer birthDay) {
        this.birthDay = birthDay;
    }
}

Person クラスのバリデータ(相関チェックの実装)

package jp.co.oracle.jdbcrealm.customvalidations;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.Period;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = PersonClassLevelValidator.PersonClassValidtor.class)
@Documented
public @interface PersonClassLevelValidator {

    String message() default " Invalid input of the Birthday or Age";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class PersonClassValidtor implements ConstraintValidator<PersonClassLevelValidator, Person> {
        PersonClassLevelValidator constraintAnnotation;
        @Override
        public void initialize(PersonClassLevelValidator constraintAnnotation) {
            this.constraintAnnotation = constraintAnnotation;
        }

        @Override
        public boolean isValid(Person person, ConstraintValidatorContext context) {
            if ( person == null) return true;

            // Person として直接扱えるので色々楽
            int age = person.getAge();
            int birthYear = person.getBirthYear();
            int birthMonth = person.getBirthMonth();
            int birthDay = person.getBirthDay();

            LocalDate birthDate;
            try {
                birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
            } catch (DateTimeException de) {
                return false;
            }
            LocalDate today = LocalDate.now();
            Period period = Period.between(birthDate, today);
            return age == period.getYears();
        }
    }
}

JSF の PhasesListener でモデル値適用後に Person をバリデート

package jp.co.oracle.jdbcrealm.cdis.phaselisteners;
import java.util.Set;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
import jp.co.oracle.jdbcrealm.customvalidations.Person;
import jp.co.oracle.jdbcrealm.customvalidations.PersonClassLevelValidator;

public class ValiationPhaseListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.UPDATE_MODEL_VALUES;
    }

    @Inject
    ValidatorFactory validFactory;

    @Inject
    javax.enterprise.inject.Instance<Person> instanceOfPerson;

    @Override
    public void afterPhase(PhaseEvent event) {
        //どこからリクエストが来たかを検証 // ここの実装を綺麗にしたかったが難しかった。
        FacesContext fContext = event.getFacesContext();
        ExternalContext extContext = fContext.getExternalContext();
        String url = ((HttpServletRequest) extContext.getRequest()).getRequestURL().toString();
        if (!url.contains("PersonBirthDayValidate.xhtml")) {
            return;
        }

        //モデルに値が適用された後(PhaseId.UPDATE_MODEL_VALUES)は、Person に値が代入されているためインジェクト可能
        Person person = instanceOfPerson.get();
        // Execute only PersonClassLevelValidator(Class-Constraint) Validation
        Set<ConstraintViolation<Person>> violations = validFactory.getValidator().validate(person, Default.class);
        //Bean Valiadtion の検証結果
        violations.stream()
                .filter(consts -> consts.getConstraintDescriptor().getAnnotation() instanceof PersonClassLevelValidator)
                .map(violation -> violation.getMessage())
                .findFirst()
                .ifPresent((String errMsg) -> {
                    FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, errMsg, null);
                    fContext.addMessage("ERROR", facesMessage);
                    fContext.validationFailed();
                    fContext.renderResponse(); //SKIP lifecycle
                });
    }

    @Override
    public void beforePhase(PhaseEvent event) {

    }

}

ちなみに、従来の JSF コンポーネントバインドを使った相関チェックのやり方はこんなかんじ

    <f:view>
        <f:metadata>
            <f:viewAction action="#{indexManaged.checkArgument()}" onPostback="true" phase="PROCESS_VALIDATIONS" />
        </f:metadata>
        <h:head>
            <title>Facelet Title</title>
        </h:head>
        <h:body>
            <h:form>
                <h:inputText id="text1" value="#{indexManaged.text1}" binding="#{indexManaged.bindComp1}"/>
                <h:inputText id="text2" value="#{indexManaged.text2}" binding="#{indexManaged.bindComp2}"/>
                <h:messages id="error_message" style="color:red;margin:8px;"/>
                <h:commandButton value="OK" action="#{indexManaged.pushButton()}"/>
            </h:form>
        </h:body>
    </f:view>
package jp.co.oracle.jsf22.multivalidate;

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.component.html.HtmlInputText;

@Named(value = "indexManaged")
@RequestScoped
public class IndexManaged {

    private String text1;
    private String text2;
    private HtmlInputText bindComp1;
    private HtmlInputText bindComp2;    

    /**
     * Creates a new instance of IndexManaged
     */
    public IndexManaged() {
    }

    /**
     * @return the text1
     */
    public String getText1() {
        return text1;
    }

    /**
     * @param text1 the text1 to set
     */
    public void setText1(String text1) {
        this.text1 = text1;
    }

    /**
     * @return the text2
     */
    public String getText2() {
        return text2;
    }

    /**
     * @param text2 the text2 to set
     */
    public void setText2(String text2) {
        this.text2 = text2;
    }

    public String pushButton() {
        return "";
    }

    /**
     * @return the bindComp1
     */
    public HtmlInputText getBindComp1() {
        return bindComp1;
    }

    /**
     * @param bindComp1 the bindComp1 to set
     */
    public void setBindComp1(HtmlInputText bindComp1) {
        this.bindComp1 = bindComp1;
    }

    /**
     * @return the bindComp2
     */
    public HtmlInputText getBindComp2() {
        return bindComp2;
    }

    /**
     * @param bindComp2 the bindComp2 to set
     */
    public void setBindComp2(HtmlInputText bindComp2) {
        this.bindComp2 = bindComp2;
    }
    public void checkArgument() {
        String val1 = bindComp1.getValue() ;
        String val2 = bindComp2.getValue() ;

        if (!val1.equals(val2)){
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "入力内容が不正です。", "テキスト・フィールドに正しい値が入力されていません。");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
}

2015年3月26日 at 1:58 午前

Java Day Tokyo 2015 まであと2週間


(2015年 3月24日時点の状況)

皆様、Java Day Tokyo 2015 まで、あと丁度2週間となりました。満席セッションもかなり多くなってきましたが、今年は会場が広いのでまだまだ魅力的なコンテンツをご選択・ご覧頂く事ができます。今からでもまだお申し込み可能なセッションを下記にご紹介します。(中には残りわずかなセッションも含まれますので)

● Java SE 系の情報を取得されたい方
【1-1】Lambdas and Streams: Taking the Hard Work Out of Bulk Operations in Java SE 8
【1-2】Date & Time API and other technologies of Java SE 8
【3-1】Javaの関数型言語への挑戦/ベターオブジェクト指向言語からの脱皮
【3-2】Java EEアプリケーションサーバの開発現場で見たJava SEの実際
【4-5】Java Flight Recorder のご紹介 (残りわずか)
【5-2】NetBeans IDE最新情報 (残りわずか)

● JavaFX 系の情報を取得されたい方
【6-1】FXML for Structure, CSS for Styling, and JavaFX as Standard GUI Library (残りわずか)

● Java EE 系の情報を取得されたい方
【2-1】Java EE 8 – directions and new features
【2-3】Applied Domain-Driven Design Blue Prints for Java EE 7
【2-4】CDI and EJB – Java EE alignment and strategy
【2-5】Reactive Java EE 7 – Let Me Count the Ways !
【4-1】Javaクラウド・サービスが実現する新しいエンタープライズJava (残りわずか)
【4-2】Oracle Developer Cloud Service, what can you do?

● Java ME/SE Embedded 系の情報を取得されたい方
【1-3】Java SE Embedded 8 / Java ME Embedded 8 Overview
【1-4】Programming the Real World
【1-5】Java and The Internet of Things For Automotive Applications
【7-1】IoT時代のエッジデバイス向け無線モジュールとJavaMEの取り組み
【7-3】Java Embedded で始める IoT

その他
● SDN(Software Defined Networking)
【7-2】OpenDaylightがやってきた!

●初心者向け
【9-1】Say Hello to Java

●Java 認定資格試験受講者向け
【9-5】最新 Java 認定資格ガイド

Java SE 8 や JavaFX、Java EE 7&8 、Embedded などの重要な情報を入手する事が今からでも間に合います。是非、皆様の周りの同僚やお友達、後輩にお声掛け頂けないでしょうか。現在「Java 20周年 盛り上げ大作戦!」を行っています。より多くの方へお誘い頂いた方にはここでしか入手できないレア・グッズをプレゼント予定でございます。

● Java 20周年 盛り上げ大作戦!の詳細はコチラ
◎ https://www.facebook.com/JavaDayTokyo/posts/674620795996755
◎ https://www.facebook.com/JavaDayTokyo/posts/687490008043167

最後に
先日もご案内さし上げましたが、Java Day Tokyo 終了後、東京国際フォーラムの近くで懇親会も実施します。こちらは、Java Day Tokyo に参加されていない方でも、今まで Java に携わられてこられた方や、Java の 20周年を一緒にお祝いしていただける方、どなたでもご参加頂ければたいへん嬉しく思います。

4/8(水) : 20th Anniversary Java コミュニティ・パーティの詳細

あと2週間でございますが、皆様のご参加を心よりお待ち申し上げます。

2015年3月25日 at 11:40 午前

4/8(水) : 20th Anniversary Java コミュニティ・パーティ


既に、JJUG コミュニティのメーリング・リスト等ではご案内を差し上げておりますが、Java Day Tokyo の終了後、東京国際フォーラムの近くで、関係者(外人スピーカー、日本人スピーカーなど)を交えた懇親会を開きたいと思います。すでに、基調講演に登壇頂く Java SE の開発部門の責任者である George Saab さんや Cameron Purdy さん、Stephan Chin さんがくる事が決まっている他、Simon Ritter さん, Sharat Chandar さん Caicedo Angela なども参加すると言って頂いています。もちろん、日本人のご登壇者の皆様も多く参加していただきます。
このように直接、Java 業界で著名な方々と一同を介して交流を持てる機会は多くなく、基調な場になるかと思いますので是非多くの皆様にご参加いただけないでしょうか。

************************************************************************************
日付:2015/4/8
時間:PM 8:30 – 10:30
場所:Alice aqua garden
http://r.gnavi.co.jp/g105302/
参加費: 6,000 円
登録サイト URL:http://javadaytokyonightparty.peatix.com/
************************************************************************************

Java Day Tokyo の余韻もさめぬまま、4/8 (水) はJava 20 周年を祝う日として最後の最後まで盛り上がりませんか?お祝いという事でちょっとした催しも考えています。参加者数に限りがあるため、大変恐れ入りますが参加ご希望の方はどうぞお早めにご登録頂けますよう宜しくお願いします。

あと1ヶ月を切りましたが、皆様と当日お会いできる事を心より楽しみに致しております。
以上、今後ともどうぞ宜しくお願いします。
寺田

2015年3月24日 at 10:57 午前 1件のコメント

日本語 Java SE 8 API ドキュメント URL 変更につきまして

皆様
いつも大変お世話になっております。

現在、Java SE 8 に関連したドキュメントを大幅に更新を掛けております。
http://docs.oracle.com/javase/jp/8/

その過程で、Java SE 8 API ドキュメントへのリンクが下記に変更されました。

旧:http://docs.oracle.com/javase/jp/8/api/
新:http://docs.oracle.com/javase/jp/8/docs/api/

これは、USのオリジナルのドキュメントがディレクトリ構成を変更したためで、USに併せて日本でも今後、上記のURLが正しいURLとなります。つきましては、大変恐れ入りますが、上記に対して現在ブックマークされている場合は改めて御変更いただけませんでしょうか。

また、現在トップページにおいてもいくつかの不具合も確認しております。
http://docs.oracle.com/javase/jp/8/

●リンク切れ
Java チュートリアル・ラーニング・パス
Java言 語および仮想マシン仕様

●リンク間違い(英語サイトへ遷移)
Java SE 8について
新機能(機能および拡張機能)
商用機能アイコン: リンクは新しいウィンドウで開きます
互換性ガイド
既知の問題

●ページ内の画像リンク間違い
Java Platform, Standard Edition HotSpot Virtual Machineガベージ・コレクション・チューニング・ガイド
Java Platform, Standard Editionトラブルシューティング・ガイド
ダウンロー ドとインストールの方法
Java SEツール・リファレンス(UNIX)
Java SEツール・リファレンス(Windows)

上記は、Firefox で見た場合、画像が読み込めないためページの読み込みに非常に時間が掛かります。Chrome ならば、画像リンク切れを無視し表示できます。
上記の3点の不具合は既に認識しており修正中でございますので何れ正しく表示されます。

一方で、繰り返しますが、API ドキュメントに対するディレクトリ構成の変更は US 側で実施されている物であるため、新しいURLで再度ブックマーク等をして頂ければ誠に幸いです。

新しい Java SE 8 日本語 API Doc の URL
http://docs.oracle.com/javase/jp/8/docs/api/

以上、どうぞ宜しくお願いします。
寺田

2015年3月10日 at 5:10 午後

Java Day Tokyo 2015 追加情報

Java Day Tokyo 2015

先日、ご案内させて頂きましたように、4/8(水)に Java Day Tokyo 2015 を東京国際フォーラムで開催致します。

Java Day Tokyo 2015 Offcial Site :
http://www.oracle.co.jp/jdt2015/

既にご登録頂きました皆様におかれましては、ご登録頂きまして誠にありがとうございます。

登録サイトオープン後にセッションが追加されておりますので下記にご案内差し上げます。また今後も追加予定がございますので、セッション情報につきましては定期的にご確認頂ければ誠に幸いです。

※セッションは登録後も変更可能でございますので、必要に応じて登録ページよりセッションをご変更ください。

●15:10-16:00 実践的なJavaアプリケーションサーバの構築・運用~転ばぬ先の杖
山田 貴裕氏 伊藤忠テクノソリューションズ株式会社

●16:15-17:05 アジャイル時代のモデリング
平鍋 健児氏 株式会社チェンジビジョン

最後に
改めまして皆様にお願いがございます。

ご登録者数の状況は昨年、一昨年よりも良好ですが、まだまだより多くの開発者の皆様にご登録頂く事ができます。今年の Java Day Tokyo は、Java の生誕 20 周年を記念して、昨年、一昨年に比べ、規模を大幅に拡大して実施します。そして、このように規模を拡大してイベントを実施できたのも、過去の Java イベントにご参加頂いた皆様のおかげです。

今、ご登録頂いている皆様におかれましては、大変恐れ入りますが是非周りのご友人や後輩にもお声掛け頂き、より多くの Java 開発者の皆様にご参加いただけるように、ご協力頂けませんでしょうか。Java Day Tokyo のオフィシャル・アカウントからも告知がございましたが、より多くの方をご招待頂いた方には、何か良い事があるとの事です。是非、まわりの Java 開発者の皆様にお声掛け頂けませんでしょうか。

オラクルユニバーシティが提供する、Java 初心者用のセッションにもまだ余裕がございますので Java 初心者の方にもどうぞお声掛け頂ければ幸いです。

皆様、お一人お一人のお力をどうぞお貸し頂けないでしょうか。
以上、どうぞ宜しくお願いします。
寺田

2015年3月9日 at 6:47 午後

Java Day Tokyo 2015 登録開始のお知らせ

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Java Day Tokyo 2015 登録開始のお知らせ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
★★★★★★ 2 月 20 日(金) 午後1時より登録開始 ★★★★★★

いつも大変お世話になっております。
すでに告知サイトが公開されているのでご存知の方も
いらっしゃるかと想定しますが、今年も待望の
Java Day Tokyo 2015 を開催する事になりました。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
日時:2015 年 4 月 8 日(水)
場所:東京国際フォーラム
費用:無料
オフィシャル・サイト:
http://www.oracle.co.jp/jdt2015/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

□━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ イベントの概要
□━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

今年は、Java の誕生から 20周年を迎える記念の年で、昨年、一昨年を大幅に超える大規模イベントになりました。この記念すべき年に、今年もオラクル本社から Java業界における多くのキーパーソンを呼びました。

基調講演では本社から Java の開発チームをまとめるGeorges Saab(@gsaab)や Cameron Purdy(@cpurdy)といったエグゼクティブが登壇する他、世界中で活躍する Java エバンジェリスト達、さらにはJava EE 6&7&8 のスペック・リードを務める Linda DeMichiel も約 10 年ぶりの来日が決定しました。

Linda は過去4、5年ほどずっと来日を要望していたため、今回その夢がかない嬉しく思うと共に、この機会により多くの日本の Java エンジニアの皆様と交流を持って欲しいと考えております。Linda は次期バージョンの Java EE について語る他、日本オリジナル・コンテンツも提供します。

さらには、もちろん日本の Java コミュニティからも多数の著名エンジニアの皆様にご協力頂き、朝から夜までより多くの Java 開発者の皆様に楽しんで頂けるのではないかと想定します。

今年はまさに、Java SE 8, Java EE 7 が本格的に普及開始する年です。この Java SE 8 そして Java EE 7 を改めてしっかりと身につけていただくための構成になっています。テクニカル・セッションではどのセッションを受講するか迷う程の内容になっていますので、是非早めにご希望のセッションをご登録ください。

□━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ おたのしみ
□━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

今年の Java Day Tokyo は、本社から新生 Duke もやってまいります。新生 Duke と写真を撮る事ができるブースや、Java Store で Duke 人形なども購入して頂く事ができます。さらには、皆様にはぜひ最後まで楽しみにして頂きたいのですが、夕方から、Java 生誕 20 周年をお祝いする Night Party も企画しています。

今年の Java Day Tokyo 2015 は規模も拡大し、盛大にJava 生誕 20 周年を皆様とお祝いしたいので、より多くの Java 開発者の皆様にお越しいただければ誠に幸いです。

皆様と1日楽しく過ごす事ができる事を楽しみにしております。明日午後1時からの登録開始を楽しみにしてください。
Enjoy with us, Have fun !!

2015年2月19日 at 5:27 午後

Java EE 8 の新機能概要のご紹介

この記事は、「Java EE Advent Calendar 2014」の19日目の記事となります。
昨日は、@nagaseyasuhitoさんの「JPAでマスター/スレーブ構成のMySQLを使うぞ」でした。明日は、@kokuzawa さんのご担当となります。

本エントリでは、今年の JavaOne で発表された、Java EE 8 (JSR-366) の今後の動向についてまとめたいと思います。

本エントリの内容は、JJUG CCC 2014 Fall で発表した内容に追加情報を加えた内容になっています。SlideShare で資料をご覧頂きたい方、もしくは PDF ファイルを入手されたい方は上記スライドをご参照ください。

本エントリの記載内容は、2014年12月時点での内容ですので、下記に記載する内容は今後大幅に変更する可能性もあることをどうぞご理解の上でご覧下さい。


まず、Java EE 8 のリリースに伴い、Java EE のスペックリードは本当に必要とされる技術が何なのかを改めて考えてみました。その際、業界のトレンドを観察し必要な技術は何なのかを検討したり、また Java の技術者の皆様にアンケートをとり、実際に技術者の皆様から求められている機能はどのような内容なのかも確認しました。アンケートの結果、JSON Binding, Security, JCache, Action ベース MVC 等が上位に占められていました。

こうして検討を重ねた結果、次の Java EE 8 のテーマを決めました。Java EE 8 では3つのテーマを元に機能提供を検討しています。

● HTML5
 + JSON Binding : JSR-367
 + JSON-P : JSR-374
 + Server-Sent Events : JSR は未定(JAX-RS,Servlet, WebSocket の何れか)
 + Action Base MVC : JSR-371
 + HTTP/2 のサポート(Servlet 4.0) : JSR-369
 + WebSocket の改善

● かんたん開発
 + CDI の適用範囲の拡大 : JSR-365
 + セキュリティ・インターセプタ
 + 仕様の削減

● クラウド環境への対応
 + Java EE Management 2.0 : JSR-373
 + Java™ EE Security API 1.0 : JSR-375

最新の Web 系の技術トレンドに対応するために、HTTP/2 への対応を Servlet 4.0 内で行うほか、Server-Sent Events の標準化、新しい Action ベースの MVC 等の導入も検討しています。また Java EE 5 以降、6,7 と継続してかんたん開発のテーマに取り組んでいますが、これは Java EE 8 でも継続します。例えば CDI の適用範囲をひろげ Java SE 環境でも CDI を利用できるようにします。さらにクラウド対応という点では、今まで Java EE アプリケーションを監視する際に使用していた、管理・監視用の JMX を改め、JAX-RS による監視を可能にする他、今までアプリケーション・サーバ毎に個別設定していた認証・認可の設定・実装(レルム)を標準化し、より簡単にユーザ管理のアプリケーションを実装できるようにします。これらの各種技術概要を見るだけでも Java EE 8 が待ち遠しくなりますが、それぞれの検討内容を下記にまとめて紹介します。

HTML 5 への対応として、ここに列挙する内容が検討されています。これらを順に説明します。

JSON Binding : JSR-367
JSON Binding は JSON と Java オブジェクトをマッピングし相互変換を簡単に実現するための機能です。

今までも、XML を利用する場合には、JAX-B を利用したり、データベースのテーブルと Java オブジェクトをマッピングするために、JPA を利用してきましたが、JSON-B はこれらと類似の方法で JSON と Java オブジェクトをマッピングできるようになります。またこれを実装する事によって JPA の Entity を使用したデータベース・テーブルから JSONへの相互変換や、JAXB を使用した XML と JSON への相互変換も容易になります。
JSON-B は JSON の Java へのマッピングにおいてできるだけ実装コードを少なくするため、Configuration by Exception のルールに乗っ取り標準でデフォルトのマッピング・ルールが提供されます。またクラスの継承も可能です。このデフォルトのルールに従う場合は、Java を簡単に JSON に変換できます。そしてもちろん、デフォルトのルールをカスタマイズしたい場合には、専用のアノテーションを付加する事でデフォルト・ルールを上書きする事もできます。
また、Java EE 7 で導入された JSON-Processing との連携も容易にできます。

JSON-B の参照実装は、Eclipse link MOXy で開発が進められています。


それでは、実際に Java と JSON のバインディングについて見ていきましょう。ここでは、Employee というクラスに、インスタンス変数、id, firstName, lastName, email が定義されており、Employee クラスのインスタンス (e) を生成した後、それぞれに値を代入しています。この Java オブジェクトを JSON で扱う場合、デフォルトのルールに従うとインスタンス変数名が、JSON の KEY になり、変数に代入された値が JSON の value として代入されます。

また、JAX-B をご利用した事のある方であれば、用語の説明は不要かと想定しますが、Java から JSON への変換を Marshal (マーシャル) といい、逆に JSON から Java への復元の事を Unmarshal (アンマーシャル) といいます。


Marshal (JavaからJSONへの変換), Unmarshal (JSONからJavaへの変換) を行うために、まず JsonContext オブジェクトのインスタンスを生成します。JsonContext のインスタンスを生成するためには、デフォルトで用意されているファクトリ・メソッド JsonContext#newInstance() を利用する事ができます。また下記のように JsonContextBuilder を通じてインスタンスを生成する事もできます。

JsonContext context = new JsonContextBuilder()
                  .setScope (MyClass.class, ...)
                  .excludeField(“field”, MyClass.class)
                  .addFilter(myContextFilterImplementation)
                  .build();

生成した JsonContext のインスタンスから、それぞれ createMarshaller() で Marshaller オブジェクトを、createUnmarshaller() で Unmarshaller のオブジェクトを生成します。


一旦、Marshaller オブジェクトを生成すると、変換したいオブジェクトを marshall() メソッドの引数に渡す事で簡単に JSON を含む String オブジェクトを取得したり、Writer として取り出す事もできます。


同様に、unmarshaller() メソッドの引数に JSON を含む String 、もしくは Reader から Java オブジェクトを渡す事で簡単に Java オブジェクトに復元する事もできます。


今まで JsonContext から Marshaller や Unmarshaller を生成し各処理を行う方法を紹介しましたが、よりかんたんに直接相互変換を行うためのユーティリティ・クラス Jsonb の作成も検討中です。Jsonb のメソッドを利用すると直接、marshal, unmarshal を実行する事もできるようになります。


JSON-B ではプリミティブ型や、参照型に対するデフォルトのマッピングルールを提供します。しかし、デフォルトのルールに従わず独自にカスタマイズしたい場合には、下記のようなアノテーションを付加しカスタマイズする事もできます。


例えば、デフォルトのルールに従うと、Java クラス中のインスタンス変数名は、JSON のキーに同一の名でマッピングされます。しかし、Java クラス中のインスタンス変数名と、キー名を変更したい場合は、@JsonPropertyアノテーションを付加して変更する事ができます。


また、Java のクラス中に含まれる特定のインスタンス変数を JSON にマッピングさせたくない場合、@JsonTransient アノテーションを付加し無効化する事ができます。


さらに、JSON ドキュメント中のキーの記載順に意味があるような場合、デフォルトでは Java クラスのインスタンス変数の記載順にマッピングされますが、その順番を変更するために、@JsonPropertyOrder アノテーションを付加し引数内に順番を指定する事ができます。


JSON-B では継承やポリモーフィズムにも対応予定で、また Marshal の前後、もしくは Unmarshal の前後に処理をインターセプトして何らかの処理を付け加えて実行したい場合に、それらを実現するための API (JsonPre***, JsonPost***) も用意しています。


JSON-Processing は Java EE 7 に JSR-353 として導入されました。JSON-P は Stream を利用して JSON の解析、生成を行うための低レベル API を提供し、XML における StAX や DOM のような機能を提供しています。
Java EE 8 では Java EE 7 で提供されている機能に加え、JSON の標準仕様に準拠した最新機能 (JSON ポインタや JSON パッチ) にも対応します。


まず、JSON ポインタについてご紹介します。


JSON ポインタは IETF RFC 6901 : JavaScript Object Notation (JSON) Pointer で定義される仕様で、JSON ドキュメント内に存在する特定の値を参照するための構文です。


たとえば、この例をご覧ください。この例では JSON 配列の中に、2つの JSON オブジェクト(名前が Duke と Jane)があります。そして人に関する情報(名前、性別、電話番号)が JSON オブジェクトとして記載されています。それではこの中から携帯電話の電話番号 (650-234-5678) を取得するにはどうすればよいでしょうか。JSON ポインタを利用すると、”/何番目/phones/mobile” といった形式で一意に値を取得する事ができるようになります。例では “0/phones/mobile” と 0 番目を指定する事で値を取得しています。


それでは、Java で JSON ポインタを扱うためにはどのようにすれば宜しいでしょうか。まず、先ほどの JSON ドキュメント(名前が Duke と Jane)が JsonArray のインスタンス contacts として表されている事とします。 この時、Json クラスのクラスメソッド createPointer() の引数に、参照したい JSON 値への参照パス(“/0/phones/mobile”)を渡し、JsonPointer のインスタンスを生成します。ポインタの getValue() を実行する事で JsonValue を取得する事ができます。またポインタに対して、replace を実行する事で、指定した参照の値を変更した結果の JsonArray を取得する事ができます(※ オリジナルを直接書き換えるわけではない)。


JsonPointer クラスには、ここで示すように様々なメソッドが用意されています。しかし、ここで1点注意をしなければならない事があります、add, replace, remove 等のメソッドは直接オリジナルの JSON ドキュメントに対する変更を行うわけではないという点です。JsonObject や JsonArray はイミュータブル(不変)のデータなので、直接それを変更するわけではなく、変更した後に新しい JsonArray や JsonObject を生成するという点に気を付けてください。オリジナルの JSON ドキュメントを編集したい場合は、JsonPointer ではなく、次に紹介する JsonPatch を利用します。


続いて、JSON パッチについて紹介します。
JSON パッチは、IETF RFC 6902 : JavaScript Object Notation (JSON) Patchで定義される仕様で、特定の JSON ドキュメントに対して行う操作(追加、変更、削除等)内容が記載された JSON のドキュメントのフォーマットです。JSON パッチのドキュメントは、op (add,replace,remove 等) と path (JSON ポインタ)が必須で、それ以外は必要に応じて追加できます。また、MIME タイプ “appliaction/json-patch+json” を指定し、HTTP の PATCH メソッドを利用できます。

※ JsonArray や JsonOBject はイミュータブル(不変)なオブジェクトなので、直接変更を加える事ができません。そこでオリジナルの JSON ドキュメントに対して、変更(追加、変更、削除など)を加えたい場合、新たに処理内容を記載した JSON ドキュメントを作成し、指定したドキュメントに対して操作を行う事ができるようになります。

下記に HTTP の PATCH メソッドの利用例をご紹介します。


PATCH /my/data HTTP/1.1
Host: example.org
Content-Length: 326
Content-Type: application/json-patch+json
If-Match: “abc123”

[
    { “op”: “test”, “path”: “/a/b/c”, “value”: “foo” },
    { “op”: “remove”, “path”: “/a/b/c” },
    { “op”: “add”, “path”: “/a/b/c”, “value”: [ “foo”, “bar” ] },
    { “op”: “replace”, “path”: “/a/b/c”, “value”: 42 },
    { “op”: “move”, “from”: “/a/b/c”, “path”: “/a/b/d” },
    { “op”: “copy”, “from”: “/a/b/d”, “path”: “/a/b/e” }
]


それでは、実際に JSON パッチのドキュメント記載方法と利用方法について説明します。まず、左側に示す、”mobile”:”650-234-5678″ の電話番号を (“650-111-2222”) に変更する場合を考えてみましょう。変更するために処理内容を記載した、JSON パッチのドキュメントを生成しますが、先ほど説明したように、op と path は必須です。ここでは既存の値を変更したいので、op には “replace” を指定します。また変更対象の値は、JSON ポインタで “/0/phones/mobile” と表す事ができますので、path にこの値を記載します。最後に value に変更後の値を指定する事で、電話番号を変更するための JSON パッチのドキュメントができあがりました。


また次に既存の JSON ドキュメントから要素を削除する例を確認してみましょう。この例では、0 番目を全部削除する場合を考えます。削除するために、JSON パッチのドキュメントを生成しますが、先ほどと同様 op と path は必須で、それぞれ remove と JSON ポインタで対象を指定します。


さて、基本的な JSON パッチの概念が理解できましたので、Java でどのようにしてパッチを扱うかについてご紹介します。オリジナルの JSON のドキュメントが JsonArray の target に代入されている事とします。また JSON パッチの記載内容が JsonArray の patch に代入されている事とします。Json クラスのクラス・メソッド createPatch(patch) を実行し、JsonPatch のオブジェクトを取得します。そして JsonPatch の apply メソッドをターゲットに対して実行します。このようにとても簡単にパッチを適用できます。


最後に、JSON クエリに対する Lambda & Stream API の適用についてご紹介します。JSON-P で提供される API の javax.json.JsonObject, javax.json.JsonArray はそれぞれ、java.util.Map, java.util.List インタフェースを実装したクラスです。そして、Map や List は Java SE 8 で導入された Lambda 式や Stream API を利用してバルク(一括)操作を行う事ができるようになります。具体的には、JSON ドキュメント中のデータのフィルタリングや変更(マッピング)などのバルク(一括)処理ができるようになります。下記に Java SE 8 の Lambda 式や Stream API を使用して JSON データに含まれるデータの抽出を行う例を紹介します。


Stream を取得するために、JsonObject, JsonArray で getValuesAs(JsonObject.class).stream() を実行します。一旦 Stream のインスタンスを取得した後は、java.util.stream.Stream で提供される filter や map といった中間操作用のメソッド、collect といった終端操作用のメソッドを、通常の Stream API と同様実行する事ができます。この例では、filter メソッド内で、性別が女性の方をフィルタリングし、 JsonObject として抽出しています、次に map メソッドで、抽出した JsonObject 中から、女性の名前を getString(“name”) で取得し、結果として String のストリームを返しています。最後に collect メソッド内で、結果を List として返しています。つまり List<String> femaleNames には女性の名前の一覧が代入されてます。

Lambda 式と Stream API を利用して JSON ドキュメントのデータの抽出等がかんたんにできる事が分かりました。しかし、Stream API の終端操作 Collectors で標準に提供する機能では、配列やリストなどへの変換しかできません。Stream API を利用して任意の中間操作を行った後、最終的に終端操作で直接、JsonObject や JsonArray のオブジェクトを取得できるとさらに有用です。そこで、Java EE 8 では java.util.stream.Collectors クラスを拡張した JsonCollectors を新たに提供する予定です。JsonCollectors では最終的に JsonObject や JsonArray を取得するためのメソッドを追加したり、groupingBy メソッドで結果のグルーピングをおこなうためのメソッドも提供する予定です。


具体的に JsonCollectors の利用例を紹介します。先ほどの例では collect で List を返していましたが、その代わりに collect で JsonCorrectors.toJsonArray() を指定する事で、結果 JsonArray オブジェクトとして結果を取得する事ができます。


最後に、今までご紹介してきた、JSON ポインタ、JSON パッチ、Lambda 式 & Stream API を使用して、オリジナルの JSON ドキュメントに対して一気に変更を加える例を紹介します。ここでは、電話番号のエリアコード(地域識別番号)で 415 を含むデータのみを抽出し、そのエリアコードを 415 から 650 に一括変更するための処理を記載します。まず、Stream を取得した後、filter メソッドで電話番号のエリアコードが 415 を含む JSONObject の Stream を取得します。次に、map メソッドで エリアコードの部分を 415 から 650 に変換するための JSON パッチを動的に生成し、生成した JsonObject の Stream を返します。最後に collect メソッドで、条件に一致する全ての変更用のパッチを含む JsonArray を生成し返します。パッチ用の JSON ドキュメント生成後、オリジナルの JSON ドキュメント(contacts) に対して、Json.createPatch(patch).apply(contacts) でパッチを適用する事で結果を取得しています。
このように、Lambda 式 & Stream API を利用する事で、より簡単にパッチの適用ができるようになります。

JSON-B に関する詳細は下記 JavaOne の発表資料「Java API for JSON Binding
Introduction and update
」もご参照ください。

ここでご紹介した API に関して、ご意見、ご要望がある場合は、メーリングリスト、JIRA などでお問い合わせください。
https://java.net/projects/jsonb-spec/
https://java.net/jira/browse/JSONB_SPEC/

続いて、Server-Sent Events (以降 SSE) について説明します。


歴史を少し振り返ると、サーバ側で発生するイベントをリアルタイムに通知するための仕組みは、今まで Ajax を使った Polling, Comet(Long Polling,Streaming), WebSocket が利用できました。Polling や Comet は、パフォーマンスが非常に悪く、大量のリクエストを捌くサービスを提供する事が困難でした。WebSocket はハイ・スケーラブルで双方向通信を実現できますが、専用のプロトコルを利用するため、これをサポートするクライアント、サーバ、さらに HTTP プロキシ等が必要でした。一方で SSE は純粋な HTTP を使用し、サーバ側からクライアントに対する一方向へのメッセージ通知としては利用できます。双方向通信ではなく、サーバからの一方向通信でよい場合、SSE は有用です。

SSE は、現在 W3C で仕様がドラフトとしてまとめられています。
http://www.w3.org/TR/eventsource/

SSE は、クライアントからサーバに接続しコネクションが確立した後は、サーバからクライアントに対して一方向でデータを送信します。この際、サーバ側で発生するイベントに応じて、何度も同一コネクションを利用してデータ転送する事ができます。MIME タイプとして専用のメディア・タイプ “text/event-stream” を利用します。SSE はクライアントがサーバに対してサブスクライブ(購読)要求をだして、サーバがサブスクライブしているクライアントに対してパブリッシュ(配信)するという点で JMS のパブリッシュ・サブスクライブのモデルに似ています。


現在、Java EE 上で SSE の実装を検討中ですが、どのレイヤーで実装するかを今まさに議論中です。具体的には Servlet 上、WebSocket 上、JAX-RS 上、もしくは独自のコンテナ上で実装する案があがっており、これらを検討中です。

検討案の説明資料:

クリックしてSSE-in-EE8.pdfにアクセス

上記をエキスパート・グループメンバーに問い合わせ中ですが、現在、スペックリードとしては JAX-RS が一番適切ではないかと考えています。なぜならば、JAX-RS で既に HTTP のリソースに対するストリーミングをサポートしており小さな変更ですむためです。

● 小さな変更で実現
  例えば、JAX-RS でサーバ、クライアントにそれぞれ下記の API を追加します
  サーバの API として : EventOutput に対し新しいメディアタイプを追加
  クライアントの API として:Server側のイベントに対する新しいハンドラを追加
● 他のHTTPの操作と組み合わせる際に便利:新しいメディアタイプ
● Jersey(JAX-RS RI)は既に SSE をサポート済み
Jersey を利用した実装例はコチラ

JavaOne で発表された、次の JAX-RS で組み込む機能紹介の概要は下記よりご参照ください。
Let’s Talk JAX-RS.next! JSR-370 – What to expect in JAX-RS in Java EE 8

また、JAX-RS の参照実装 Jersey で既に実現している SSE の実装方法については下記をご参照ください。
Chapter 14. Server-Sent Events (SSE) Support


オリジナルの資料では Java EE 7 から導入された Concurrency Utilities for EE を使って説明されていなかったため、Concurrency Utilities for EE を使って書き直したコードを下記に記載します。ここでは、ManagedExecutorService を @Resource アノテーションでインジェクトした後、別スレッドで SSE のイベント通知を行っています。別スレッドの処理内容の例は、StockThread に記載しています。実際に SSE でメッセージ通知は EventOutput#send()メソッドで行っています。

また、SSE ではクライアント用の API も用意しています。これにより、JavaFX 等のスタンドアローン・アプリケーションでも SSE クライアントを実装し、SSE のサーバ・サイドからの通知を受信して何らかの別処理を行う事ができます。


次に、Action ベースの新しい MVC フレームワークについて紹介します。
Java EE 7 まで Web アプリケーションの開発を行う際、JavaServer Faces(以降 JSF), もしくは JAX-RS を利用できました。この中で JSF はコンポーネント・ベースの MVC フレームワークとして Java EE 5 以降標準の Web 開発フレームワークとして導入されています。一方、アクション・ベースの MVC フレームワークも世の中には多く存在します。例えば Struts や SpringMVC 等がこれに当てはまります。

Java EE の開発者にアンケートを実施した所「アクション・ベースの MVC は改めて必要でしょうか?」という質問に対し、約 6 割の方々が ハイと答えました。またその際、アクション・ベースのMVC を実装するために、「参考にすべき技術(デファクト・スタンダードな技術)はありますか?」と質問した所、75% の開発者は分からない、もしくは存在しないと答えました。

当初、JAX-RS のエキスパート・グループ・メンバーを中心に新しいアクション・ベースの MVC について議論を行いましたが、様々な議論を行った結果、JAX-RS とは別途、検討・実装した方がよいという結論になり、グループを再編し、スタンドアローンのAPI として、新しく JSR 371: Model-View-Controller (MVC 1.0) Specification として仕様策定を進めています。

※ 現在まさに仕様を検討中ですので、下記に紹介する内容は今後大きく変更する可能性があります。その点をどうぞご注意ください。


まず、MVC の各構成にどのような技術を適用するかを紹介します。アンケートの結果、参考にすべきアクション・ベース MVC が無い、もしくは分からないというご意見が多数あったため、既存の資産を有効活用するため Java EE で現在提供されている機能を組み合わせて、それらをつなぎ合わせて実装できるような MVC フレームワークを検討中です。Movel には CDI, Bean Validation, JPA 等を View は Facelets, JSP, 任意のテンプレート・エンジン(プラグイン可能なテンプレートエンジンが入れられると望ましい)等が予定されています。

一方で、現時点でまだ Controller 部分の実装が決まっていません。スペックリードが現在(10/29 から)この新しい MVC フレームワークのコントローラ部分をどのような環境で提供すべきかアンケートも実施しています。
https://java.net/projects/mvc-spec/lists/users/archive/2014-10/message/68

(A) Layer MVC on top of the Servlet API: define new set of annotations, new URI mapping algorithm and new data binding layer for controllers. This option implies no MVC + REST controllers, at least not in a elegant manner (see example on e-mail thread).

(B) Layer MVC on top of the JAX-RS API: reuse existing set of JAX-RS annotations, URI mapping algorithm and data binding layer for controllers. This option implies that MVC + REST controllers will be possible, but also that our runtime will depend on the JAX-RS runtime.

メーリングリストでの回答の多くは、(A) の Servlet API 上に Controller 実装を希望している方が多く見られるようです。一方、Oracle (Santiago) としては (B) に投票予定のようです。

(3) Oracle’s Vote: We have been busy writing some prototypes and evaluating
MVC frameworks for the last few weeks. We are not taking this decision
lightly as it obviously has a great impact on future work. Our main concern
has always been familiarity of existing APIs and duplication of work,
especially around matching (routing) and binding. These are the list of
annotations that JAX-RS defines for this:

* Matching: ApplicationPath, Consumes, Produces, GET, PUT, POST, DELETE,
HEAD, OPTIONS, Path, HttpMethod

* Binding: BeanParam, CookieParam, DefaultValue, Encoded, FormParam,
HeaderParam, MatrixParam, PathParam, QueryParam, Cookie, Form

And this is just annotations, no matching and binding semantics, etc.
This fact, together with the existence of several MVC frameworks built on top
of JAX-RS, has led us to the conclusion that JAX-RS is right technology for
MVC to be layered on. Thus, Oracle votes for option (B).

下記に JavaOne 発表時のサンプル・コードを示しますが、上記の投票結果や今後の進捗によって今後大きく変更される可能性があります。






上記では、JSP や Facelets で <form action=”/rough-example/form1a.jsp”> を記載し、ページ内に EL 式を用いてデータ・バインディングができるようになっています。またサーバ側では、クライアントのリクエストに対応する処理を @Path を付加したメソッド内で記述し、メソッドの戻り値として画面遷移先を返しています。

Java EE におけるアクション・ベースの MVC フレームワークのプロジェクトはまだ始まったばかりです。ご興味のある方は是非、java.net に存在するプロジェクトやメーリング・リストにご参加ください。

JSR 371: Model-View-Controller (MVC 1.0) Specification
The MVC specification project : java.net


HTML 5 関連で最後に、HTTP/2 対応についてご紹介します。
HTTP/2 は Internet Engineering Task Force(IETF)の Hypertext Transfer Protocol Bis (HTTPbis)のワーキング・グループで標準化が進められている、次バージョンの HTTP プロトコルです(現在はまだドラフト)。HTTP/2 の特徴として下記のような物があげられます。

* レイテンシを軽減
* Head of Line Blocking 問題の対応
* 並列処理のサポート(複数コネクションは不要)
* HTTP 1.1 の意味は保持
* HTTP 1.x との連携を定義

Java EE で HTTP/2 に対応するために、JSR 369: Java™ Servlet 4.0 Specification で対応を行います。Servlet API は、HTTP/1.x に対応していたため、単一リクエストに対し単一レスポンスを返すアーキテクチャになってました。この問題点として、例えば、同一クライアントからサーバに対して大量の HTTP リクエストを行うような場合、特定のリクエストで処理時間を多く要した場合、後続の処理が待ち状態になり全体としてパフォーマンスが低下する場合がありました。しかし HTTP/2 ではよりデータ転送の効率化をはかるために、単一コネクションで、リクエストとレスポンスを多重化できるようになります。これにより、例え一つのリクエスト処理に時間を要しても後続の処理に影響が発生しにくくなるため、より効率的なデータ転送を行う事ができるようになります。

Servlet 4.0 における変更点の詳細は下記に記載していますので、下記をご覧ください。

また、JSF 2.3 における変更点は下記ごご覧ください。


続いて、「かんたん開発」の分野における Java EE 8 の拡張ポイントについて説明します。まず、CDI の適用範囲が大幅に広がります。

CDI は Java EE 6 で導入され、Java EE 7 まで、Java EE のコンテナ、つまりアプリケーション・サーバ上で利用されてきました。実際、CDI の仕様である JSR 299 は Contexts and Dependency Injection for the Java™ EE platform として記載されていました。しかし Java EE 8 からは、JSR 365 として Contexts and Dependency Injection for Java™ 2.0 に名前を変え、CDI の適用範囲を Java EE 外にもひろげ、Java SE 環境でも利用できるようにします。これにより、EJB の組み込み可能コンテナと同様に、JUnit のテストコード等でも CDI を利用できるようになります。

Java EE 8 に含まれる CDI 2.0 では、大きな機能拡張としてここにあげる3つの機能があります。

また、上記以外にも下記のような機能拡張も予定されています。

● イベント処理の拡張
● インターセプター・デコレータの仕様への対応
● SPI の拡張
● コンテキストの拡張
● Java 8 機能への対応(タイプ・アノテーション、アノテーションのくり返し、Lambda, Stream, デフォルト・メソッド、型推論)

詳しくはWorking method for CDI 2.0をご参照ください。


まず、Java SE 環境で利用可能にするために、CDI を Java SE 環境で起動するための Bootstrap 用 API が提供されます。

CDI 2.0 first Face to face meeting feedback によると、下記のようなクラスの提供を検討しているようです(まだ議論中との事)。上記会議での議論の内容は CDI 2.0 の新機能を理解する上で重要ですのでご興味のある方はどうぞご覧ください。

public class ContainerBoot {

    /**
     * Simple boot
     */
    static BeanManager initialize() {
      ...
    }

    /**
     * Boot with parameters
     */
    static BeanManager intialize(Map&lt;?,?&gt;) {
      ...
    }
    void shutdown() {}
}

つづいて、モジュール化について説明します。CDI は Java EE 6 における標準化以降、Java EE において非常に重要な機能になっています。そして、EJB 等で培ってきた経験を元に、EJB が持つ機能も多く CDI に取り込まれて利用できるようになってきており、この方向性は今後も引き続き継続されそうです。この中で CDI が機能を持てば持つ程、CDI 自身が大きく、重量になる事も懸念されてます。そこで、CDI 自身を引き続き継続して軽量に扱う事ができるように、CDI 自身のモジュール化を検討しています。

上記では①、②、③と示しましたが、実際にはより細かく検討されています。

A. 単純な DI の機能
B. Observer パターンを利用した CDI によるイベント管理機能
C. 対象型の発見方法の拡張
デプロイしたアプリケーションの起動時に型検査を行う
D. (A+B+C+AOP:インターセプタ、デコレータ)
E. D+コンテキスト管理

詳細は CDI 2.0 modularity proposal をご覧ください

また、EJB の MDB に変わり、CDI でも非同期メッセージを受信するための新しい API も検討中です。現在の MDB の実装は、たくさんの設定が必要で MessageListener を implements したクラスの実装も必要でした。
今回、JMS をさらに簡単に利用でき、任意の CDI に対して利用ができるようにします。また、MessageListener を implements したクラスの実装も不要で、直接メソッドに @JMSListener のアノテーションを付加し、監視する Queue を destinationLookup で指定し実装できるようになります。

また、Java EE 7 までの MDB と同等の振る舞いを実装するためには、該当の CDI に対して @Singleton アノテーションを付加する事で MDB と同等の振る舞いを実現できます、また @Transactional アノテーションを付加する事でコンテナ管理のトランザクションも正しく動作します。ここに記載したコード例のように既存の MDB の実装に比べより簡単に実装できるようになります。


Java EE 7 まで提供されてきた認可(Authorization)用のアノテーションとして、@RolesAllowed や @RunAs といったアノテーションが存在しました。これらのアノテーションは多くの利用場面に有用でした。しかしより複雑な認可処理が必要な場合、別途、認可用のプログラミングを実装するか、もしくは新しく CDI のインターセプタを実装する必要がありました。また認可用のアノテーションを実装する際に、EL 式が評価できるようになる事でより多くのユースケースにかんたんに対応できるようになります。

今回、ロールに基づく認可の他、Java EE のコンテキスト情報にもアクセスし、コンテキスト情報から認可情報(プリンシパル名、ロールチェック、認可チェック)を取得する事も可能な新しいアノテーションを、CDI のインターセプタとして実装する予定です。

詳細は、JIRA に登録されている JAVAEE_SPEC-29 : EL-Enabled Authorization Annotation をご覧ください。

また、上記以外にも、CDI との連携をより強化するために、様々な場所でクリーン・アップを行います。例えば、WebSocket の実装においても CDI のスコープを利用できるようにしていますが、このように CDI が他の仕様でも幅広く利用されている事がわかります。

WebSocket の拡張に関しては下記の Slide もご参照ください。


また、Java EE 8 では Pruning (剪定:仕様の削減) 候補として EJB 2.x のリモート、およびローカルのクライアント・ビュー(EJBObject, EJBLocalObject, EJBHome, EJBLocalHome インタフェース)があげられています。さらに CORBA : (Prune CORBA interoperability) もあげられています。理由として昨今 SOAP や REST で通信を行う事が多く CORBA の利用場面が大幅に減ってきているためです。現在これらを用いて実装している場合は、アップデートをご検討ください。


最後に、Java EE プラットフォームの近代化(クラウド環境への対応)を行うための機能を紹介します。


まず、Java EE Management & Deployment API について説明します。
JSR 77: J2EE™ Management という JSR において、Java EE のプラットフォームで提供される管理オブジェクトを定義していました。これらの管理オブジェクトの各インスタンスは、構造化された OBJECT_ID で識別され、管理オブジェクトは追加機能を提供するために、コンテナ側で下記インタフェースを実装する事もできました。そして、これらの管理オブジェクトは、JConsole 等のツールを利用して管理、監視を行ったり、独自に管理・監視機能実装してアプリケーション全体の運用管理を行う事ができました。

EventProvider : 設定イベントの通知 : GlassFish 実装
StatisticsProvider:統計情報採取 : GlassFish 実装
StateManageable:状態管理(基本的なライフサイクル) : GlassFish 実装

今回提案する仕様では、現在の実装方法に代わり、REST インタフェースで管理可能な、管理オブジェクトを定義する事を目的としています。これにより、既存の HTTP のツールやライブラリを用いてかんたんに Java EE アプリケーションの管理ができるようになります。またこれにあわせ、エキスパート・グループ・メンバーは、既存の Management EJB の API や JMX API をオプションにするべきかどうかも検討中です。これは仕様をかんたんにするためという理由だけではなく、今回提案する REST インタフェースをより積極的に採用していただくためです。

新しい REST インタフェースは、既存で提供している OBJECT_NAME を URL に変換し、また個々の管理オブジェクトに対する CRUD 操作も可能です。EventProvider のイベント通知に Server-Sent Events もサポートする予定で(WebSocket も検討中だが、対応ツール(HTTPのアップグレードは不要)リアルタイムで監視する事ができるようになります。

また、JSR 88: Java™ EE Application Deployment という JSR において、デプロイ・ツール用のインタフェースが定義されていました。そしてこれに準拠したデプロイ・ツールから、個々のアプリケーション・サーバに対して直接アプリケーションをインストールする事ができました。JSR 88 のサポートは Java EE 7 からオプション化されています。

デプロイ用の API も上記、REST インタフェース内に取り込む予定です。このインタフェースを利用する事で、アプリケーション・サーバのインスタンスに対して、REST インタフェースを通じて直接アプリケーションをインストールする事ができるようになります。その際、依存するリソース定義や管理も REST インタフェースを通じてできるようになります。


次にセキュリティについて説明します。現在、セキュリティの設定・実装に関する多くがアプリケーション・サーバ固有設定になっており、これにより移植性が大きく損なわれていました。今回、これらサーバ独自の設定を排除し標準化する事で、クラウド環境でより柔軟に移植性の高いアプリケーションの構築が可能になります。
これらは、JSR 375: Java™ EE Security API で検討中です。

まず、パスワード・エイリアスを導入します。これまで、アプリケーション・サーバからデータベースや、LDAP 等の外部リソースへの接続するためには、サーバ側の設定でユーザ名、パスワードを設定していました。所がこのユーザ名、パスワード管理はアプリケーション・サーバ固有で、一部のアプリケーション・サーバでは生のパスワードを記載しなければならない場合もありました。データベースや LDAP への接続用のユーザ名やパスワードを生の形で見えるようにしておくのは非常に危険です。そこで、生パスワードを記入しなくてもよい標準の方法を提供します。

@DataSourceDefinition{
  name=“java:app/MyDataSource”,
  className=“com.example.MyDataSource”,
  …
  user=“duke”,
  password=“${ALIAS=dukePassword}”)

上記の構文は、現在 Java EE の参照実装 GlassFish で採用されているパスワード・エイリアスの指定方法で、標準化にあたりこれをベースにしていますが、パスワードの値には、実パスワードを参照するためのエイリアス(仮の名前)が設定されており、実行環境が必要に応じてエイリアスから元の実パスワードを参照するようになっています。

ご参照:Password Aliasing for EE 7

続いてユーザ管理について説明します。Java EE 7 までユーザ管理(認証・認可)を扱うアプリケーションの実装は、各アプリケーション・サーバ・ベンダーに依存していました。つまり統一的なユーザ管理用の API も用意されていなかったため、概念は共有できても実装コードは個別に行う必要がありました。以前、GlassFish v4 で始める Java EE JDBC レルム ハンズオン・ラボ として GlassFish 上で Java EE6/7 利用者向けのハンズオン・ラボを公開しましたが、ここで記載した内容は他のコンテナではそのままでは利用できません。そこで、このようなユーザ管理を行うアプリケーションを作成する際の、標準化を行い移植性の高いアプリケーションを構築するため、ユーザ管理機能の標準化が行われます。
この仕様もまた、JSR 375: Java™ EE Security API 内で行われています。また、JIRA に登録されている JAVAEE_SPEC-9 : Simplify and standardize authentication & role mapping もご参照ください。



ユーザ管理を行うために、3つのコア・クラスを提供します。これらを順に紹介します。

● UserSourceDefinition:データ・ソース(DB, LDAP, ファイルなど)を定義
● UserService:ユーザの管理(追加、変更、削除など)機能を定義
● UserInfo:ユーザ情報の定義(ユーザ名、パスワード、有効期限など)

UserSource(DB, LDAP, ファイル、その他)のリソース中に含まれるユーザ、グループを UserService で処理し、個々のユーザは UserInfo として管理され、ユーザ名、パスワードだけでなく、有効期限や、アカウントのロック状態なども管理ができるようになります。

具体的に、LDAP からユーザ、パスワードを参照するアプリケーションを作成する例をここで紹介します。@LdapUserSourceDefinition というアノテーションを付加し、ユーザ情報が含まれる LDAP ディレクトリをしていします。またこれを利用する為には、@Resource アノテーションを付加し UserService をインジェクトしています。UserService のインスタンスを取得した後は、下記に示すメソッド(現時点での仮案)を利用してユーザ管理、グループ管理を行う事ができるようになります。


+ UserInfo:loadUserByUsername(username)
+ changePassword
+ createUser
+ deleteUser
+ updateUser
+ userExists
+ createGroup
+ addUserToGroup
+ removeUserFromGroup
+ isUserInGroup

また、UserInfo のインスタンスは下記のフィールドを持ち、ユーザ自身の管理も標準で用意にできるようになります。

+ Username
+ Password
+ AccountExpired
+ AccountLocked
+ PasswordExpired
+ Enabled
+ Attributes


続いて、ロール・マッピングについて説明します。ロール・マッピングもユーザ管理同様、アプリケーション・サーバ固有に設定・実装が必要でした。ロールマッピングの実装もまた標準化を行います。

ロール管理を行うために、2つのコア・クラスを提供します。これらを順に紹介します。

● RoleMapper:ロール情報が保存されるデータ・ソース(DB, LDAP, ファイルなど)を定義
● RoleService:ロールの管理(権限の付加、排除、権限の有無チェックなど)機能を定義


RoleMapper(DB, LDAP, ファイル、その他)のリソース中に含まれるロール情報を RoleService で処理します。

ここでは、メモリに存在するロール情報を元に、ロール管理を行うアプリケーションを作成例を紹介します。ここでは、@MemoryRoleMapperDefinition アノテーションを付加し、その中でロール情報を定義しています。ここで定義されたロール情報を元に @Resource アノテーションで RoleService をインジェクトしインスタンスを生成しています。getRolesメソッドの引数で与えられたユーザが持つ全てのロール一覧を取得するために、getRolesForUser(username) を実行しています。RoleService が提供するメソッドの一覧(現時点での仮案)は下記の通りです。


+ grantRoleToUser(username, role)
+ revokeRoleFromUser(username, role)
+ hasRoleForUser(username, role, includeGroups)
+ getRolesForUser(username, includeGroups)
+ getUsersWithRole(role, includeGroups)
+ grantRoleToGroup(group, role)
+ revokeRoleFromGroup(group, role)
+ hasRoleForGroup(group, role)
+ getRolesForGroup(group)
+ getGroupsWithRole(role)

このように、ユーザ管理用の API やロール管理用の API が標準化される事で、よりかんたんにユーザ管理アプリケーションが実装できるようになるだけでなく、移植性の高い認証・認可のアプリケーションを構築できるようになります。

Java EE 8 は 2016 年の秋頃を目処に仕様を FIX し提供する予定です。

また、これに向け Java EE 8 は JSR 366 として登録され投票の結果、満場一致で承認されました。

詳細なロードマップは上記ですが、Java EE 8 の正式リリース時には、今までと同様 GlassFish が参照実装として提供される予定です。

現時点で登録済みの Java EE 8 関連の JSR 一覧を下記に示します。下記 JSR もどうぞご参照ください。

● JSR 366: Java Platform, Enterprise Edition 8 (Java EE 8) Specification
● JSR 107: JCACHE – Java Temporary Caching API
● JSR 365: Contexts and Dependency Injection for Java™ 2.0
● JSR 367: Java™ API for JSON Binding (JSON-B)
● JSR 368: Java™ Message Service 2.1
● JSR 369: Java™ Servlet 4.0 Specification
● JSR 370: Java™ API for RESTful Web Services (JAX-RS 2.1) Specification
● JSR 371: Model-View-Controller (MVC 1.0) Specification
● JSR 372: JavaServer Faces (JSF 2.3) Specification
● JSR 373: Java™ EE Management API 2.0
● JSR 374: Java™ API for JSON Processing 1.1
● JSR 375: Java™ EE Security API

その他、メンテナンス・リリースとしてここに示す各既存 API の改善も検討されています。

Java EE 8 の今後にご興味のある方は Java EE プロジェクトにご参加頂き、メーリング・リスト等でフィードバックをください。


Adopt-A JSR プロジェクトを通じて、日本 Java ユーザ・グループの一員としてフィードバック等をおこなってください。

最後に、Java EE 7 が日本で本格的に導入されるのは 2015 年からですが、Java EE 7 のプロジェクトを開始するにあたり、その先の Java EE 8 の変更点等を理解し意識した上でプロジェクトを進めていく事は、将来の移行、更新において非常に有用です。例えば、Pruning 予定の EJB 2.x の機能を使っているかた、Java で CORBA の利用をご検討中の方は時代の流れをいち早くつかみ、そうしたコードを排除する事がより安全に長く使っていただくための秘訣です。また認証・認可の実装コードも将来標準化される予定のクラスやメソッド・シグネチャを理解しておく事で、移行も用意になるかと想定します。Java EE 8 が市場で投入されるようになるのは、2017 年後半〜2018年辺りになる事が予想されるので随分先の内容ですが、将来の動向もみながらどうぞ今のプロジェクトをお勧めください。2016 年にリリース予定の Java EE 8 をどうぞ楽しみにしてください。

2014年12月19日 at 10:00 午前 1件のコメント

Older Posts Newer Posts


Java Champion & Evangelist

Translate

ご注意

このエントリは個人の見解であり、所属する会社の公式見解ではありません

カレンダー

2025年12月
1234567
891011121314
15161718192021
22232425262728
293031  

カテゴリー

clustermap

ブログ統計情報

  • 1,312,014 hits

Feeds

アーカイブ