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

How to add maven build output to plugin classloader?

我 运行遇到 maven-antrun-plugin 中 AntTask 运行 的问题。不幸的是,AntTask 使用插件 classloader 从项目中定位文件,但是当 运行 来自插件时,构建输出不包含在插件的 classpath 中。

来自Guide to Maven Classloading

Please note that the plugin classloader does neither contain the dependencies of the current project nor its build output.

...

Plugins are free to create further classloaders on their discretion. For example, a plugin might want to create a classloader that combines the plugin class path and the project class path.

任何人都可以指出正确的方向如何创建我自己的 maven-ant运行-插件版本,我可以在其中创建我自己的 classloader 结合插件 class路径和项目class路径?我需要更新 classloader 以便当 class 由我的自定义 ant运行-plugin 调用时执行:

getClass().getClassLoader().getResource()

class加载器也会搜索构建输出文件夹。

在尝试解决这个配置问题几个小时后,我硬着头皮写了自己的插件来扩展 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 class 将我的 Ant 任务的 Log4j 输出转换为 Maven 记录器 ():

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;
    }
}

希望对以后的人有帮助或帮助。