java.lang.class#getAnnotation()eclipseプラグインで呼び出されたときにnullを返します

StackOverflow https://stackoverflow.com/questions/8309444

質問

サポートするためにEclipseプラグインを書いています フリージ プログラミング言語。私は使用します インプ メタツーリングプラットフォームとEclipse Indigo(3.7)。実行時間環境はJava 1.7です。

プラグインは、トークンの解析、構文分析などのバッチコンパイラと同じコードを使用します。ただし、Eclipseプラグインから実行すると、以前のコンパイルされたモジュールのクラスファイルを読み取る次の方法にトレースしたときに、違いがあることに気付きました。 Javaアノテーションの形でそこに保管されているメタ情報を取得します。

public static MD.Operator[] getOperators(ClassLoader loader, String pack) 
                                              throws ClassNotFoundException {
    Class<?> cl = null;
    cl = loader.loadClass(pack);
    MD.FregePackage os = cl.getAnnotation(MD.FregePackage.class);
    if (os == null) return null;        // <-- no annotation present
    return os.ops();
}    

コードは独自のインスタンスを作成することに注意してください URLClassLoader, 、これは議論として渡されます。クラスパスを正しく設定しない場合、getoperatorsメソッドはClassNotFoundExceptionを正しくスローするため、クラスをロードすることを確認できると思います。トレースメッセージは、クラスローダーが次のパスで構築されていることを教えてくれます(これはデフォルトではクラスパスだけです):

mkClassLoader:[C:\opt\eclipse\plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar, X:\dev\frege\build]

Fregeコンパイラによって作成されていないクラスファイルには通常 MD.FregePackage 注釈これは通常、ユーザーがプレーンJavaクラスをインポートしようとしたことを示しており、実際、プラグインで次のメッセージを受け取ります。

X:/dev/runtime-EclipseApplication/TestJFrege/src/Neu.fr:1: `frege.prelude.Base` is not a frege package

それでも、コマンドラインからこれをうまくコンパイルできます。ここには、問題の注釈が実際に同じ場所からロードできるという証拠としてこれを含めました。

X:\dev\frege>java -cp ./build frege.compiler.Main X:/dev/runtimeEclipseApplication/TestJFrege/src/Neu.fr
mkClassLoader: [./build]
running: javac -cp ./build -d . -encoding UTF-8 ./Neu.java

事実を再開する:

  1. コンパイラがコマンドラインインターフェイスを介して呼び出されたときに、注釈をロードすることになっているコードは正常に機能します。
  2. 注釈をロードすることになっているコードは、プラグインまたはコマンドラインから呼び出されるかどうかはわかりません。実際、プラグインは先週まで存在しませんでしたが、コマンドラインインターフェイスは数か月間正常に動作していました。
  3. もちろん、注釈は RetentionPolicy.RUNTIME それ以外の場合は、コマンドラインコンパイルもそれらを認識しません。しかし、それは事前に行われます。

ですから、私が描くことができる唯一の結論はそれです Class.getAnnotation() どういうわけか正しく機能していません。これは非常に残念です。これは、モジュールシステムに必要な基本的な機能を効果的に破壊するためです。

これがとにかく重要な場合:Fregeコンパイラコードはプラグインが使用しています 自体 FregeとTheで書かれています frege.prelude.Base 上記のクラスは、すべてのモジュールが必要とする基本的なライブラリであるため、もちろん異なるクラスローダーを使用しても、プラグインのアクティブ化に既にロードされている必要があります。

誰かが同様の経験をしていますか?これを解決することは可能ですか?これを回避する方法は、大歓迎です。

役に立ちましたか?

解決

だった MD.FregePackage メソッドで使用されているクラスローダーによってロードされたクラス? 2つのクラスがそうではないので、おそらくそれを最初にロードしてみてください equal() それらが異なるクラスローダーでロードされた場合。それはなぜそれが見つからないのかを説明することができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top