Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaOne2015報告会 Java EE アップデート #j1jp

12,501 views

Published on

JavaOne2015報告会 Java EE 8 に関するスライドです。

Published in: Software
  • Be the first to comment

JavaOne2015報告会 Java EE アップデート #j1jp

  1. 1. JavaOne2015 - Java EE 2015/11/14 上妻 宜人 (あげつま のりと)
  2. 2. • APサーバサポート、Javaトラブルシューティング • ブログ 見習いプログラミング日記 • twitter: @n_agetsu 上妻 宜人 (あげつま のりと)
  3. 3. • Java EE 8 のアップデート • Early Draft Review1: Servlet4.0, JMS2.1 • ドラフト未リリース: JAX-RS2.1, JPA2.2 • Java EE 周辺の話 • WildFly Swarm 本日の内容
  4. 4. Java EE 8 はまだ検討中。 この先の内容は、今後大きく変わる 可能性があります。
  5. 5. Servlet4.0 現在のステータス: Early Draft Review JSR-368 https://jcp.org/en/jsr/detail?id=368
  6. 6. Servlet 4.0 サーブレットコンテナもHTTP/2通信に対応 • 2015年5月 RFC 7540で公開。SPDYが原型。 • 多重化 / バイナリフレーム / ヘッダ圧縮 • ヘッダの意味合い (GET/POST/200 OK など) は基本的に踏襲 client server client server client server 並行リクエストは、複数TCP接続が必要 ブラウザ実装によっては同時接続数『6』 1TCP接続で多重化 TCPコネクション_1 TCPコネクション_2..
  7. 7. Servlet 4.0 HTTP/2 ストリームによる多重化 Connection : 1つのTCPコネクション Stream : 1つのリクエスト & レスポンスの組 Stream id=1 Stream id=1 .. N: http://chimera.labs.oreilly.com/books/1230000000545/ch12.html#HTTP2_STREAMS_MESSAGES_FRAMES Request Stream: 1 :method: GET ... Frame : HTTP2.0通信の最小単位 Stream: 1 :status:200 HEADERS frame Stream: 1 response data DATA frame Response
  8. 8. Servlet 4.0 HTTP/2 ストリームによる多重化のServlet影響 • APIのユーザ視点では影響はあまりない • 1リクエスト => 1レスポンス の法則が崩れなければ、 doGet, doPostメソッドの現状の仕組みがそのまま使える • HttpServletRequest/HttpServletResponse へのメソッド追加 • int getStreamId() • ストリームIDを知りたい機会は少ないと思う
  9. 9. Servlet 4.0 HTTP/2 サーバプッシュ client server .html .js .png .css • SSE/WebSocketとは用途が異なる • 関連リソースをサーバプッシュ • 例えばhtmlの要求がきたら • 関連のjs, png, css もプッシュする • 従来はインラインイメージを適用 • 1リクエスト => 1レスポンスが崩れる • 今までのHttpServletResponseは 1レスポンスが前提
  10. 10. Servlet 4.0 HTTP/2 サーバプッシュのServlet影響 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PushBuilder builder = request.getPushBuilder(); builder.setPath(“/style.css”); builder.push(); res.setContentType(“text/html”); PrintWriter out = res.getPrintWriter(); out.println(“<html>”); out.println(“<head>”) out.println(“<link rel=”stylesheet” type=”text/css” href=“style.css”>”); … }
  11. 11. Servlet4.0 まとめ • HTTP/2 対応 – サーブレットコンテナがHTTP/2に対応 – ストリームID取得, サーバプッシュ向けAPIの追加 • 本日は未紹介 – (検討中) Java9 Flow対応によるリクエスト処理
  12. 12. JAX-RS2.1 現在のステータス: ドラフト未リリース JSR-370 https://jcp.org/en/jsr/detail?id=370
  13. 13. JAX-RS2.1 主なテーマ • 非同期クライアントAPIの改善 • ノンブロッキング I/O • Server-Sent Event – Jersey実装と同じ
  14. 14. JAX-RS2.1 非同期クライアントAPIの改善 • 並列で依存関係のあるWebAPIを呼び出したい • Jerseyには既に実装がある • RxJava Observable, Java 8 CompletableFuture 対応 出張手配 サービス 新幹線予約 ホテル予約大阪1泊2日で! 手配完了 料金請求 1. 予約を並列実行 2. 予約が終わったら 請求サービスに投げる
  15. 15. JAX-RS2.1 非同期クライアント: rx()によるCompletationState取得 // Aの問い合わせ (非同期) WebTarget targetA = Client.newClient().target(...); CompletionStage<User> a = target1.request().resolveTemplate(“id”, 1) .rx().get(User.class); // Bの問い合わせ (非同期) CompletionState<Product> b = targetB.request().resolveTemplate(“id”, 1) .rx().get(Product.class); // AとBの結果を組み合わせて、Cに問い合わせ (非同期) CompletionState<String> c = a.thenCombine(b, (user, product) -> targetC.request() .resolveTemplate(“user”,user) .resolveTemplate(“prod”,product).rx().get(...))); // 最終的な結果の取得 c.join(); a b c 最終的な結果
  16. 16. JAX-RS2.1 非同期クライアント: rx()によるCompletationState取得 // Aの問い合わせ (非同期) WebTarget targetA = Client.newClient().target(...); CompletionStage<User> a = target1.request().resolveTemplate(“id”, 1) .rx().get(User.class); // Bの問い合わせ (非同期) CompletionState<Product> b = targetB.request().resolveTemplate(“id”, 1) .rx().get(Product.class); // AとBの結果を組み合わせて、Cに問い合わせ (非同期) CompletionState<String> c = a.thenCombine(b, (user, product) -> targetC.request() .resolveTemplate(“user”,user) .resolveTemplate(“prod”,product).rx().get(...))); // 最終的な結果の取得 c.join(); a b c 最終的な結果
  17. 17. JAX-RS2.1 非同期クライアント: アノテーションによる依存性制御 class DeclarativeRxHandler { @FinalResult public String getC( @PartialResult(“A”) String a, @PartialResult(“B”) String b) { return a; } @PartialResult(“A”) public CompletableFuture<String> getA() {...} @PartialResult(“B”) public CompletableFuture<String> getB() {...} } A B C 最終的な結果
  18. 18. JAX-RS2.1 ノンブロッキング I/O - 背景 • 不安定/遅いネットワークからファイルアップロード • CPUは別スレッドに割当てられても、メモリは1MB消費し続ける @Path(“/upload”) public class FileUploadResource { @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public void upload(@FormDataParam(“file”) InputStream input, ...) { byte[] buf = new byte[1024]; int readed; try { while ((readed = input.read(buf)) != -1) { // write file ... } catch (IOException e) {...} } データが来るまでブロック (64bitJVM)
  19. 19. @POST @Consumes(MediaType.APPLICATION_OCTET_STREAM) public void upload(@QueryParam(“path”) String path, @Context request, @Suspend AsyncResponse response) { FileOutputStream out = new FileOutputStream(tmpdir); byte[] buf = new byte[1024]; request.entity(input -> { try { if (input.isFinished()) { // データ読み込み完了 out.close(); response.resume(“Upload Completed”); } else { final int n = input.read(buffer); out.write(buffer, 0, n); } } catch (IOException e) {...} } } JAX-RS2.1 ノンブロッキング I/O - JavaOneで紹介されていたアイディア
  20. 20. @POST @Consumes(MediaType.APPLICATION_OCTET_STREAM) public void upload(@QueryParam(“path”) String path, @Context request, @Suspend AsyncResponse response) { FileOutputStream out = new FileOutputStream(tmpdir); byte[] buf = new byte[1024]; request.entity(input -> { try { if (input.isFinished()) { // データ読み込み完了 out.close(); response.resume(“Upload Completed”); } else { final int n = input.read(buffer); out.write(buffer, 0, n); } } catch (IOException e) {...} } } ブロックしない 読込可能データの発生毎に 繰り返しコールバックされる? JAX-RS2.1 ノンブロッキング I/O - JavaOneで紹介されていたアイディア
  21. 21. JAX-RS2.1 ノンブロッキング I/O - まだまだ検討中 • 本当に必要? 色々と議論がある • ユーザレベルでNIOを意識しなくても良いのでは など? – MessageBodyReader, MessageBodyWriterの実装内に隠蔽 (JAX-RSランタイムの中の json read/write 時に利用) – Servlet コンテナのコネクタ実装としてのNIOで十分では?
  22. 22. JMS2.1 現在のステータス: Early Draft Review JSR-368 https://jcp.org/en/jsr/detail?id=368
  23. 23. JMS2.0 Java EE 7 - JMS2.0のMDBを振り返る @MessageDriven( activationConfig = { @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty( propertyName="destination", propertyValue="java:/queue/myQueue") }) public class SampleMDB implements MessageListener { @Override public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
  24. 24. @MessageDriven( activationConfig = { @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty( propertyName="destination", propertyValue="java:/queue/myQueue") }) public class SampleMDB implements MessageListener { @Override public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } } JMS2.0 Java EE 7 - JMS2.0のMDBを振り返る 何のリスナ (Queue or Topic)を 文字列で指定する必要がある
  25. 25. @MessageDriven( activationConfig = { @ActivationConfigProperty( propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty( propertyName="destination", propertyValue="java:/queue/myQueue") }) public class SampleMDB implements MessageListener { @Override public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } } JMS2.0 Java EE 7 - JMS2.0のMDBを振り返る インタフェースの実装、 Messageのキャストが必要
  26. 26. JMS2.1 JMS2.1の主な機能追加 • MDBからMessageListenerの実装を不要とする • タイプセーフ • キャストの不要化 • 1クラスで複数コールバックメソッドを実装
  27. 27. JMS2.1 JMS2.1ドラフト: @JMSQueueListener @MessageDriven public class SampleMDB { @JMSQueueListener (destionationLookup = “java:/queue/myQueue”) public void printMessage(TextMessage text) { try { System.out.println(text.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
  28. 28. @MessageDriven public class SampleMDB { @JMSQueueListener (destionationLookup = “java:/queue/myQueue”) public void printQueue1Msg(TextMessage text) { …. } @JMSQueueListener (destionationLookup = “java:/queue/myQueue2”) public void printQueue2Msg(TextMessage text) { …. } } JMS2.1 JMS2.1ドラフト: 1クラスに複数コールバック定義
  29. 29. • MDB停止中のトピック書き込みは検知できない • JMS2.0では @ActivationConfigProperty( propertyName="subscriptionDurability“, propertyValue="NonDurable") @MessageDriven public class SampleMDB { @JMSNonDurableTopicListener(destinationLookup=“java:/topic/myTopic”) public void printMessage(TextMessage text) { …. } } JMS2.1 JMS2.1ドラフト: トピック向け非永続化サブスクライバ
  30. 30. @MessageDriven public class SampleMDB { @JMSDurableTopicListener ( destinationLookup=“java:/topic/myTopic”, cliendId=“someid”, subscriptionName=“somename”) public void printMessage(TextMessage text) { …. } } • 全永続化サブスクライバの受信までメッセージ削除されない • JMS2.0では @ActivationConfigProperty( propertyName="subscriptionDurability“, propertyValue="Durable") @ActivationConfigProperty(propertyName=“clientid”, propertyValue=“someid”) @ActivationConfigProperty(propertyName="subscriptionName", propertyValue=“somename") JMS2.1 JMS2.1ドラフト: トピック向け永続化サブスクライバ
  31. 31. JMS2.1 まとめ • 今のところはMDBのシンプル化が主な内容 • CDI管理Beanによるメッセージ受信は検討中 (Early Draft Review1には含まれていない)
  32. 32. JPA2.2 現在のステータス: ドラフト未リリース JSRなし (状況はJIRA参照https://java.net/jira/browse/JPA_SPEC)
  33. 33. JPA2.2 検討中の主な項目 • Java SE 8対応 • Date and Time API への対応 • @NamedQueryのRepeatableアノテーション対応 • スクロール機能の標準化 • 例: org.hibernate.ScrollableResults
  34. 34. JPA2.2 スクロール機能の標準化 - getStreamResult() Query q = em.createQuery(“select e from Employee e”); // OutOfMemoryError ?? List<Employee> employees = q.getResultList(); // 少ないJavaヒープメモリで動作 int total = q.getStreamResult().collect( Collectors.summingInt(Employee::getSalary));
  35. 35. Java EE 8 スケジュール Java EE 8 & GlassFish5リリースは2017上半期予定 • 2015 Q4 Early Draft • 2016 Q1 Public Review • 2016 Q4 Proposed Final Draft • 2017年上半期 Final 予定
  36. 36. Java EE 周辺の話 Spring Boot風 Java EE “WildFly Swarm”
  37. 37. WildFly Swarm Java EE で java -jar myapp.jar 起動 • Spring Boot風のJava EE • 2015/5 に1.0.0.Alpha1リリース – まだ実験的: (最新) 2015/10/25 1.0.0.Alpha5 • APサーバの事前インストールが不要になる • java -jar myapp.jar で手軽に起動
  38. 38. なぜ WildFly Swarm Spring Bootとは少し背景が違う • Spring Bootの背景 (集約) • 機能が豊富で、pom.xml の組み合わせ方法が難しい => 推奨組み合わせを作って、簡単に使えるようにした • WildFly Swarmの背景 (分解) • Java EE をフルセットで使う人は少ない => アプリで利用する機能だけ一式jarにまとめて軽量化
  39. 39. Hello World! 1. 利用したい機能をpom.xmlに記述 <dependencies> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>wildfly-swarm-jaxrs-weld</artifactId> <version>${version.wildfly-swarm}</version> </dependency> <dependency> <groupId>org.wildfly.swarm</groupId> <artifactId>wildfly-swarm-jpa</artifactId> <version>${version.wildfly-swarm}</version> </dependency> </dependencies> JAX-RS & CDI JPA 組み込みH2の起動 データソースExampleDS追加
  40. 40. Hello World! 2. uber jar を作成する wildfly-swarm-plugin <plugin> <groupId>org.wildfly.swarm</groupId> <artifactId>wildfly-swarm-plugin</artifactId> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin> • Mavenプラグインによりmvn packageで実行可能jarを生成
  41. 41. Hello World! 3. 通常と変わりなくコードを書く @Path("/") public class EmployeeResource { @Inject EntityManager em; @GET @Produces("application/json") public List<Employee> get() { return em.createNamedQuery("Employee.findAll", Employee.class) .getResultList(); } }
  42. 42. Hello World! 4. アプリケーションの起動 • デフォルト設定利用時はmainメソッド不要 • mvn package; java -jar target/xxx-swarm.jar – 必要なモジュールのみjarにまとめられる – JAX-RS+CDI+JPAアプリで94MB(WildFly全体約127M)。まだ大きい。 • サンプルコードが豊富 – https://github.com/wildfly-swarm/wildfly-swarm-examples
  43. 43. Hello World! カスタム設定はmainメソッドに実装 public static void main(String[] args) throws Exception { Container container = new Container(); / /H2向けJDBCドライバの登録と、データソースの生成 container.fraction(new DatasourcesFraction() .jdbcDriver("h2", (d) -> { d.driverDatasourceClassName("org.h2.Driver"); d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource"); d.driverModuleName("com.h2database.h2"); }) .dataSource("MyDS", (ds) -> { ds.driverName("h2"); ds.connectionUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;... "); ds.userName("sa"); ds.password("sa"); }) ); ....
  44. 44. Hello World! カスタム設定はmainメソッドに実装 public static void main(String[] args) throws Exception { Container container = new Container(); / /H2向けJDBCドライバの登録と、データソースの生成 container.fraction(new DatasourcesFraction() .jdbcDriver("h2", (d) -> { d.driverDatasourceClassName("org.h2.Driver"); d.xaDatasourceClass("org.h2.jdbcx.JdbcDataSource"); d.driverModuleName("com.h2database.h2"); }) .dataSource("MyDS", (ds) -> { ds.driverName("h2"); ds.connectionUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;... "); ds.userName("sa"); ds.password("sa"); }) ); ....
  45. 45. デフォルト設定を調べるには Fraction: WildFlyのサブシステムのようなもの • Swarmのソースより、xxxFraction.java クラスの中を確認 – デフォルト値はWildFlyの設定値 (standalone.xml) とほぼ同じ public class JPAFraction extends JPA<JPAFraction> implements Fraction { ... @Override public void initialize(Container.InitContext initContext) { if (!inhibitDefaultDatasource) { final DatasourcesFraction datasources = new DatasourcesFraction() .jdbcDriver(new JDBCDriver("h2") .driverName("h2") .driverDatasourceClassName("org.h2.driver") .....
  46. 46. 主なFraction Java EE 以外からも機能を取り込み • Java EE : JAX-RS, JSF, JPA, CDI, Transaction, JMS ... • logstash • サーバログをlogstashサーバ(TCP)に送る機能 • java -Dswarm.logstash.hostname -Dswarm.logstash.port • Netflix OSS(Ribbon, Hystrix), Jolokia (JMX REST-API) • 一覧はSwarmユーザガイド参照 https://wildfly-swarm.gitbooks.io/wildfly-swarm-users-guide/
  47. 47. SwarmによるJava EEの分解を見て Java EE にもマイナーアップデートが欲しい • Spring Frameworkは着実に進化 – 4.0 (2013/12) => 4.1 (2014/9) => 4.2 (2015/7) • Java EE は標準化に時間が掛かる – Java EE 7 (2013年) => Java EE 8 (2017年予定) – 実装サーバは仕様がFinalになってから1年ぐらい後 – 例えば JCache + MVC + Java 8 RepetableAnnotation 対応で Java EE 7.1 など
  48. 48. まとめ
  49. 49. まとめ • Java EE 8 は2017年リリース予定 – HTTP/2対応、非同期、APIのシンプル化 – 徐々にではあるが、検討が進み始めている • Java EE 周辺 – WildFly Swarmの進化に期待

×