![画像](https://habrastorage.org/getpro/habr/post_images/f4b/ece/954/f4bece954ed0e3ed290e0b1e6880740d.png)
カットの下で私たちを待っている痛みの種類を知ることができます。
Javaプロジェクトを8番目のバージョンから9番目または10番目に移行する際に発生する可能性のあるすべての問題をここに記載するつもりはありません。 同僚との口頭での話し合い以外の何らかの形で、Javaの新しいバージョンとの最初のコンタクトの小さな経験を修正したいと思います。 たぶん彼
![画像](https://habrastorage.org/getpro/habr/post_images/348/c0d/5cc/348c0d5cc2c7d40417b4c863f1843125.jpg)
まず、IDEAバージョン2018.1は、JVMバージョン9および10と2つの異なるマシンでの動作を拒否しました。 GUI要素の一部がなく、残りの要素の一部にテーマがないように見えました。 IDEAは実行する特定のJVMを指定できるため、これは小さな問題でした。
1.モジュール性の実装に関する問題
始めるために、アプリケーションをモジュール化しましょう(JDK開発者がJigsawプロジェクトを試してみて苦しんだのは、何のためでもありませんでした)?
1.1。 jdepsユーティリティの問題
既存のクラス階層からjavaモジュールを取得するには、次のものが必要です 。
- モジュールの名前、依存関係、エクスポートされたパッケージを1つ以上のmodule-info.javaファイルに書き込みます
- コンパイラに引数を追加します(--module-pathなど)
![画像](https://habrastorage.org/getpro/habr/post_images/049/e11/0fb/049e110fb509e3d6f49e2a63a4a82452.gif)
一見、すべてが非常に単純なようです。
1.1.1。 外部ライブラリの依存関係は、特別なスペルなしでは機能しなくなりました
ただ一緒になるものは何もありません。 モジュラーアプリケーションを構築する場合、依存関係もモジュラーでなければなりません。 そうしないと、単にmodule-info.javaに追加できません。 より正確には、追加できます-ライブラリの昔ながらのjarファイルは、いわゆる「自動モジュール」と見なされます。 ただし、問題は、アセンブリ中に自動モジュールを使用できないことです。 はい、これまで人気のあるリポジトリにモジュールとしてコンパイルされたライブラリは非常に少なく、使用することはできません。 誰も気にしません。
これはjdepsユーティリティが必要だった場所です。jdepsユーティリティはjarファイルを解析し、古いファイル形式のjarからモジュールを作成するためのmodule-info.javaを生成できます。 回避策として、すべての依存関係を1つのヒープに展開し、すべての依存関係を持つファッショナブルなモジュールを作成できる単一のjarを作成することが決定されました。 stackoverflowの例が添付されています。
1.1.2。 実際に必要な依存関係よりもはるかに多くの依存関係を含める必要があります
Jdepsは依存関係を再帰的に解決し、Maven / Gradleがオプションと見なす偶数の依存関係の必須の解決を必要とします。 その結果、小さな実験プロジェクトの依存関係ツリーも数回成長します。 パラグラフ(1.1.1)で製造することが決定された依存関係のあるモジュールは
1.1.3。 予期しないパブリック[Roskomnadzor]ユーティリティ
いくつかのクラスが異なるモジュールに複製されている状況では、jdepsはコードの深さのどこかからIllegalStateExceptionスタックレースで抜け出し、何が問題なのかを説明しませんでした。 1つの小さな手がかりは、例外のコンストラクターへの引数としてのメッセージ「自己依存」です。 ある時点で、この不名誉は 、すべて(アプリケーションクラス、依存関係クラス、「オプション」の依存関係のクラス)を1つのjarファイルにダンプする必要があるという事実を暗示しているように思えました 。 そして本当に-それは働いた。
1.2。 ランタイムの問題
すべてがすでに奇跡的に組み立てられていたとしても、モジュール式アプリケーションと、そのためのカスタムJREイメージでさえ、最も重要な驚きがまだ来ていないことが判明しました。 つまり、実行時です。
1.2.1。 これで、開始ファイル/ディレクトリへのパスを決定することは不可能です
Javaアプリケーションでは、多くの場合
Main.getProtectionDomain().getCodeSource().getLocation().toURI()
Javaの新しいバージョンではこの呪文が機能しなくなり、ファイルパスの代わりに「jrt://com.example.myapp」のようなものが表示されることを発見したときの驚きを想像してください。 私は熱心にグーグルで探し始め、スタックをオーバーフローさせました。 モジュールを特定し、どのファイルがそのモジュールに属しているのかを何らかの方法で把握しようとしました。 クラスパスにアクセスしようとしても、私は何もしませんでした。アプリケーションは、昔ながらのクラスパスではなく、いわゆるモジュールパスでモジュール式に起動されるからです。 フィニッシュでした。 その瞬間、Java 10に移行する際の実験を最小限に抑えることにしました。もちろん、コマンドラインでディレクトリにパスを渡すことも、正しいディレクトリからのみユーザーを強制的に実行することもできます。 しかし、私自身は、今のところ十分であると個人的に決めました。
1.2.2。 ファイルのMIMEタイプを判別しようとしたときの失敗。
ケーキの上のチェリーは一人ではないことが判明しました。 トップ10での実験のために、それをインストールし、システムのデフォルトJVMとして構成しました。 したがって、驚きは続きました。 のようなコード
final String mimeType = Files.probeContentType(itemInputFilePath);
引数が対応する拡張子を持つ通常のCSVファイルである場合、nullが返されるという事実につながり始めました。 「どのように?」と思ったのですが、「JVMは通常のCSVファイルのMIMEタイプを判別できませんか?」 私は少し物beいでした
Files.readAllLines("/etc/mime.types", Charset.defaultCharset())
「不正な入力」のようなメッセージで小さな例外をスローします。
この不名誉の理由については、私はまだ始めていませんでした。 /etc/mime.typesファイルを確認しました
1.2.3。 壊れた新しいサービスプロバイダーメカニズム
バージョン9以降、Javaは、古いサービスプロバイダーを置き換える新しいサービスプロバイダーメカニズムも提供します。 悪いことではなく、実行時に許可されるプラグインを作成できます。 新しいメカニズムでは、キーワード「provides」および「with」を使用してmodule-info.javaで拡張子を宣言します。 それは簡単かもしれません。 実際には、古いメカニズム(リソース/ META-INF / services / ...ファイルを使用)とは異なり、これは機能しませんでした。 時間の問題が十分ではなかったことを理解してください。 しかし、特別な呪文なしではうまくいかないというマークは、おそらくここでやるでしょう。
2.ローカル変数型推論の実装に関する考察
ローカル変数型推論の場合、Scalaの影響を示唆する新しいキーワード「var」(変数、変数)があります。 しかし、個人的には「val」(値)も追加しなかった理由は個人的には奇妙に思えました。 代わりに、「final var」を記述する必要があります。これは「final variable」または「constant variable」として目で読み取られます-これは簡潔さだけでなく、私の意見
かなり面白いものもいくつか登場しました。 例:
final var someStrings = new ArrayList<String>();
ここで、JVMは「someStrings」という名前のArrayList <String>を「記憶」しています。
final var someStrings = (List<String>) new ArrayList<>();
しかし、すでにどういうわけか非常に簡潔ではないように見えます。 この瞬間は、いくつかの致命的な欠陥のタイトルのふりをするものではありませんが、わずかな一貫性のなさを示しています。
3.残念な結論
このノートで表明された問題のいくつかは、9番目のバージョンで発生しました。 それらが今まで修正されていないことを考えると、この混乱全体が第11バージョン以降にあるという不快感があります。 私はクリックしたくありませんが、この主観的な感覚から何かが続きます。プログラミング言語としてのJavaは衰退を経験し始めます。 たぶん私は間違っているかもしれませんが、多分そうです。Javaを置き換えるには、別のツールを探す必要があります。
更新
残念ながら、私はメモリから書き込みますので、いくつかの詳細が欠落しています。 私はまた別の素晴らしいことを思い出しました。 これはannotashka sun.misc.Contendedで、8番目のバージョンに登場し、その後のバージョンでは安全に飲まれました。 彼女の短い人生にもかかわらず、彼女は使用されたライブラリの 1つに入ることができましたが、これも多くのトラブルを引き起こしました。 それは10-keではなく、あなたが望むことをしますが、クラスへのリンクがあるため、モジュールを構築するために必要です。 それはすべて、conversantmediaディスラプターライブラリが必須の依存関係ではないことを思い出して、ソースの空のクラスに必要なクラスを置き換えるだけでした。 そして、これは数がなかった小さなものの一つです...