【问题标题】:Accessing classes in custom maven reporting plugin访问自定义 Maven 报告插件中的类
【发布时间】:2012-07-05 09:47:03
【问题描述】:

我编写了一个自定义的 maven 报告插件来输出有关 spring-mvc 类的一些基本信息。在我的内部测试中,我可以看到这样的代码:

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

但是,如果类在 maven 的 runtimeClasspathElements var 之外没有依赖项,这只会加载类。有没有办法将这些类也合并到类域中?

【问题讨论】:

    标签: java maven reflection maven-plugin


    【解决方案1】:

    好的。扩展上述评论中的答案,完整的解决方案是使用一个同时考虑运行时类路径和来自 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;
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      也许用

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

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-10
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多