Eclipseプラグイン・プロジェクトでJavaのクラスのメソッド・パラメータの名前をリフレクションで取得できない時の暫定対応メモ


Java8以降、クラスのコンストラクタを含むメソッドのパラメータ名をリフレクションを通して取得できるようになりました。javac-parametersオプションを追加してコンパイルすることで、これに必要な情報がクラスファイルに格納されます。

Eclipseにおいては、例えばJavaプロジェクトの場合、プロジェクト共通あるいはプロジェクト毎の設定において、以下のチェックを入れてエクスポートすることで、対応したjarを作成することができます。恐らく、チェックすることで、-parametersオプションが内部で設定されてコンパイルされるのだろうと思います。

簡略ですが、以下のような感じでコンストラクタやメソッドオブジェクトへの参照からリフレクションを使って、パラメータ名を確認することができます。

for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
    System.out.println("constructor: " + constructor.getName());
    for (Parameter param : constructor.getParameters()) {
        System.out.println("  param: " + param.getName() + ", type: " + param.getType().getSimpleName());
    }
}
for (Method method : clazz.getDeclaredMethods()) {
    System.out.println("method: " + method.getName());
    for (Parameter param : method.getParameters()) {
        System.out.println("  param: " + param.getName() + ", type: " + param.getType().getSimpleName());
    }
}

問題の症状

ところが、プラグイン・プロジェクトの場合、何故か、この設定が機能していないようで、エクスポートして作成したjar(というかバンドル)では、メソッドのパラメータ名は、arg0, arg1, arg2…となります。このような名前は、-parametersオプションを指定しない場合に、自動的に付けられるものです。なお、使用しているEclipse IDEは、Version: 2020-06 (4.16.0) Build id: 20200615-1200です。(多分、最新)

このことから、プラグイン・プロジェクトの場合、チェックを入れても、実際には-paramtersオプションが使用されずにコンパイルされているように見えます。なお、チェックを入れると、以下のファイルに次の一行が追加されます。

<プロジェクト>/.settings/org.eclipse.jdt.core.prefs

org.eclipse.jdt.core.compiler.codegen.methodParameters=generate

この設定が入ったプロジェクトでエクスポートすることで、メソッドのパラメータ名をリフレクションで取得可能なjarが作成されることが期待されます。

プラグイン・プロジェクトの場合、バンドルの依存関係を明示したMANIFEST.MFを作成して、手軽にOSGiバンドルを作成できて重宝なのですが、今回の件は、かなり不便に感じました。

暫定対応

そこで、一旦、プラグイン・プロジェクトで作成した、バンドルの依存関係を解決したMANIFEST.MFの雛形を、別途、そのプラグイン・プロジェクトと同一ソースのJavaプロジェクトを起こして、そこから参照させてOSGiバンドルを作成することにしました。(安易ですが)

以上、備忘録でした。(何か誤解しているかも?)