如何将maven构建输出添加到插件类加载器?

时间:2016-05-17 01:42:35

标签: java maven plugins classloader maven-plugin

我遇到maven-antrun-plugin内运行AntTask的问题。不幸的是,AntTask使用插件类加载器从项目中定位文件,但是当从插件中运行时,构建输出不包含在插件的类路径中。

来自Guide to Maven Classloading

  

请注意,插件类加载器既不包含   当前项目的依赖关系及其构建输出。

     

...

     

插件可以自行决定是否可以自由创建更多的类加载器。   例如,插件可能想要创建一个组合的类加载器   插件类路径和项目类路径。

有人能指出我正确的方向如何创建我自己的maven-antrun-plugin版本,在其中我可以创建自己的类加载器,它结合了插件类路径和项目类路径?我需要更新类加载器,以便当我的自定义antrun-plugin执行的类调用时:

getClass().getClassLoader().getResource()

类加载器也将搜索构建输出文件夹。

1 个答案:

答案 0 :(得分:2)

经过几个小时试图通过配置解决这个问题,我点了点子弹,然后编写了我自己的插件,扩展了AntRun插件。这是使用Maven 3.2.5完成的:

@Mojo( name = "run", threadSafe = true, requiresDependencyResolution = ResolutionScope.TEST )
public class CustomAntMojo
    extends AntRunMojo
{

    @Component
    private PluginDescriptor pluginDescriptor;

    public void execute()
        throws MojoExecutionException
    {
        File buildDirectory = new File( getMavenProject().getBuild().getOutputDirectory() );

        // add the build directory to the classpath for the classloader
        try {
            ClassRealm realm = pluginDescriptor.getClassRealm();
            realm.addURL(buildDirectory.toURI().toURL());
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        }

        // configure the log4j logger to output the ant logs to the maven log
        BasicConfigurator.configure( new MavenLoggerLog4jBridge(getLog()));
        super.execute();

    }
}

使用MavenLoggerLog4jBridge类将我的Ant任务的Log4j输出转换为maven logger(https://stackoverflow.com/a/6948208/827480):

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.maven.plugin.logging.Log;
public class MavenLoggerLog4jBridge extends AppenderSkeleton {
    private Log logger;

    public MavenLoggerLog4jBridge(Log logger) {
        this.logger = logger;
    }

    protected void append(LoggingEvent event) {
        int level = event.getLevel().toInt();
        String msg = event.getMessage().toString();
        if (level <= Level.DEBUG_INT ) {
            this.logger.debug(msg);
        } else if (level == Level.INFO_INT) {
            this.logger.info(msg);
        } else if (level == Level.WARN_INT) {
            this.logger.warn(msg);
        } else if (level == Level.ERROR_INT || level == Level.FATAL_INT) {
            this.logger.error(msg);
        }
    }

    public void close() {
    }

    public boolean requiresLayout() {
        return false;
    }
}

希望将来可能对某人有所帮助或帮助。