2012-01-26 85 views
11

我想要做的是編寫一些Maven插件,它可以掃描應用程序類,尋找特定接口的實現(它也可能是帶有某些註釋的類),並根據結果生成一些代碼。我已經成功實現了在生成源代碼階段運行的插件並將源代碼編寫到生成的源代碼目錄。在Maven插件中掃描java classpath

問題是掃描具有某些註釋的特定接口實現/類的classpath。 我使用Reflections庫進行掃描以下列方式類:

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

不幸的是,這個方法返回空集。當打印我的類路徑中的類擴展org.apache.maven.plugin.AbstractMojo(同我使用Reflections在其中)我得到以下結果:

/home/pd5108/apache-maven-2.2.1/boot/classworlds- 1.1.jar

我想使用Reflections找到的類存在於依賴JAR以及插件配置的模塊中。查看打印出來的類路徑,似乎此時(maven中定義的生成源相位)依賴關係在classpath中都不可用 - 可能它們會在下一個階段添加。真的嗎?有沒有其他方法可以使用?

這裏是這樣的類路徑是如何打印出:

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

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

回答

5

要求MOJO類字段:

/** 
    * 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; 

所有依賴JAR文件的分辨率:

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

可能更快/更安全/容易只是有插件配置列表中,您要根據生成代碼的類。然後你只需將它添加到pom中,就完成了。不需要反思,它肯定會加速插件的運行。

+0

這是我認爲最後的選擇......因爲我有很多類實現這個接口,並且所有這些都在代碼生成中考慮,所以我想避免將它們全部靜態地輸入。另外,這些類經常被添加/刪除。 –

+0

你可以總是有一個shell腳本,它執行grep所有的java文件,用於「implements X」,然後解析類名並構建它們的屬性文件。然後讓你的插件使用該屬性文件來知道哪些類可以生成額外的代碼。如果你不在unix上,你可以在java中模擬grep,但它會慢很多。 – Michael

1

<dependencies>部分中定義了工件依賴關係,並在<plugin><dependencies>下定義了插件依賴關係。

插件依賴關係被添加到類路徑,而我不確定工件依賴關係。您是否嘗試在<plugin><dependencies>下添加插件依賴關係?

+0

根據你的建議,我添加了一個'插件依賴項',現在它在打印出來的類路徑下不可見(奇怪),但反射庫檢測到正確實現MyInterface的類!有沒有什麼辦法可以在插件依賴中包含工件依賴?我很想避免整個部分的複製粘貼:/ –

+1

@PiotrekDe也許你可以創建一個jar項目,其中包含所有必要的依賴項,這些依賴項可以用作POM和插件的依賴項。我不知道這是值得的痛苦,雖然... –