Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

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

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Wird geladen in …3
×

Hier ansehen

1 von 49 Anzeige
Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (19)

Anzeige

Ähnlich wie JavaOne2015報告会 Java EE アップデート #j1jp (20)

Anzeige

Aktuellste (20)

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の進化に期待

×