2012-07-05 52 views
1

我寫了一個定製的maven報告插件來輸出一些關於spring-mvc類的基本信息。在我的內部測試中,我可以看到這樣的代碼:訪問定製maven報告插件中的類

public Set<Class<?>> findControllerClasses(File buildOutputDir) throws IOException, ClassNotFoundException { 

    Collection<URL> urls = ClasspathHelper.forJavaClassPath(); 
    if (buildOutputDir != null) { 
     urls.add(buildOutputDir.toURI().toURL()); 
    } 

    Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(urls)); 
    Set<Class<?>> types = reflections.getTypesAnnotatedWith(Controller.class); 
    return types; 
} 

在拉動帶註釋的類中工作良好。但是,當我在另一個項目中使用報告插件時,不會提取帶註釋的類。

有人可以闡明如何訪問編譯的類用於報告的目的?或者這是否有可能?

編輯:使用答案部分解決:Add maven-build-classpath to plugin execution classpath

然而,這只是加載類,如果他們有runtimeClasspathElements VAR的行家之外沒有依賴關係。有什麼辦法可以將這些類合併到classrealm中嗎?

回答

0

確定。擴展上述評論的答案,完整的解決方案是使用配置器,該配置器考慮運行時類路徑和來自poms依賴關係的url。代碼如下

/** 
* 
* @plexus.component 
*     role="org.codehaus.plexus.component.configurator.ComponentConfigurator" 
*     role-hint="include-project-dependencies" 
* @plexus.requirement role= 
*      "org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup" 
*      role-hint="default" 
* 
*/ 
public class ClassRealmConfigurator extends AbstractComponentConfigurator { 

    private final static Logger logger = Logger.getLogger(ClassRealmConfigurator.class.getName()); 

    public void configureComponent(Object component, PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm, ConfigurationListener listener) throws ComponentConfigurationException { 

     addProjectDependenciesToClassRealm(expressionEvaluator, containerRealm); 

     converterLookup.registerConverter(new ClassRealmConverter(containerRealm)); 

     ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter(); 

     converter.processConfiguration(converterLookup, component, containerRealm.getClassLoader(), configuration, expressionEvaluator, listener); 
    } 

    private void addProjectDependenciesToClassRealm(ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm) throws ComponentConfigurationException { 
     Set<String> runtimeClasspathElements = new HashSet<String>(); 
     try { 
      runtimeClasspathElements.addAll((List<String>) expressionEvaluator.evaluate("${project.runtimeClasspathElements}")); 

     } catch (ExpressionEvaluationException e) { 
      throw new ComponentConfigurationException("There was a problem evaluating: ${project.runtimeClasspathElements}", e); 
     } 

     Collection<URL> urls = buildURLs(runtimeClasspathElements); 
     urls.addAll(buildAritfactDependencies(expressionEvaluator)); 
     for (URL url : urls) { 
      containerRealm.addConstituent(url); 
     } 
    } 

    private Collection<URL> buildAritfactDependencies(ExpressionEvaluator expressionEvaluator) throws ComponentConfigurationException { 
     MavenProject project; 
     try { 
      project = (MavenProject) expressionEvaluator.evaluate("${project}"); 
     } catch (ExpressionEvaluationException e1) { 
      throw new ComponentConfigurationException("There was a problem evaluating: ${project}", e1); 
     } 
     Collection<URL> urls = new ArrayList<URL>(); 
     for (Object a : project.getArtifacts()) { 
      try { 
       urls.add(((Artifact) a).getFile().toURI().toURL()); 
      } catch (MalformedURLException e) { 
       throw new ComponentConfigurationException("Unable to resolve artifact dependency: " + a, e); 
      } 
     } 
     return urls; 
    } 

    private Collection<URL> buildURLs(Set<String> runtimeClasspathElements) throws ComponentConfigurationException { 

     List<URL> urls = new ArrayList<URL>(runtimeClasspathElements.size()); 
     for (String element : runtimeClasspathElements) { 
      try { 
       final URL url = new File(element).toURI().toURL(); 
       urls.add(url); 
      } catch (MalformedURLException e) { 
       throw new ComponentConfigurationException("Unable to access project dependency: " + element, e); 
      } 
     } 

     return urls; 
    } 

} 
1

也許使用

/** 
* The classpath elements of the project. 
* 
* @parameter expression="${project.runtimeClasspathElements}" 
* @required 
* @readonly 
*/ 
private List<String> classpathElements; 

private ClassLoader getProjectClassLoader() 
    throws DependencyResolutionRequiredException, MalformedURLException 
{ 
    List<String> classPath = new ArrayList<String>(); 
    classPath.addAll(classpathElements); 
    classPath.add(project.getBuild().getOutputDirectory()); 
    URL[] urls = new URL[classPath.size()]; 
    int i = 0; 
    for (String entry : classPath) 
    { 
     getLog().debug("use classPath entry " + entry); 
     urls[i] = new File(entry).toURI().toURL(); 
     i++; // Important 
    } 
    return new URLClassLoader(urls); 
} 
+0

我試過了,但它沒有幫助。我發現有幫助,雖然是這個線程http://stackoverflow.com/questions/2659048/add-maven-build-classpath-to-plugin-execution-classpath – MikePatel 2012-07-06 08:51:53