2

我编写了一个自定义 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;
}

在引入带注释的类方面效果很好。但是,当我在另一个项目中使用报告插件时,不会选择带注释的类。

有人可以阐明如何访问已编译的类以进行报告吗?或者这是否可能?

编辑:使用以下答案部分解决: 将 maven-build-classpath 添加到插件执行类路径

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

4

2 回答 2

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 );
}
于 2012-07-05T15:41:15.403 回答
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;
    }

}
于 2012-07-06T10:35:28.620 回答