7

I have the following code:

private static CtClass resolveCtClass(String clazz) throws NotFoundException {
  ClassPool pool = ClassPool.getDefault();
  return pool.get( clazz );
}

When running under JDK8, if this method is called using java.io.Serializable, it works, but when running under the JDK9 environment, it throws the NotFoundException.

Is there something I overlooked here?

4

2 に答える 2

7

これは、Java 9 の現在の EA ビルドでは発生しなくなりました。モジュールにカプセル化されている場合でも、クラス ファイルは常に検索可能になりました。

ClassLoaderこれは、エクスポートされていないリソースがAPI経由で使用できなくなった Java 9 のモジュール カプセル化の結果です。裏では Javassist が呼び出します

ClassLoader.getSystemClassLoader().findResource("java/io/Serializable.class");

のクラスファイルを取得しますSerializable。次に、このクラス ファイルを解析し、Java リフレクション API と同様に情報を表しますが、ロードする前に編集できるようにクラスをロードしません。

Java 8 まで、このクラス ファイルはアクセス可能でした。ほとんどのクラス ローダーは、上記の呼び出しがファイルへのポインタを返すように、クラス ファイルをロードする前にルックアップに依存していたURLためです。findResource(String, String)Java 9 以降、名前付きモジュールのリソースは、2 番目の引数がそのクラスのモジュールに名前を付ける新しい API メソッドを介してのみ利用できます。

簡単に言えば、Javassist は Java 9 で動作しなくなり、その依存プロジェクトも動作しなくなります。これは、現在の Java 9 実装の既知の問題であり、リリース前に修正されることを願っています。

于 2016-06-19T08:52:52.913 に答える
1

(私は Javassist を使用したことがないので、ここでは暗闇で撮影しています...)

ドキュメントにClassPoolは次のように書かれています。

このget()オブジェクトに対して が呼び出されると、 で表されるさまざまなソースClassPathを検索してクラス ファイルを見つけ、そのクラス ファイルを表すオブジェクトを作成しCtClassます。

これは、クラスパスの概念に縛られているようです。見て、その仮定ClassPathをサポートします。CtClass

その場合、Javassist は JDK 9 の真新しいモジュールを調べるのに適していない可能性があります。

私の推測が正しければ、プールから JDK クラスを取得することはできないはずです。これは簡単に検証できるはずです。

于 2016-06-18T07:28:04.643 に答える