Upgrade to Pro — share decks privately, control downloads, hide ads and more …

これからのJavaの話をしよう

 これからのJavaの話をしよう

社内向けにJava9で導入されたModule SystemとJavaのロードマップに関して説明する際に使用した資料です。発表時と現在とで仕様に差分があるかもしれない点と、私もまだ学習中の身ですので、誤って理解している箇所があるかもしれない旨ご容赦ください。

TakaakiSuzuki

January 30, 2018
Tweet

More Decks by TakaakiSuzuki

Other Decks in Technology

Transcript

  1. リリースサイクルが変わる(予定) 9 Java SEは6ヶ月毎にリリースされる ‘18 ‘19 ‘20 ‘21 ‘22 ‘23

    ‘24 ‘25 9(←今ココ) 10(←次ココ 2018/3) 11(← ココから OracleのLong Term Supportが可能になる※9と10はない) ・・・ ・・・ OpenJDKとOracleJDKのソースコードは2018後半ころに差分がなくなる(と言われている) ‘26 ‘27 Premier support(5年) extended support(3年) Sustaining support(無期限)
  2. “もう少し先”のJava(JDK Project) 12 ØJigsaw (Java 9で導入済み) • Javaのモジュール化に関する仕様変更 ØValhalla •

    データ型に関する仕様追加 ØPanama • JVMや外部コード(native code)に関する仕様変更 ØAmber • Javaの文法の改善
  3. JPMS(Java9〜) 14 JPMSはJavaのモジュール化に関する仕様 ‣The Java Platform Module System(JSR 376) •

    2005年頃から議論されてきた ‣Project Jigsaw(JEP 200, 201, 220, 260, 261, 282)
  4. モジュール化が提供する機能 15 xxx.jar(ライブラリを提供する側) 外部に使わせたいクラスたち package xxx.aaa - public class A

    - public class B 外部に触ってほしくないクラス Package xxx.bbb - public class C - Public class D yyy.jar(ライブラリを利用する側) ①適切なインタフェース定義 外部公開するパッケージの明示 公開先の明示 module-info.java import xxx.aaa.A import xxx.aaa.B import xxx.bbb.C import xxx.bbb.D module-info.java ③明示的な依存関係の宣言 利用するモジュールを明示 ②強いカプセル化 公開しているパッケージ以外は Reflectionでもアクセスできない。(※) public修飾子はあくまでもモジュー ル内でのpublicアクセスを許可する ※JVMオプション指定で回避可能
  5. 3種類のModule 16 Moduleの種類 参照先 特徴 Unnamed Module classpath ü 実行環境をJava9にしただけ

    ü Module化の恩恵を受けないため、移行は比較的スムーズ Automatic Module modulepath ü 全てのパッケージがexportsされる(module-info.javaがない) ü 既存Javaライブラリは大体コレになる Named Module modulepath ü 依存関係を記載するmodule-info.javaが存在する ü 単にmoduleというとこれを指す classpath modulepath Unnamed module Automatic module Named module xxx.jar yyy.jar zzz.jar ※CLIオプション追加で参照を追加することは可能 module-info.javaあり module-info.javaなし
  6. モジュール化とクラスの読み込み 17 Java8以前やUnnamed moduleの場合 classpath上のクラスをClassLoaderが読み込む 今まで classpath jar jar jar

    jar jar jar jar jar jar jar jar jar 同じクラスが存在する場合には ClassLoaderが先に読み込んだものを使う (実行時例外の原因)
  7. モジュール化とクラスの読み込み 18 Named moduleの場合 mainとなるmoduleをrootとしてmodulepath上のクラスをClassLoaderが読み込む これから modulepath jar jar jar

    jar jar jar jar jar jar jar jar 同じパッケージが 別モジュールに存在する場合 エラーになる 今まで classpath jar jar jar jar jar jar jar jar jar jar jar jar
  8. Java 9 移行までの4ステップ 22 Step:1 Java9の移行方法の学習 Step:2 依存ライブラリの バージョンアップ Step:3

    Unnamed Moduleとして対応 Step:4 Named Moduleとして対応 Java 8 Java 9 Java 9 未完
  9. 1. Java 9の移行方法の学習 23 先人からJava 9へのマイグレ方法を学ぶ ‣Virtual Java User Group(VJUG)の動画を見る

    ‣ハンズオンで移行方法を実践する ‣並行して「Java 9 Modularity」を読む
  10. 2. 依存ライブラリのバージョンアップ 24 Java 8でバージョンアップ可能なライブラリはやってしまおう ライブラリ(略称) 変更前 Ver. 変更後 Ver.

    Java 9対応 Ver. spring-boot 1.4.5.RELEASE 1.5.9.RELEASE 2.0.0(未リリース) spring-boot-starter- velocity 1.4.5.RELEASE - 非対応 spring-boot-starter- thymeleaf - 1.5.9.RELEASE 2.0.0(未リリース) jmockit 1.24 1.37 1.33 lombok 1.16.18 1.16.18 1.16.19 commons-io 2.5 2.6 2.6 jackson 2.8.0 2.9.2 2.9.1(?) mariadb-java-client 2.2.1 2.2.1 2.x gradle 2.13 4.4 未定 赤字=差し替えたライブラリ
  11. 3. Unnamed Moduleとして対応 25 Step ①コンパイラのバージョンを変更 sourceCompatibility = 1.8→9 targetCompatibility

    = 1.8→9 ②コンパイルエラーを修正する options.compilerArgs += [ "--add-modules=java.xml.ws", "--add-modules=java.xml.ws.annotation", "--add-modules=java.xml.bind", ] ③単体テストの実行 振る舞いに変更がないかチェック ④アプリケーションの起動 ./gradlew bootRun (Spring Boot Gradle Pluginを使用する場合) または java –jar コマンド ⑤結合テストの実行 外側から見た振る舞いに変更がないかチェック ここまで到達すると「動作環境」がJava 9 (モジュール化はされていない) Java EEの一部パッケージが除外になったため、 JVMオプションへの明示的な追加が必要。 (プロジェクト毎に異なる) Point 以降はIDEではなく、ビルドツールのCLIコマンドを使って動作 確認をした方が良い モジュール化に向けて、Unnamed Moduleの状態でも テストがパスするように整備しておく Javaのプロセスを確認して、classpathでjarを読み込んでいる ことを確認する JVMのその他の起動引数もここでチェック
  12. 4. Named Moduleとして対応 26 Step ①パッケージ構成の変更 (逆DNS名) → (モジュール名).(逆DNS名) ②module-info.javaの作成

    パッケージルートにファイルを置く module clarisse.common.main { exports clarisse.common.main.xxx.xxx; requires tomcat.annotations.api; requires tomcat.embed.core; } ③module-pathを参照させる javaオプション的には--classpath → --module-path options.compilerArgs += [ “—add-modules”, “xxxxxxx”, "—module-path”, classpath.asPath, ] classpath = files() ④ビルドファイルを修正しコンパイル ./gradlew clean compileJava 実行時にReflectionが必要なもの(Dependency Injection) はパッケージを opens 指定する Point モジュール名とパッケージ構成は依存関係 classpath上のクラスを読み込まないように注意 依存ライブラリがAutomatic ModuleかNamed Moduleか注意 複数モジュール間でのパッケージ重複に注意 ※今回はspring-boot-starter-webの依存ライブラリ Springboot 2.x.x 対応待ち
  13. これからのJavaへの対処 29 これからのJavaは ‣ロードマップに要注意 • 世間が追従できるのか? • “脱・重量級言語”に向けた改修が今後も入ってくる? ‣JPMSが一つの壁 •

    JPMSほど大きな改修が必要な仕様変更はなさそう Module Systemへのマイグレの目処が立った ‣依存ライブラリの対応状況のウォッチ大切 • ライブラリ側のマイナーバージョンアップも入るので早めの動作確認を ‣ライブラリ同士の依存関係をより意識する構造になっている • どこかのタイミングでビルドツールがよしなにやってくれることに期待
  14. Java使いに残された道 30 1. Javaの仕様変更に追随していく ‣ 追随していくだけのスキルと体力が必要かも 2. ベンダー(Oracle)サポートを受けて延命 ‣ 単純明快!札束解決!

    3. サポートが切れたJavaと共に心中する ‣ EoL/EoS確定のサービスなら、まぁ。。 4. Javaを卒業する ‣ 言語も適材適所。ただし、次の言語も勉強必要よ。
  15. 余談:Pythonは壁を超えた 31 後方互換性を損なう言語仕様変更の前例 ‣2008: Python 3.0 ← 1st release ‣2012:

    Python 3.3 ← 言語仕様が安定し「そろそろいいかもね」と言われだした頃 ‣2016: Python 3.6 ← syntaxの改善や実行環境の高速化 ‣2017: クラウドベンダー が 3.xをサポート ‣2020: Python 2.x サポート終了(予定) 今でもPython 2.7系は根強く利用されているが、3.xからのバックポートがあった。 移行の妨げ要因 1. 言語仕様が不安定(頻繁な変更、パフォーマンスの問題) 2. 既存のライブラリが使えなくなる可能性がある 3. 周辺のエコシステム側が旧バージョンとの依存が強いこと
  16. 参考資料 32 Java SE 9の紹介: モジュール・システムを中心に https://www.slideshare.net/miyakawataku/introduction-of-java-se-9-and-the-module-system MVC 1.0 を通じて

    Adopt a JSR を知ろう! https://www.slideshare.net/miyakawataku/adopt-a-jsr-jjug ヌーラボのアカウント基盤を Java 9 にマイグレーションして起きた問題と解決法 https://nulab-inc.com/ja/blog/nulab/java9-migration/ JDK Project (OpenJDK) http://openjdk.java.net/projects/jdk/