4

I have made a Maven plugin that validates and instantiates the classes in the project. When does a Maven plugin have on the classpath the classes in the project?

The pluging keeps throwing a ClassNotFoundException.

Asking the question after looking through the Maven documentation and searching.

Any help would be greatly appreciated. Thank you!

Thomas Beauvais
  • 1,546
  • 2
  • 16
  • 30
  • What exactly are you trying to do? What do you mean by "Validates". Are you doing some bytecode manipulation? Otherwise JUnit would probably suffice... – Boris the Spider Jan 21 '14 at 22:11
  • I am wanting to process-classes against a configuration. This has nothing to do with a unit test. It uses reflection to validate the configuration to make sure the class is indeed where a configuration says. – Thomas Beauvais Jan 21 '14 at 22:18

2 Answers2

6

When does a Maven plugin have on the classpath the classes in the project?

The short answer is it doesn't by default.

Have a look at Guide to Maven Classloading

Specifically:

Please note that the plugin classloader does neither contain the dependencies of the current project nor its build output. Instead, plugins can query the project's compile, runtime and test class path from the MavenProject in combination with the mojo annotation requiresDependencyResolution from the Mojo API Specification.

If you are missing classes from a well known artifact, you can add that artifact as a project dependency.

Ori Dar
  • 18,687
  • 5
  • 58
  • 72
  • Ahh.. that makes sense but how would I go about loading the classes for the current project after they were compiled. For instance, my plugin's default phase is process-classes. – Thomas Beauvais Jan 21 '14 at 22:23
  • process-classes phase follows compile, so no problem in that case – Ori Dar Jan 21 '14 at 22:28
  • I might be missing something but the meager documentation or "Guide to Maven Classloading" isn't too much help. Surely there is a standard way of modifying the classpath or class realm. – Thomas Beauvais Jan 21 '14 at 22:44
  • You can add `requiresDependencyResolution` annotation property to your mojo annotation, something such as `@Mojo(name = "your-mojo-name", requiresDependencyResolution = ResolutionScope.COMPILE)` or use the equivalent `@requiresDependencyResolution` Javadoc tag – Ori Dar Jan 21 '14 at 22:51
  • 1
    http://maven.apache.org/ref/3.1.1/maven-plugin-api/plugin.html has probably the best descriptions for all options of the plugin annotations. – Robert Scholte Jan 21 '14 at 22:55
  • I have, requiresDependencyResolution = COMPILE, which I also thought was enough.. but it seems that has no impact with the project class files. This is rather strange behavior. – Thomas Beauvais Jan 21 '14 at 23:06
  • A simple search would have given some examples [such as in here](http://stackoverflow.com/questions/871708/maven-plugin-cant-load-class) – Ori Dar Jan 21 '14 at 23:15
1

Okay, so I was able to modify the classload by adding the output directory to the ClassRealm for the plugin. This still sounds strange to me, but it works.

final PluginDescriptor pluginDescriptor = (PluginDescriptor) getPluginContext().get("pluginDescriptor");
final ClassRealm classRealm = pluginDescriptor.getClassRealm();
final File classes = new File(getProject().getBuild().getOutputDirectory());
try
{
    classRealm.addURL(classes.toURI().toURL());
}
catch (MalformedURLException e)
{
     e.printStackTrace();
}
Thomas Beauvais
  • 1,546
  • 2
  • 16
  • 30