1. ホーム
  2. java

[解決済み] 不正な反射型アクセスとは?

2022-02-11 07:29:21

質問事項

Java 9 の不正な反射アクセスに関する質問が多くあります。

エラーメッセージを回避する方法については多くの議論がありますが、不正な反射アクセスとは実際にどのようなものなのかを知りたいです。

そこで質問なのですが

不正な反射アクセスの定義と、どのような状況で警告が発生するのでしょうか?

Java 9で導入されたカプセル化の原則と関係があることはわかりましたが、それがどのように組み合わされ、何が警告の引き金となり、どのようなシナリオになるのかについての説明が見当たりません。

解決方法は?

モジュールとそれぞれのパッケージ間のアクセスについて理解することは別として。私は、この問題の核心は モジュールシステム#Relaxed-strong-encapsulation そして、その中から関連する部分を抜き出して、質問に答えようとするのです。

<ブロッククオート

不正な反射的アクセスの定義と、どのような状況か 警告が出るきっかけは?

Java-9への移行を支援するために、モジュールの強力なカプセル化を緩和することができる。

  • 実装は 静的アクセス つまり、コンパイルされたバイトコードによるものです。

  • のコードにオープンなモジュールの1つまたは複数のパッケージで、そのランタイムシステムを呼び出す手段を提供してもよい。 すべての無名モジュール つまり、クラスパス上のコードに対してです。ランタイムシステムがこの方法で呼び出され、 そうすることによって、そうでなければ失敗したであろうところで、 リフレクションAPIのいくつかの呼び出しが成功するならば、です。

そのような場合、実は、あなたが作ってしまった リフレクティブアクセス という "違法"。 純粋なモジュールの世界では、このようなアクセスは想定されていなかったからです。

どのような仕組みで、どのような場合に警告が発生するのでしょうか。 シナリオは?

このカプセル化の緩和は、新しいランチャーオプションによって実行時に制御されます。 --illegal-access と同じで、Java9ではデフォルトで permit . そのため permit モードは

このようなパッケージに対する最初の反射アクセス操作によって という警告が出ますが、それ以降、警告は出ません。 この1つの警告は、それ以降の警告を有効にする方法を説明しています。この 警告を抑制することはできません。

モードは値で設定可能です debug (メッセージと、そのようなアクセスごとのスタックトレース)。 warn (そのようなアクセスごとのメッセージ)、および deny (そのような操作を無効化する)。


アプリケーションのデバッグと修正のためのいくつかの事柄は、以下の通りです。

  • で実行します。 --illegal-access=deny について知り、回避するために オープン を含むモジュール宣言なしに、あるモジュールから別のモジュールへパッケージを移動させることができます ( opens を明示的に使用するか --add-opens VM arg.
  • コンパイルされたコードから JDK 内部 API への静的な参照は jdeps ツールを使って --jdk-internals オプション

不正な反射アクセス操作が行われた場合に表示される警告メッセージ が検出された場合、以下のような形式になります。

WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM

<ブロッククオート

のところです。

$PERPETRATOR を含む型の完全修飾名です。 当該反射的操作を呼び出したコードと、そのコード ソース(つまり、JARファイルのパス)がある場合は、そのソースと

$VICTIM は、アクセスされるメンバーを説明する文字列です。 囲んでいる型の完全修飾名を含む

このような警告例に対する質問: = JDK9: 不正な反射的アクセス操作が発生しました org.python.core.PySystemState

最後に重要なことですが、このような警告に直面しないように、また将来的に安全であるようにするために必要なことは、あなたのモジュールが違法な反射アクセスをしていないことを確認することです :)