jakarta ee:java eeの後継リリースで マイクロ …...
TRANSCRIPT
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
15
//the leading edge/
長年、JavaプラットフォームでWebアプリケーションやエンタープライズ・アプリケーションを開発するために、
さまざまなアプローチがとられてきました。JVMの草創期には、Webアプリケーションで動的コンテンツを
実現するために、画期的なサーブレット・テクノロジーが導入されました。また、アプレットなどのテクノロジーに
よって、ユーザーのデスクトップでリッチ・インターネット・アプリケーションを動作させることができるようになり
ました。やがて、JavaServer Pages(JSP)やApache Strutsなどのフレームワークによって、簡単かつ、より直感的
にサーブレットを使える方法が生み出されました。このようなサーブレット・テクノロジーをベースに構築されたソ
リューションにより、開発者は定型コードではなくフロントエンドにいっそうの時間を注げるようになりました。
1999年に導入されたJ2EEプラットフォームでは、エンタープライズベースのアプリケーションを作成するための
APIがいくつか提供されました。JDBC、Enterprise JavaBeans(EJB)、JSP、Java Message Service(JMS)などがその
APIに当たります。初期のJ2EEは複雑でした。必要な構成が多数あり、ロジックを追うことが困難だったからです。
この構成のため、J2EEプラットフォームは使いにくいものでした。
年が経つにつれ、J2EEは進化して提供されるAPIが増え、複雑さも減少しました。そして、2006年のJava EE 5
の導入に伴い、プラットフォームの名前が変更されました。このリリースは重要なものでした。EJB 3.0で行われた
変更などの優れた生産性向上機能や、JavaServer Faces(JSF)フレームワークがプラットフォームに導入されたた
めです。それに続く2回のリリース、Java EE 6とJava EE 7は、おもに開発者の生産性とプラットフォームの最新化に
重点を置いたものです。いずれのリリースも、XMLを必要とする構成に代えてアノテーションなどの技術を組み込む
ことで、プラットフォームの複雑さが大幅に軽減されました。Java EE 6でプラットフォームの中核として導入された
Contexts and Dependency Injection(CDI)は、アプリケーション全体でコンテキスト依存オブジェクトを簡単に
利用する方法を提供するものです。その後、1つのWARファイルとして最新のアプリケーションを開発してデプロイ
するという手法は、Java EEプラットフォームとともに効率化されていきました。
Jakarta EE:Java EEの後継リリースでマイクロサービスを構築する新生エンタープライズJavaリリースによるマイクロサービス構築を初公開
JOSH JUNEAU
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
16
//the leading edge/
Java EEは大幅に進化しましたが、テクノロジーの急速な変化により、プラットフォームがさらに高速に前進す
ることが求められています。Java EE 8リリースでは、それに応えて、Webサービスの使用を容易にするAPIや新たな
セキュリティAPIの提供、そしてコンテナ環境へのデプロイの改善が行われました。しかし、プラットフォームを前進
させるペースを上げるというニーズには、まだ対応しきれていません。2017年、オラクルはこの要件に対処するた
め、Eclipse Foundationを通じてこのプラットフォームをオープンソース化しました。
本記事では、エンタープライズJavaにおける新たな進化であるJakarta EEについて説明します。オラクルから
Eclipse Foundationへの仕様の移管について解説し、最新コードを入手してJakarta EEを使ってみる方法を紹介し
たいと思います。
Jakarta EEが生まれた理由オラクルがEclipse Foundationを通じてJava EEプラットフォームをオープンソース化することを決めると、Eclipse
Enterprise for Java(EE4J)プロジェクトが作成されました。このプロジェクトは、GitHub上にあるベース・リポジトリ
です。プロジェクトの目的は、各Java EE仕様のコードベース、ドキュメント、Technology Compatibility Kits(TCK)
の移管と格納です。EE4Jは、オープンなプラットフォームとなるものではなく、新しいプラットフォームの各仕様を含
むプロジェクトです。オラクルは、2016年後半に、各仕様のドキュメント、コードベース、TCKを対応するEE4Jプロジェ
クトに移管する作業を開始しました。本記事執筆時点(2018年半ば)では、移管はまだ進行中であり、できる限り
シームレスかつタイムリーに移管を行うための重要な作業が行われています。
以前Java EEと呼ばれていたオープンソース・プラットフォームは、新たにJakarta EEと呼ばれることになりまし
た。つまり、オラクルから移管されるすべてのEE4Jプロジェクトを合わせると、Jakarta EEプラットフォームとなりま
す(Jakartaという名前は、Javaコミュニティで重要な意味を持ちます。その理由として、Jakarta Projectというプロ
ジェクトが数年にわたってApache Software Foundation傘下のプロジェクトとして運営されていたことが挙げられ
ます。このプロジェクトは、大半のサブプロジェクトがApache Software Foundation内で独立したプロジェクトと
なったため、2011年に終了しました。そのため、同じ名前を使っても混乱はないものとプロジェクト・チームは判断
しました)。
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
17
//the leading edge/
新しいガバナンス・プロセスJakarta EEの重要な特徴の1つに、Java EEよりもリリースの頻度が高いことが挙げられます。これを実現するため
に、Jakarta EEワーキング・グループがJakarta EEプラットフォームを管理することになる予定です。このグループは、
EE4Jに関連した技術の進化や、その幅広い採用を促します。このワーキング・グループは、任務の一環として、ベン
ダーに依存しないマーケティングの実施、仕様決定に関する新たなガバナンス・プロセスの定義および管理、互換
性およびブランディング・ルールの定義、コミュニティ参加の推進、ワーキング・グループおよびコミュニティが持続
可能な形で業務を行えるようにする資金調達モデルの確立を行います。
Jakarta EEワーキング・グループには、Strategic、Enterprise、Participant、Committer、Guestという5種類のメ
ンバーが存在します。Strategic、Enterprise、Participantは、いずれも組織が対象ですが、プロセスへの関与の度合
いが異なります。Committerは、Eclipse Foundationのプロジェクトにコードをコミットして貢献できる個人メンバー
です。Guestは、Eclipse FoundationのAssociate会員である1年更新の組織メンバーで、運営委員会の招待により、
限定的な形で委員会に参加します。メンバーは、Jakarta EEワーキング・グループの下で、プラットフォームの方向性
決定に寄与することや、プラットフォームを構成するEE4Jプロジェクトへのパッチのコミットや拡張機能の追加を通
じてプラットフォームに直接貢献することができます。
Jakarta EEを使ってみるそれでは、Jakarta EEプラットフォームでアプリケーションを構築する方法を紹介します。Jakarta EE 8は、2018年末
までにリリースされる予定です。そのため、次のセクションで説明する情報の中には、公式リリース前にJakarta EE 8
を試す方のみに関連するものもあります。
以降のセクションでは、さまざまなサービスの開発に必要なライブラリの入手方法についても説明します。そ
れらのサービスを組み合わせて使用し、サンプル・アプリケーションを作成します。実際には、サンプル・アプリケー
ション内の個々のサービスは、必要なEE4Jプロジェクトのみを使用する個別のプロジェクトです。最後に、各サービ
スを「完全」版のPayara Serverの単一インスタンスにデプロイし、アプリケーションを提供する方法について説明
します。この設定は、複数のWARファイルからなるアプリケーションを単一サーバーにデプロイする際に使うことが
できます。しかし、それぞれのWARファイルを別々のコンテナにマイクロサービスとしてデプロイする方が一般的で
す。いずれの方式も有効で、プロジェクトの要件に応じて選ぶことができます。
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
18
//the leading edge/
スポーツ選手名簿アプリケーションの構築Jakarta EEアプリケーションは標準に基づいて構築されており、開発は簡単です。今回のサンプル・アプリケーショ
ンは、スポーツ・チームのメンバーの登録と問合せを行うことができるものです。ここで構築するアプリケーション
では、JSF 2.3(Mojarra)フロントエンドを利用するとともに、JAX-RS Webサービスを使って、データベースと連携す
るJava Persistence API(JPA)と通信します。このアプリケーションは、3つの個別のサービスで構成されています。
それぞれのサービスはMavenプロジェクトです。最初に説明するプロジェクトは、データベースへの問合せに使用
するものです。次に、登録(データベースへの挿入またはデータベースの更新)を行うもの、最後にフロントエンド・
ユーザー・インタフェースを紹介します。
Jakarta EEスタック全体をバンドルしてはいない別々のコンテナ(Apache Tomcatなど)に各サービスをデプ
ロイすることもできる点に注意してください。そのため、POMには、スタック全体ではなく、各サービスに必要な依
存性のみを記述しています。本記事で説明する各サービスは、GlassFish 5などのアプリケーション・サーバーまたは
サーブレット・コンテナの単一インスタンスにデプロイすることができます。
環境の設定 Jakarta EEアプリケーション開発には、数多くのIDEを使うことができます。本記事執筆時点でのおもな問題は、
Jakarta EE自体を直接サポートしているIDEがないことです。しかし、大半のIDEはJava EE 8を完全にサポートしてい
ます。Jakarta EEの初期リリースはJava EE 8との整合性がとれているため、Jakarta EEアプリケーションを開発する
際には、IDEのJava EEサポートを利用できます。主要なIDEのほとんどが、将来的にはJakarta EEを直接サポートす
ることになるでしょう。
本記事では、コードベースからビルドしたApache NetBeans 9.0リリース候補版をIDEとして使用しています。
IDEをビルドした後に、Java EEプラグインをインストールすることができます。
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
19
//the leading edge/
サービス内で使用するプロジェクトの取得EE4Jでは、Jakarta EEプラットフォームを構成するさまざまなプロジェクトがホストされています。Jakarta EEプラット
フォームの完全リリースが始まると、Maven座標や特定の場所から、さまざまなバリエーションのJakarta EEプラッ
トフォームをダウンロードしてプロジェクトに追加できるようになります。おそらく、プラットフォーム全体としても、
個別のAPIとしても使用できるようになるでしょう。しかし、Jakarta EEが公式にリリースされるまでは、EE4Jプロ
ジェクトをダウンロードするか、Maven依存性として個別に追加する必要があります。必要な仕様やAPIを入手する
経路は、いくつかあります。具体的には、コードベースをダウンロードして自分でビルドするか、Maven Centralリポ
ジトリを利用してプロジェクトに取り込みます。
EE4J APIをダウンロードしてビルドするためには、そのAPIに対応するEE4J GitHubプロジェクト・ページにアク
セスしてそれぞれのGitHubリポジトリを探し、プロジェクトのコードベースをクローンし、(通常は)Mavenを使っ
てAPIをビルドします。各プロジェクトのGitHubリポジトリのホームページに掲載されている手順に従ってくださ
い。優れた例を確認したい方は、Mojarraプロジェクトをご覧ください。EE4J APIのビルドを行い、生成されたプロ
ジェクトでそのAPIを使用する方法に関する豊富なドキュメントが含まれています。ほとんどのプロジェクトでは、
mvn clean installを実行するだけでプロジェクトをビルドすることができ、依存性JARが生成されます。生成され
たJARは、ローカルMavenリポジトリに追加することも、プロジェクトに直接追加することもできます。
本記事の例では、プロジェクトのPOMファイルに依存性を追加してMaven Centralを使用しています。Maven
Centralに、実際のJakarta EEプラットフォームAPIがまだ登録されていない可能性があることに注意してください。
そのため、一部のAPIはJava EE 8の依存性を指しています。
サービスの開発Apache NetBeansで「New Project」→「Maven」→「Web Application」を選択し、今回の例の各サービス
をMavenプロジェクトとして作成しました。プロジェクトの名前は、それぞれSportsTeamQueryService、SportsTeamRegistrationService、SportsTeamUIServiceとしています。
今回の例のデータベース表(Apache Derby)は、次のSQLを使用して作成することができます。便宜上、表は
サンプルDerbyスキーマに追加します。GlassFish 5またはPayara Server 5を使用して今回の例をデプロイする場合
は、JDBCコネクションとしてDerbyサンプル・スキーマが登録されている必要があります。
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
20
//the leading edge/
create table team_roster (id numeric,first_name varchar(150),last_name varchar(150),position varchar(150),registration_date date,PRIMARY KEY (ID));
問合せサービス:SportsTeamQueryServiceはもっとも簡単です。特に、IDEを使用している場合は、数行のコード
を記述するだけで作成されます。このサービスは、EJB、JPA、JAX-RSの各Jakarta EE仕様を使用するため、リスト1
に示すPOMが必要になります(説明のみを行い、記事には掲載していないリストも含め、本記事のすべてのコード
は筆者のGitHubリポジトリから入手できます)。
サービスがデータベースに接続できるように、永続性ユニットが必要です(リスト2)。このサービスでは、エンティティ・クラスを使って永続化を行っています。Apache NetBeansを使用してTeamRosterエンティティ・クラス
を作成するためには、「New」→「Entity Classes from Database」を選択し、前のセクションで作成したデータベー
ス表を選択します。リスト3に、TeamRosterエンティティ・クラスのコードベースを示します。 データベースへの問合せには、JAX-RSサービスを使用できます。サービス内でJAX-RSを有効にするためには、
リスト4に示す内容のApplicationConfigクラスを作成します。
リスト4:package org.javamagazine.sportsteamqueryservice.service;
import java.util.Set;import javax.ws.rs.core.Application;
@javax.ws.rs.ApplicationPath("rest")public class ApplicationConfig extends Application {
@Override
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
21
//the leading edge/
public Set<Class<?>> getClasses() { Set<Class<?>> resources = new java.util.HashSet<>(); addRestResourceClasses(resources); return resources; }
private void addRestResourceClasses( Set<Class<?>> resources) { resources.add( org.javamagazine.sportsteamqueryservice .service.TeamRosterFacadeREST.class ); } }
@ApplicationPathアノテーションでは、各サービスのRESTful Webサービスのエントリ・ポイントとして使用する
URLパスを定義しています。RESTfulサービスとして使うリソース・クラスは、すべてApplicationConfig内に登録す
る必要があります。
このRESTサービス・クラスの名前は、TeamRosterFacadeRESTです。リスト5をご覧ください。
リスト5:@javax.ejb.Stateless@Path("teamrosterqueryservice")public class TeamRosterFacadeREST {
@PersistenceContext(unitName = "SportsTeamQueryServicePU") private EntityManager em;
public TeamRosterFacadeREST() {
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
22
//the leading edge/
}
@GET @Path("{id}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public TeamRoster find( @PathParam("id") BigDecimal id) { return (TeamRoster) em.createQuery( "select object(o) from TeamRoster o " + "where o.id = :id") .setParameter("id", id) .setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS) .getSingleResult(); }
@GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public List<TeamRoster> findAll() { return em.createQuery("select object(o) from TeamRoster o") .setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.BYPASS) .getResultList(); }
protected EntityManager getEntityManager() { return em; } }
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
23
//the leading edge/
このクラスには@javax.ejb.Statelessアノテーションが付加されています。このアノテーションは、クラスがステート
レスSession Beanであることを示しています。javax.ws.rs.Pathアノテーションでは、クラスのサービス・エンドポイン
トにアクセスする際に使用できるURLパスを定義しています。TeamRosterFacadeRESTクラスには、TeamRosterを検索するfind()と、TeamRosterのListを検索するfindAll()という2つのサービス・メソッドが含まれています。
このサービスは、http://localhost:8080/SportsTeamQueryService/rest/teamrosterqueryserviceという
URLを呼び出すことで使用できます。また、TeamRosterのIDを、pathパラメータとしてURLの末尾に追加して渡す
こともできます。
登録サービス:SportsTeamRegistrationServiceでは、スポーツ・チームに新しい選手を登録できるWebサービ
スを公開します。このサービスは、SportsTeamQueryServiceとほぼ同じですが、TeamRosterFacadeRESTクラス
(リスト6)は例外で、RESTful Webサービスのメソッドが異なっています。このクラスには、TeamRosterオブジェ
クトの数を返す、countRoster()という名前の@GETメソッドと、選手の姓、名、ポジションを表す@FormParam
型のパラメータを受け取る、addPlayer()という名前の@POSTメソッドが含まれています。このメソッドは、新しい
TeamRosterオブジェクトを作成し、パラメータとして渡された値を設定し、EntityManagerを使ってオブジェクト
をデータベースに永続化します。最後に、成功または失敗を示すjavax.ws.rs.core.Responseを返します。
選手を登録するためには、JAX-RSクライアントを使用して、addPlayer Webサービスにjavax.ws.rs.core.Form
を送信します。次のセクションでは、JSFユーザー・インタフェースを使用してこれを実現する方法について説明しま
す。
ユーザー・インタフェース・サービス:SportsTeamUIServiceでは、JSFフレームワークを使ってユーザー・
インタフェースを制御します。このサービスでは、SportsTeamQueryService Webサービスへの問合せと、
SportsTeamRegistrationServiceを使った、新しい選手の登録を行います。そのため、JAX-RSクライアントへの依
存性も必要になります。リスト7にPOMファイルを示します。このUIサービスでは、どのWebフレームワークも使用で
きますが、今回はJSFを選択しました。そのため、WebビューはXHTMLファイルとして作成し、フロントエンドとバッ
クエンドの間の通信にはCDIコントローラ・クラスを使っています。
メイン・ビューは、index.xhtmlファイル(リスト8参照)です。DataTableを使って、登録されている各選手を一覧表示することに加え、新しい選手を登録するためのフォームも含まれています。index.xhtmlのバックエンドと
なるBeanは、TeamRegistrationController(リスト9参照)およびTeamQueryController(リスト10参照)というCDIコントローラです。
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
24
//the leading edge/
コントローラには、@RequestScopedというアノテーションが付加されています。つまり、リクエストごと
にコントローラの新しいインスタンスが作成されます。したがって、index.xhtmlビューにアクセスがあるたび
にコントローラが作成され、getTeamRosterList()メソッドが呼び出されて、全選手のリストが返されます。
SportsTeamQueryServiceに問合せを行って選手のリストに移入する処理は、JAX-RSクライアントを使って行って
います。
コントローラのteamRosterフィールドは、データを移入して新しい選手(TeamRosterオブジェクト)を作成す
るために使用しています。ビュー(図1)の「Register」ボタンをクリックすると、registerPlayer()コントローラ・メソッドが呼び出されます。このメソッドでは、teamrosterregistrationservice.addPlayer Webサービスの
呼出しに使用するJAX-RSクライアントを新しく作成し、新しいjavax.ws.rs.core.Formを作成しています。また、
ビューに入力されたデータが、TeamRosterオブジェクトで対応するフィールドに移入されます。サービスを呼び出
すと、成功または失敗を示すJAX-RSレスポンスが返されます。実際の使用例では、セキュリティAPIを使い、JSON
WebトークンなどのテクノロジーでWebサービスを保護する必要があることに注意してください。
図1:SportsTeamRegistrationServiceのユーザー・インタフェース
ORACLE.COM/JAVAMAGAZINE //////////////////// SEPTEMBER/OCTOBER 2018
25
//the leading edge/
デプロイメント・オプションと構成Jakarta EEはクラウド・プラットフォームです。つまり、アプリケーションはほとんどのコンテナにデプロイできます。
前述のように、本記事で説明した3つのサービスは、単一のアプリケーション・サーバー・コンテナにデプロイする
ことも、それぞれをDockerコンテナなどの別々のコンテナにデプロイすることもできます。
別々のコンテナを使う場合は、MicroProfileで提供されているような構成APIを使用し、WebサービスURIなど
を動的に構成するとよいでしょう。Jakarta EEの初期リリースには、構成APIは含まれていませんが、今後追加され
るかもしれません。また、Java EEのSecurity APIやJSON Webトークンなどの標準化されたセキュリティ・ソリュー
ションを使用して、Webサービスのエンドポイントを保護することもお勧めします。
ロードマップJakarta EEは新しいオープン・プラットフォームです。すなわち、Jakarta EEは前身のJava EEよりも、はるかに高速に
進化する可能性を秘めています。Jakarta EEの初期リリースはJava EE 8と等価なものになる見込みですが、今後の
リリースでは、新機能、場合によっては新APIがプラットフォームに導入されることになるでしょう。これまでJava EE
プラットフォームは、機能を増やしながら、使いやすく進化してきました。新ブランドでの2回目のリリースとなる
Jakarta EE 9リリースでは、このプラットフォームの将来像が明らかになり始めるでしょう。
しかし、Jakarta EEの開発に関与するなら、今が絶好のタイミングです。関与する特に重要な方法として、
メーリング・リストに参加して議論に加わるというものがあります。Jakarta EEワーキング・グループやEclipse
Foundationに参加して、EE4JプロジェクトのCommitterになることもできます。いずれにしても、JavaでWebアプリ
ケーションやエンタープライズ・アプリケーションを作成する場合は、Jakarta EEのスピードに追いつくための時間を
確保することが大事です。</article>
Josh Juneau(@javajuneau):アプリケーション開発者、システム・アナリスト、データベース管理者。おもに、Javaやその他のJVM言語を使った開発に従事。Oracle Technology NetworkやJava Magazineで多くの記事を執筆し、JavaやJava EEに関する複数の書籍をApressから出版している。JSR 372およびJSR 378のJCP専門家グループのメンバーを経験。NetBeans Dream Teamメンバー、Java Champion、CJUG OSS Initiativeのリーダーであり、JavaPubHouse Off Heapポッドキャストにレギュラー出演中。