I am creating a Maven plugin with a rather unique requirement for proper operation: it needs to spawn new processes of itself and then wait for those processes to complete a task.
While this is relatively trivial to do on the command line, Maven plugins do not get invoked in the same manner as traditional Java code and thus there is no classpath. I cannot figure out how to resolve the correct classpath inside the plugin such that I can spawn a new JVM (invoking the Main method of another class inside the plugin).
Using the current artifact's MavenProject
I am able to get an Artifact
reference to myself (the plugin) and get it's relative directory inside the local Maven repository:
Artifact self = null;
for (Artifact artifact : project.getPluginArtifacts()) {
if ("my-group-id".equals(artifact.getGroupId()) && "my-artifact-id".equals(artifact.getArtifactId())) {
self = artifact;
break;
}
}
if (self == null) {
throw new MojoExecutionException("Could not find representation of this plugin in project.");
}
for (ArtifactRepository artifactRepository : project.getPluginArtifactRepositories()) {
String path = artifactRepository.pathOf(self);
if (path != null) {
getLog().info("relative path to self: " + path);
break;
}
}
How do I get a reference to all of its dependencies (and transitive dependencies) such that I can construct a full classpath for a new invocation? I see that self
has a dependency filter but I don't know where to apply it.
Is this the proper way to create a new process of "myself" inside a plugin? Is there a better way?
I found a great article on the differences between dependency resolution on Maven 2 and Maven 3.
Given an Artifact
it boils down to the following:
private Set<Artifact> getDependenciesForArtifact(Artifact artifact) {
ArtifactResolutionRequest arr = new ArtifactResolutionRequest()
.setArtifact(artifact)
.setResolveTransitively(true)
.setLocalRepository(local);
return repositorySystem.resolve(arr).getArtifacts();
}
With the Set
you can construct a by calling pathOf
on an ArtifactRepository
for each element and joining with File.pathSeparator
.
Hm. Not really an answer but some hints. Why do you need such a complex thing? Furthermore i would take a deep look into the maven-surefire-plugin which can fork a jvm for unit tests and can handle classpath. On the other hand you can take a look into the maven-invoker or in the maven-invoker-plugin which can fork maven completely. Ah..what i missed. Take a look into the maven-dependency-plugin which has a particular goal for creating the classpath where you can take a look into the sources how they construct the classpath.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With