2012-01-26 14 views
11

私がやろうとしているのは、特定のインターフェースの実装を探しているアプリケーションクラスをスキャンするいくつかのMavenプラグインを書くことです(いくつかの注釈を持つクラスかもしれません)いくつかのコードを生成します。私はプラグインをgenerate-sources段階で実行し、ソースコードをgenerated-sourcesディレクトリに書き込むことに成功しました。mavenプラグインのjavaクラスパスをスキャンする

問題は、いくつかの注釈を持つ特定のインタフェース実装/クラスのクラスパスをスキャンすることです。私は次のようにクラスをスキャンするReflectionsライブラリを使用しています :

残念ながら
private Set<Class< ? extends MyInterface >> scan(final String packageName) { 
    final Reflections reflections = new Reflections(packageName); 
    return reflections.getSubTypesOf(MyInterface.class); 
} 

、このメソッドは空のセットを返します。

/home/pd5108/apache-maven-2.2.1/boot/classworlds-:私は(私はReflectionsを使用していた内の同じ)org.apache.maven.plugin.AbstractMojoを拡張するクラスで私のクラスパスを印刷するとき、私は次のような結果を得ます1.1.jar

リフレクションを使用して検索したいクラスは、依存関係のあるJARおよびプラグインが設定されているモジュールに存在します。クラスパスを見ると、クラスパス上でまだ利用できないmavenで定義されたこの時点(生成元フェーズ)の依存関係がまだ存在しているようです。おそらくそれらは次のフェーズで追加されます。本当?私が使用できる他のアプローチはありますか?ここで

は、クラスパスがプリントアウトされるかの方法である:

URL[] urls = ((URLClassLoader)sysClassLoader).getURLs(); 

for(int i=0; i< urls.length; i++) { 
    System.out.println(urls[i].getFile()); 
} 

答えて

5

必要MOJOクラスのフィールド:すべての依存関係のJARファイルの

/** 
    * The project currently being built. 
    * 
    * @parameter expression="${project}" 
    * @readonly 
    * @required 
    */ 
    private MavenProject project; 

    /** @parameter expression="${localRepository}" */ 
    protected ArtifactRepository m_localRepository; 

    /**@parameter default-value="${localRepository}" */ 
    private org.apache.maven.artifact.repository.ArtifactRepository 
     localRepository; 

    /** @parameter default-value="${project.remoteArtifactRepositories}" */ 
    private java.util.List remoteRepositories; 

    /** @component */ 
    private org.apache.maven.artifact.factory.ArtifactFactory artifactFactory; 

    /** @component */ 
    private org.apache.maven.artifact.resolver.ArtifactResolver resolver; 

は、解像度:

final List<Dependency> dependencies = project.getDependencies(); 

    for (Dependency d : dependencies) { 

     final Artifact artifact = 
      artifactFactory.createArtifactWithClassifier(d.getGroupId(), 
       d.getArtifactId(), d.getVersion(), d.getType(), 
       d.getClassifier()); 

     try { 
      resolver.resolve(artifact, remoteRepositories, 
        localRepository); 
     } catch (ArtifactResolutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ArtifactNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     File artifactFile = artifact.getFile(); 
     System.out.println(artifactFile.getAbsolutePath()); 
    } 

そして今、我々は適切なクラスを探してリフレクションAPIを使用して、これらのJARをスキャンする必要があります。 私がgenerate-sourcesで作業しているので、次のフェーズのアーティファクト値はまだ計算されていないので、この時点では他の方法はないと思います。

-2

だけでプラグインの設定リストにあなたがに基づいてコードを生成したいクラスを持つことが容易/迅速/方が安全です。それからあなたはポンにそれを加えて、あなたは完了です。リフレクションは必要なく、プラグインの実行をスピードアップします。

+0

私は最後の手段として考えているオプションです。私はこのインターフェイスを実装するクラスがたくさんあり、それらのすべてがコード生成で考慮されているので、それらをすべて静的に入力しないようにしたいと思います。また、これらのクラスは頻繁に追加/削除されます。 –

+0

"implements X"用のgrep all javaファイルのようなことをしたシェルスクリプトをいつでも持っていて、クラス名を解析してそれらのプロパティファイルを構築できます。次に、あなたのプラグインがそのプロパティファイルを使用して、どのクラスが余分なコードを生成するのかを知ることができます。あなたがUNIX上でなければ、私が想定しているJavaでgrepをエミュレートできますが、それはずっと遅くなります。 – Michael

1

<dependencies>セクションに定義されているアーティファクトの依存関係と、<plugin><dependencies>の下に定義されたプラグインの依存関係があります。

プラグインの依存関係がクラスパスに追加されますが、アーティファクトの依存関係についてはわかりません。 <plugin><dependencies>の下にプラグインの依存関係を追加しようとしましたか?

+0

あなたの助言によると、私は 'プラグインの依存関係'を追加しましたが、クラスパスの下では表示されません(奇妙なことですが)Reflectionsライブラリは、MyInterfaceを正しく実装するクラスを検出します。プラグインの依存関係にアーティファクト依存関係を含めることができる方法はありますか?/ –

+1

@PiotrekDe POMとプラグインの両方に依存するすべての必要な依存関係を持つjarプロジェクトを作成することができます。私はそれが痛みの価値があるとは確信していません... –

関連する問題