2017-07-12 17 views
1

注釈プロセッサのinit(ProcessingEnvironment)メソッド内からのServiceLoaderの使用は可能ですか?注釈プロセッサ内でのServiceLoaderの使用

interface Service {} 

class AnnotationProcessor extends AbstractProcessor { 

    public static void main(String[] args) { 
     ServiceLoader<Service> loader = ServiceLoader.load(Service.class); 
     System.out.println("Found Services:"); 
     for (Service service : loader) { 
      System.out.println(service); 
     } 
    } 

    @Override 
    public synchronized void init(ProcessingEnvironment env) { 
     super.init(env); 

     ServiceLoader<Service> loader = ServiceLoader.load(Service.class); 
     System.out.println("Found Services:"); 
     for (Service service : loader) { 
      System.out.println(service); 
     } 
    } 

    ... 
} 

メインメソッドを実行すると、META-INF/servicesファイルで指定したサービスが生成されます。ただし、init(ProcessingEnvironment)メソッドが別のプロジェクトのビルドの一部として呼び出された場合、そのサービスはリストされません。

これを行う方法はありますか?

+0

あなたはもう少しあなたのセットアップについて説明することはできますか?どのようなプロジェクトがありますか?あなたのサービスはどこに定義されていますか?短い答え、はい、それは可能でなければなりません。しかし、META-INF/servicesファイルがあなたのクラスパス上にない理由を理解する必要があります。メインメソッドを実行するときのクラスパスは何ですか? – jbunting

+0

私はMavenを使ってプロジェクト間のすべての依存関係を処理していますので、クラスパスはちょっと魔法です。私はそれを掘り下げ、私はより良い答えを考え出すことができるかどうかを見ます。 – bnorm

+0

何か興味深いと思ったことは、注釈プロセッサーからプロセッサー・サービス(注釈プロセッサーのように)をロードしたときに空のリストも得られたことです。私は注釈プロセッサーにいるので、クラスパスが正しくセットアップされていることがわかります! – bnorm

答えて

4

問題はServiceLoaderはmain方法からMETA-INF\services注釈プロセッサの中からファイルができますが、を見ることができないのClassLoaderが指定されていないThread.currentThread().getContextClassLoader()を使用しています。

ServiceLoader.load(Service.class, AnnotationProcessor.class.getClassLoader())を使用すると、AnnotationProcessor内からサービスが正しくロードされます。

(ContextClassloaderとはMETA-INF\servicesを見ることができない理由を知っていれば私の答えに追加するにはお気軽に)

+0

チップをありがとう。時間を節約しました。 –

関連する問題