Glassfish勉強会(JavaEE6について)

37,802 views

Published on

Published in: Technology
0 Comments
24 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
37,802
On SlideShare
0
From Embeds
0
Number of Embeds
27,038
Actions
Shares
0
Downloads
125
Comments
0
Likes
24
Embeds 0
No embeds

No notes for slide

Glassfish勉強会(JavaEE6について)

  1. 1. エンタープライズJava開発はこれからが面白い!<br />10年の歳月を経て、JavaEEプラットフォームは<br />実践的な開発プラットフォームへと進化した<br />2011/8/10<br />浅井 良<br />
  2. 2. 自己紹介<br />名前 浅井 良<br />現職 株式会社オージス総研 <br />アドバンストモデリングソリューション部アーキテクトチーム所属<br />去年から達人プログラマーを目指してのブログを書いています。<br />http://d.hatena.ne.jp/ryoasai/<br />TwitterIDryoasai74<br />Googleアカウント ryoasai74<br />
  3. 3. そうです、ワタシが<br />JavaEE<br />おじさんです。<br />
  4. 4. 本日のアジェンダ<br />JavaEEの進化の歴史の振り返り(15分)<br />JavaEE6アプリケーション開発で必要な主要開発技術の紹介(25分)<br />JSF2.0<br />EJB3.1<br />JPA2.0<br />CDI<br />今後のエンタープライズJavaEE開発(10分)<br />一般的なSIの開発案件で<br />使えそうな組み合わせ<br />
  5. 5. JavaEEの進化の歴史を振り返る<br />
  6. 6. エンタープライズアプリケーションの形態の変化<br />ホストコンピューター+ダム端末(80年代)<br />C/S構成のシステム(90年代~)<br />Webアプリケーション(90年代後半~)<br />Web2.0、SaaS、クラウド(2000年代~)<br />80年代<br />90年代<br />現在<br />
  7. 7. エンタープライズシステムの特徴<br />複雑<br />
  8. 8. コンポーネント<br />があれば<br />幸せになれる!?<br />
  9. 9. J2EEの当初の目標は分散コンポーネント開発基盤の標準化<br />ミドルウェアに対する標準API<br />関係データベースへのアクセス(JDBC)<br />ネーミング・ディレクトリサービスへのアクセス(JNDI)<br />分散トランザクション(JTA、JTS)<br />通信基盤(RMI/IIOP、Webサービス、JMS)<br />標準プログラミングモデル<br />JSP・サーブレット<br />EJB<br />
  10. 10. J2EEの複雑なプログラミングモデル<br />分散コンポーネントモデル<br />各機能単位にモジュールが別々のプロセスに分散<br />現在のSOAの考え方と似ている<br />状態を持ったオブジェクトがプロセスをまたいでメッセージをやり取りする<br />オブジェクトの位置等価性<br />重たい<br />面倒<br />高コスト<br />
  11. 11. 初期のEJBでHelloWorldを作ると<br />①リモートコンポーネントインターフェースを定義する<br />決まった親インターフェースを継承<br />public interface Hello extends EJBObject { <br /> String sayHello(String name) <br />throws RemoteException; <br />}<br />全メソッドでRemoteException送出を宣言<br />
  12. 12. ②ホームインターフェースを定義する<br />決まった親インターフェースを継承<br />public interface HelloHome extends EJBHome { <br />Hello create() <br /> throws CreateException, RemoteException; <br />}<br />業務と無関係な例外送出を宣言<br />
  13. 13. ③EJB実装クラスを定義する<br />実装するのはHelloではない!<br />public class HelloBean implements SessionBean { <br />private SessionContext context;<br />public void setSessionContext(<br />SessionContextaContext) {<br /> context = aContext;<br />}<br />public void ejbActivate() {}<br />public void ejbPassivate() {}<br />public void ejbRemove() {}<br /> public void ejbCreate() {}<br />public String sayHello(String name) {<br />return “こんにちは " + name;<br />}<br />}<br />業務的に意味のあるのは<br />この部分だけ<br />
  14. 14. ④XMLデプロイメント記述子を作成する<br /><?xml version="1.0" encoding="UTF-8"?><br /><ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"><br /> <display-name>EJB2App-ejb</display-name><br /> <enterprise-beans><br /> <session><br /> <display-name>HelloBeanSB</display-name><br /> <ejb-name>HelloBean</ejb-name><br /> <home>hello.ejb.HelloHome</home><br /> <remote>hello.ejb.Hello</remote><br /> <ejb-class>hello.ejb.HelloBean</ejb-class><br /> <session-type>Stateless</session-type><br /> <transaction-type>Container</transaction-type><br /> </session><br /> </enterprise-beans><br /> …<br /></ejb-jar><br />
  15. 15. 呼び出し側も大変だった<br />①JNDIからホームオブジェクトをルックアップ<br />public static HelloHomelookupHelloHome() {<br />Context context = null;<br /> try {<br /> context = new InitialContext();<br />return (HelloHome) PortableRemoteObject.narrow(<br />context.lookup("java:global/EJB2App/EJB2App-ejb/HelloBean!hello.ejb.HelloHome"), HelloHome.class);<br /> } catch (NamingException ex) {<br /> throw new RuntimeException(ex);<br /> } finally {<br /> if (context != null) {<br /> try {<br />context.close();<br /> } catch (NamingException ex) {<br /> throw new RuntimeException(ex);<br /> }<br /> }<br /> }<br />}<br />
  16. 16. ②ホームオブジェクトから<br />EJBオブジェクトを作成して呼び出す<br />Hello hello = null;<br />try {<br /> hello = helloHome.create(); <br />return hello.sayHello(name); <br />} catch (CreateException ex) {<br /> throw new RuntimeException(ex);<br />} catch (RemoteException ex) {<br /> throw new RuntimeException(ex);<br />} finally {<br /> if (hello != null) {<br /> try {<br />hello.remove();<br /> } catch (RemoteException ex) {<br /> throw new RuntimeException(ex);<br /> } catch (RemoveException ex) {<br /> throw new RuntimeException(ex);<br /> }<br /> }<br />}<br />業務的に意味のあるのは<br />この行だけ<br />
  17. 17. 重量Javaのせいで多くのプロジェクトが失敗した<br />
  18. 18. J2EE関連のデザインパターンの登場<br />プロジェクトの失敗は仕様自体の問題ではなく、アプリケーションの設計が不十分なため?<br />パターンによりJ2EE開発のベストプラクティスを学ぼうという雰囲気があった。<br />18<br />EJBデザインパターン<br />Floyd Marinescu (著) <br />J2EEパターン 第2版<br />Deepak Alur (監修), John Crupi (著), Dan Malks (著)<br />
  19. 19. 軽量Javaフレームワークへのパラダイムシフト(2003年~)<br />Springを作ったRodJohnsonの「ハゲ本」<br />開発生産性で不満のたまった優秀な開発者の間から、J2EE仕様自体の問題点が公に議論されるようになった。<br />POJO<br />EoD<br />軽量Java<br />expert one-on-one<br />J2EE Development<br />without EJB<br />Rod Johnson(著)<br />
  20. 20. JavaEE5標準に対する軽量Javaの考え方の導入<br />2006年にようやく登場のJavaEE5標準では開発簡易化(EoD)が重視された<br />EJBをPOJOとして開発<br />一部にDI・AOPの考え方を導入<br />アノテーションの利用によるxmlファイルの削減<br />
  21. 21. EJB3でHelloWorldを作ると<br />①ビジネスインターフェースを定義する<br />@Remote<br />public interface Hello { <br /> String sayHello(String name) ; <br />}<br />
  22. 22. ②ビジネスインターフェースの実装クラスを定義する<br />アノテーションだけでEJBとして登録される。<br />XMLファイルの設定は不要。<br />普通にビジネスインターフェースを実装<br />@Stateless<br />public class HelloBean implements Hello { <br /> public String sayHello(String name) {<br /> return “こんにちは " + name;<br /> }<br />}<br />
  23. 23. ③インジェクションして普通に呼び出す<br />@EJB<br />private Hello hello; <br />public void someMethod() {<br />...<br /> String message = hello.sayHello("Test");<br />...<br />}<br />アノテーションを使ってインジェクションする。<br />普通にメソッドを呼び出す。<br />
  24. 24. 見かけは簡単になったけど<br />EE5対応のAPサーバは以前よりさらに巨大で重たくなった気がする<br />動作確認するにはearファイルにパッケージ化する必要がある<br />結合試験の自動化が意外に困難<br />DIやAOPが使えるのは一部の重量コンポーネント(EJB、サーブレットなど)に限られる<br />プレゼン層とビジネス層のコンポーネントモデルがまったく異なる<br />肝心の互換性が少ない<br />結局JavaEEは<br />使えないんじゃ?<br />
  25. 25. そして、JavaEE6の時代へ<br />EE5から3年半たって2009年12月に策定<br />開発をさらに簡易化させるアイデアが多数盛り込まれている<br />SeamやFaceletsなどEE5の弱点を補足するフレームワークのしくみを導入<br />OSSの開発コミュニティが主導で、本当に便利で必要な機能が追加されている<br />余分な機能の削除によるさらなる軽量化<br />Webプロファイル<br />Pruning(使われなくなった仕様の間引き)<br />
  26. 26. なによりも本当に軽量なJavaEE6サーバーが登場<br />
  27. 27. でも、JavaEE6で<br />本当にまともに<br />開発できるの?<br />
  28. 28. JavaEE6開発の主要技術の紹介<br />
  29. 29. JavaEE6だけでWebアプリケーションを作るとどうなるか?<br />JavaEE6は便利になったと言われるが、フルスタックのサンプルがなかなか見当たらない<br />画面<br />ビジネスロジック<br />データアクセス<br />試験<br />そこで、JsfScrumToyというJSFのサンプルをリファクタリングしてどこまで簡単にできるかPOCを実施<br />
  30. 30. 実際に組み合わせを検証したJavaEE6の技術<br />Webプレゼンテーション -> JSF2.0<br />トランザクション管理 -> EJB3.1<br />データアクセス -> JPA2.0<br />DI、コンポーネント管理 -> CDI<br />試験 -> JUnit、埋め込みGlassfish<br />
  31. 31. Webアプリケーションとは?<br />Webアプリ<br /><ul><li>C/Sやホストのプレゼンテーションをブラウザ上で実行するもの
  32. 32. 本質的にステートフル</li></ul>狭義の<br />Webアプリ<br />JSF<br />Webサイト<br /><ul><li>一部に動的なコンテンツを含むWebサイト</li></ul>サーブレット・JSP<br />Webサービス<br /><ul><li>他のシステムに対してデータやロジックを提供する
  33. 33. 基本的にステートレス</li></ul>JAX-WS、JAX-RS<br />
  34. 34. Webフレームワークの分類<br />アクションベース<br />VS<br />コンポーネントベース<br />
  35. 35. 主要Webフレームワークの位置づけ<br />S2Struts<br />Struts1<br />設定簡易化<br />アクション<br />ベース<br />Struts2<br />SAStruts<br />会話状態サポート<br />Spring MVC<br />Spring WebFlow<br />Web MVC<br />FW<br />Spring Faces<br />JSF<br />会話状態サポート<br />コンポーネント<br />ベース<br />Seam<br />Tapestry<br />設定簡易化<br />Teeda<br />Wicket<br />Click<br />
  36. 36. アクションベースFW<br />HTTPリクエスト<br />HTTPリクエスト解析<br />アクション<br />業務ロジック<br />HTTPレスポンス<br />HTTPレスポンス生成<br />
  37. 37. UIコンポーネントツリーと管理Bean<br />UIコンポーネントツリー<br />UIViewRoot<br />管理Bean<br />管理Bean<br />UIForm<br />値取得<br />UIOutputText<br />値設定<br />UIInputText<br />管理Bean<br />UICommandButton<br />アクション起動<br />
  38. 38. コンポーネントベースFWの存在意義<br />リッチな画面部品(カレンダーなど)の再利用が容易<br />VBのように、部品さえ用意すれば、簡単にロジックを呼び出せる<br />ボタンや入力項目が大量についている画面が大量にあるようなアプリには適する<br />社内C/Sアプリ<br />のWeb化に適する<br />
  39. 39. 以前はいまいちだったけど、<br />JSF2は前バージョンから大幅に改良されている!<br />
  40. 40. 38<br />Faceletsを使った画面テンプレート化<br />ほとんどのWeb画面では、メニューバーやサイドバー、フッターなどがパターン化されている<br />画面が増えてくると、毎回同様のxhtmlファイルを作成するのは面倒<br />JSF2.0ではFaceletsを採用することで、テンプレート化が簡単に行えるようになった<br />
  41. 41. 画面テンプレートの定義例<br /><html …><br /><head><br />…<br /><ui:insert name="head"/><br /> </head><br /> <body><br />…<br /> <div class="body"><br /><ui:insert name="body"/><br /> </div><br /> </body><br /></html><br />template.xhtml<br />
  42. 42. 個別画面の定義例<br />hello.xhtml<br /><html …><br /><ui:composition template="/layout/template.xhtml"><br /><ui:define name="body"><br /> <h1>こんにちは世界!</h1><br /></ui:define><br /></ui:composition><br /></html><br />
  43. 43. コンポジットコンポーネント<br />画面中で繰り返し出現するパターンを抜き出して「タグリブ化」することが可能<br />部品定義をxtmlで通常の画面と同様に作成し、以下のフォルダに格納するだけでよい<br />Webアプリルート/resources<br />JSP2.0のタグファイルに近い方法で気軽に画面部品を作成できるようになった<br />
  44. 44. コンポジットコンポーネントの定義例<br />link.xhtml<br /><html …> <br /><composite:interface><br /> <composite:attribute name="value“ /><br /> <composite:attribute name="outcome"/><br /> </composite:interface><br /><composite:implementation><br /> <h:link<br /> outcome="#{cc.attrs.outcome}" value="#{cc.attrs.value}"><br /> <f:param name="cid“<br /> value="#{javax.enterprise.context.conversation.id}"/><br /> </h:link><br /></composite:implementation><br /></html><br />パラメーターを宣言<br />部品の中身を定義<br />
  45. 45. コンポジットコンポーネントの利用例<br />create.xhtml<br /><html ... xmlns:scrum="http://java.sun.com/jsf/composite/components"><br />...<br /><scrum:link<br /> outcome="/project/show"<br /> value="プロジェクト一覧" /><br />...<br /></html><br />
  46. 46. JSF1.2までの画面遷移定義<br />JSF1.2まではすべての画面遷移ルールをxmlで定義する必要があった<br /><navigation-rule><br /> <description><br /> sprint navigation rules<br /> </description><br /> <from-view-id>/sprint/show.xhtml</from-view-id><br /> <navigation-case><br /> <from-outcome>showStories</from-outcome><br /> <to-view-id>/story/show.xhtml</to-view-id><br /> </navigation-case><br /> <navigation-case><br /> <from-outcome>showDashboard</from-outcome><br /> <to-view-id>/dashboard/show.xhtml</to-view-id><br /> </navigation-case><br /></navigation-rule><br />faces-config.xml<br />
  47. 47. 暗黙ナビゲーション<br />JSF2.0ではほとんどの場合遷移先のビュー名を直接記述した方が便利<br />SprintAction.java<br />public String showSprints(Project project) {<br />selectCurrentEntity(project);<br /> return "/sprint/show?faces-redirect=true";<br />}<br />拡張子は省略可<br />?faces-redirect=trueを付けるとHTTPリダイレクトする<br />
  48. 48. BeanValidation(JSR303)<br />public class Task extends AbstractEntity implements Serializable{<br />…<br /> @NotNull<br /> @Size(min=0, max=128)<br /> private String name;<br />アノテーションを付けるだけで単項目のバリデーションが行われる。<br />
  49. 49. Ajax機能を簡単に利用<br /><h:panelGroup><br /> <h:inputText id=“endDate” value=“#{currentProject.endDate}”><br /> <f:convertDateTime pattern=“yyyy/MM/dd" /><br /><f:ajax event="blur" render="endDateError" /><br /></h:inputText> <br /></h:panelGroup><br /><h:message id="endDateError" for="endDate" styleClass="errorMessage" /><br />このように書くとblur、<br />つまり、フォーカスが外れた段階でAjaxリクエストが送信され、結果がエラーメッセージに反映される。<br />
  50. 50. その他細かい改良点が多数<br />Enumのリストを直接選択項目としてバインドできるようになった<br />以前はわざわざSelectItemのリストに変換する必要あり<br />POJOのリストを直接テーブルに表示できるようになった<br />以前はDataModelに変換する必要があり<br />選択行は直接アクションメソッドのパラメータとして簡単に受け取れる<br />
  51. 51. EJB3.1=ちょっと特殊な能力を持ったPOJO<br />以前はEJB=ビジネスコンポーネント=面倒<br />最新のEJB3.1はちょっと特殊な能力を持ったPOJOに過ぎない<br />トランザクション<br />リモート呼び出し<br />同時実行<br />タイマー実行<br />非同期実行<br />
  52. 52. さらに、EJB3.1では<br />インターフェースはオプション<br />Warファイル中に格納可能<br />Earファイルは単純な<br />Webアプリでは不要<br />
  53. 53. EJB3.1を使った非同期実行<br />呼び出し側のスレッドをブロックせずに時間のかかる処理を実行<br />@Stateless <br />public class OrderProcessBean {<br />@Asyncronous<br /> public void registerOrder(Order order) { <br /> ...<br /> }<br />}<br />戻り値の型はvoidかFuture型<br />
  54. 54. EJB3.1を使ったタイマー実行<br />EJB3.1で新登場の<br />シングルトンBean<br />@Singleton<br />public class LogCleanUpBean {<br />@Schedule(minute="1", hour="*") <br /> public void cleanUpOldLogs() { <br /> ...<br /> }<br />}<br />CRON的な宣言で簡単に定期実行可能<br />
  55. 55. JPAを使ったデータアクセス<br />JPA = Java Persistence API<br />O/Rマッピングの標準化<br />
  56. 56. JPAを使うと何がよいのか?<br />静的なインピーダンスミスマッチの解決<br />継承などを駆使した複雑なドメインモデルをテーブルにマッピングできる<br />動的なインピーダンスミスマッチの解決<br />エンティティの状態変更を適切なタイミングと粒度でテーブル更新に変換してくれる<br />エンティティに複雑な状態変更などの振る舞いを持たせられる<br />DDDと相性がよい!<br />※DDD=DomainDrivenDevelopment<br />
  57. 57. ドメイン駆動型設計(DDD)<br />流通、販売など業務固有の処理こそが最も大切で複雑な部分<br />コアの業務ドメインに優秀な開発者を割り当てて時間をかけてあるべきモデルに進化させていく<br />
  58. 58. Story<br />Task<br />ID=null<br />ID=null<br />Task<br />永続コンテキスト<br />ID=null<br />Story<br />Project<br />ID=3<br />ID=101<br />Task<br />Sprint<br />ID=9<br />Story<br />ID=11<br />ID=10<br />Project<br />ID=101<br />DB<br />永続コンテキスト中のエンティティの状態はDBと自動的に同期される。<br />
  59. 59. JPA2.0の新機能<br />JPA2では細かい改良と機能追加が行われている<br />キャッシュの標準化<br />悲観ロックの標準化<br />クライテリアクエリAPIの標準化<br />より柔軟なドメインモデルのマッピング<br />Stringなど値コレクションのマッピング<br />Mapを使ったマッピング方式の拡張<br />
  60. 60. JavaEEでちょっと複雑な「Bean」について<br />JavaEE仕様の中ではBeanという言葉が様々な仕様で使われている<br />EnterpriseJava Bean(EJB)<br />JSFの管理Bean<br />(@javax.faces.bean.ManagedBeanで定義)<br />JSR250で新たに登場した管理Bean<br />( @javax.annotation.ManagedBeanで定義)<br />意味が不統一なだけでなく、お互いに連携させるのも困難<br />
  61. 61. 一方で、SpringやSeamでは<br />レイヤーに関係なく、ほぼすべてのPOJOをBeanとしてコンテナに登録できる<br />Bean同士はお互いに統一された方法で連携させることができる<br />やはり、Java EE6はイマイチなのか?<br />
  62. 62. JavaEE6でBeanを統一的に扱う切り札となるCDI<br />CDI=Contextsand Dependency Injection<br />beans.xmlファイル(空でもよい)をモジュール内に格納することでCDI機能が有効になる<br />CDIを有効にすると、ほとんどのPOJO・EJBをすべて統一的にBeanとして扱うことができるようになる<br />
  63. 63. CDIのBeanの例<br />Beanの有効<br />なスコープを定義<br />JSFのビューから<br />参照する名前を定義<br />一定の条件を満たせば自動的にCDIのBean<br />@Named @ConversationScoped<br />public class SprintAction implements Serializable { <br />@Inject<br />ScrumManagerscrumManager;<br />@Inject<br />SprintRepositorysprintRepository;<br />…<br />}<br />任意のBeanは@Injectで注入<br />
  64. 64. CDIのBeanのスコープ<br />CDIのBeanはスコープを持てる<br />@RequestScoped<br />@SessionScoped<br />@ApplicationScoped<br />@ConversationScoped<br />Singleton、Dependent疑似スコープ<br />独自のスコープを定義して拡張することも可能<br />
  65. 65. JavaEE6と試験自動化<br />Java EE6のコンポーネントは大部分POJO<br />従って、JUnitとモックオブジェクトを使って容易に単体試験可能<br />加えて、軽量な埋め込みコンテナを利用することで、トランザクションやDB接続を行う結合試験の自動化もできる<br />JeeUnitやArquillianなどを利用すると、CDIによりいっそう楽になる<br />
  66. 66. 今後のエンタープライズJava開発<br />
  67. 67. ところで、日本のSI業界では<br />JavaEEの技術(プログラミングモデルの部分)は主に海外で利用され、発展してきた<br />そもそも、日本のSI業界の事情は違うのでは<br />そもそも、コンポーネント化や多層分散アーキテクチャのシステムはほとんどなかったのでは?<br />大規模だが、モノリシックなアーキテクチャを強制するフレームワークが蔓延<br />
  68. 68. SI業界の残念な実情<br />FN1002Commandのようなレガシーなクラス名の規約<br />10000行を超えるクラスがあってもリファクタリングしない(できない)<br />業務ロジックはexecute()メソッド内に記述、勝手にメソッドを分割できない<br />今でも新規案件をJDK1.4で開発<br />
  69. 69. 海外はオーバーエンジニアリング<br />海外だと、アーキテクトの権限が強いことが多く、過剰な設計となりがちだった?<br />過剰なレイヤ、ティア分割、分散化<br />面倒だけど頑張ってコンポーネント化、ドメインモデリングしていた?(Sessionファサードパターン)<br />
  70. 70. 日本はアーキテクチャ軽視<br />日本だと、適切なアーキテクチャが施行されていないケースも多い<br />1機能1クラス(コマンドパターン)<br />Excelから全クラスと設定を自動生成<br />箱はたくさん分かれているが、論理的なレイヤー構造やコンポーネント構造はなし<br />
  71. 71. 開発簡易化(EoD)の真の意味<br />従来の大変だけれどつまらない単純作業から開発者が解放される<br />単純な値の詰め替え<br />冗長な設定ファイルの記述<br />サービスの粒度などを自由に設計できる<br />ドメイン駆動型設計など複雑な業務ドメインをモデル化<br />つまり「頭を使う必要がある」ということ<br />
  72. 72. EoDと生産性の関係<br />生産性・保守性<br />SOA、 TDD、<br />ドメイン駆動型<br />アジャイルの開発<br />日本のSI業界的な<br />労働集約型、<br />ウォーターフォール<br />コピペ中心の開発<br />EoD技術の進化<br />
  73. 73. エンタープライズJava開発はこれからが面白い<br />JavaEE6の時代になり、標準仕様ですらEoDがかなり成熟してきたといえる<br />コンポーネント化、DDD、テストファーストなどのメリットが低コストで実現できる仕掛けが標準で得られるようになった<br />日本のSI開発のやり方も従来の労働集約型のモデルから脱却して、より賢い開発方法を取り入れていかなくてはならない時代<br />
  74. 74. 今後はスキルをあるべき方向に発揮できる、<br />開発者にとって面白い時代になる<br />

×