1

I'm running into a problem with an AntTask run within the maven-antrun-plugin. Unfortunately, the AntTask uses the plugin classloader to locate a file from the project, but when run from within a plugin, the build output is not included in the plugin's classpath.

From the 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.

Can anyone point me in right direction how to create my own version of the maven-antrun-plugin in which I can create my own classloader that combines the plugin class path and the project class path? I need to update the classloader such that when a class executed by my custom antrun-plugin calls:

getClass().getClassLoader().getResource()

the classloader will search the build output folder as well.

Eric B.
  • 23,425
  • 50
  • 169
  • 316
  • What are you trying to do? And why using maven-antrun-plugin? – khmarbaise May 17 '16 at 09:14
  • @khmarbaise I'm trying to convert a legacy ant project to maven. Unfortunately part of the ant build uses a defunct Kodo Ant task for JDO enhancing of entities for which I have found no maven equivalent. So I am just trying to call the ant task via the maven-Antrim-plugin. But as I explained, the task uses the class loader to locate a properties file in the class path. But since the plugin class loader does not include the build sources/output, it fails to find it and the task fails. Modifying the ant task isn't really an option so I was looking to modify the class path of the plugin loader. – Eric B. May 17 '16 at 10:53

1 Answers1

3

After several hours trying to work my way around this issue with configuration, I bit the bullet and simply wrote my own plugin that extends the AntRun plugin. This was done using 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();

    }
}

With the MavenLoggerLog4jBridge class being used to convert from my Ant task's Log4j output to 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;
    }
}

Hopefully it might be of some use or assistance to someone in the future.

Community
  • 1
  • 1
Eric B.
  • 23,425
  • 50
  • 169
  • 316