I'm making a maven plugin that run in test phase, in pom.xml configuration of a project that uses my plugin, I'm setting a class canonical name that I want to use to run that class from my plugin, basically I'm making a way to have a dynamic class loading of classes inside the project from my plugin.
Class clazz = Class.forName("... class from pom.xml ...")
When I run it I receive the expectable "ClassNotFoundException", seems the class loader are not the same or not shared.
There is a way to do it? Like capture the class loader from the project or receive it by dependency injection into my plugin? What is the best way?
We can use the Hibernate implementation in mojo can be used as a reference to make it:
Checkout the source code here: http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.mojo/hibernate3-maven-plugin/2.2/org/codehaus/mojo/hibernate3/HibernateExporterMojo.java#HibernateExporterMojo.getClassLoader%28%29
private ClassLoader getClassLoader(MavenProject project)
{
try
{
List classpathElements = project.getCompileClasspathElements();
classpathElements.add( project.getBuild().getOutputDirectory() );
classpathElements.add( project.getBuild().getTestOutputDirectory() );
URL urls[] = new URL[classpathElements.size()];
for ( int i = 0; i < classpathElements.size(); ++i )
{
urls[i] = new File( (String) classpathElements.get( i ) ).toURL();
}
return new URLClassLoader( urls, this.getClass().getClassLoader() );
}
catch ( Exception e )
{
getLog().debug( "Couldn't get the classloader." );
return this.getClass().getClassLoader();
}
}
To capture the "project" object, we can use the mojo dependency injection:
/**
* Dependency injected
*/
@Parameter(defaultValue = "${project}")
public MavenProject project;
And use it to load some class in project class loader:
getClassLoader(this.project).loadClass("com.somepackage.SomeClass")