问题
What is the problem when I execute the maven command in the loop ? The goal is to update the version of pom.xml of the list of bundles. The first iteration, maven execute correctly (update pom.xml), but it makes error for all item after.
for (String bundlePath: bundlesToUpdate)
{
MavenCli cli = new MavenCli();
String[] arguments = {
"-Dtycho.mode=maven",
"org.eclipse.tycho:tycho-versions-plugin:set-version",
"-DgenerateBackupPoms=false",
"-DnewVersion=" + version};
int result = cli.doMain(arguments, bundlePath, System.out, System.err);
}
Same error with the code:
`MavenCli cli = new MavenCli();
for (String bundlePath: bundlesToUpdate)
{
String[] arguments = {
"-Dtycho.mode=maven",
"org.eclipse.tycho:tycho-versions-plugin:set-version",
"-DgenerateBackupPoms=false",
"-DnewVersion=" + version};
int result = cli.doMain(arguments, bundlePath, System.out, System.err);
}`
First time, it's ok:
[main] INFO org.eclipse.tycho.versions.manipulation.PomManipulator - pom.xml//project/version: 2.2.6-SNAPSHOT => 2.2.7-SNAPSHOT
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - ------------------------------------------------------------------------
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - Reactor Summary:
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger -
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - XXXX project ....................... SUCCESS [ 0.216 s]
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - com.sungard.valdi.bus.fixbroker.client.bnp ........ SKIPPED
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - XXX project Feature ...................... SKIPPED
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - ------------------------------------------------------------------------
[main] INFO org.apache.maven.cli.event.ExecutionEventLogger - BUILD SUCCESS
After the errors are:
[main] ERROR org.apache.maven.cli.MavenCli - Error executing Maven.
[main] ERROR org.apache.maven.cli.MavenCli - java.util.NoSuchElementException
role: org.apache.maven.eventspy.internal.EventSpyDispatcher
roleHint:
[main] ERROR org.apache.maven.cli.MavenCli - Caused by: null
[main] ERROR org.apache.maven.cli.MavenCli - Error executing Maven.
[main] ERROR org.apache.maven.cli.MavenCli - java.util.NoSuchElementException
role: org.apache.maven.eventspy.internal.EventSpyDispatcher
roleHint:
回答1:
The solution I found is to use Maven Invoker and it works fine for the same functionality:
public class MavenInvoker {
public static void main(String[] args) throws IOException, NoHeadException, GitAPIException
{
MavenInvoker toto = new MavenInvoker();
toto.updateVersionMavenInvoker("2.2.8-SNAPSHOT", "TECHNICAL\\WEB" );
}
private InvocationRequest request = new DefaultInvocationRequest();
private DefaultInvoker invoker = new DefaultInvoker();
public InvocationResult updateVersionMavenInvoker(String newVersion, String folderPath)
{
InvocationResult result = null;
request.setPomFile( new File(folderPath+"\\pom.xml" ) );
String version = "-DnewVersion="+newVersion;
request.setGoals( Arrays.asList("-Dtycho.mode=maven",
"org.eclipse.tycho:tycho-versions-plugin:set-version",
"-DgenerateBackupPoms=false",
version) );
try {
result = invoker.execute( request );
} catch (MavenInvocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
回答2:
This works for me inside a custom maven plugin (using Maven 3.5.0):
ClassRealm classRealm = (ClassRealm) Thread.currentThread().getContextClassLoader();
MavenCli cli = new MavenCli(classRealm.getWorld());
cli.doMain( ... );
The plexus Launcher sets the context class loader to its ClassRealm
, which has access to the "global" ClassWorld
.
Not sure how stable that solution is, but so far looking good.
Used imports:
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.apache.maven.cli.MavenCli;
回答3:
See the email thread for a more detail explanation: https://dev.eclipse.org/mhonarc/lists/sisu-users/msg00063.html
It seems the correct way is to give MainCli
a ClassWorld
instance on construction so it can maintain a proper state through multiple calls.
Example:
final ClassWorld classWorld = new ClassWorld("plexus.core", getClass().getClassLoader());
MavenCli cli = new MavenCli(classWorld);
String[] arguments = {
"-Dtycho.mode=maven",
"org.eclipse.tycho:tycho-versions-plugin:set-version",
"-DgenerateBackupPoms=false",
"-DnewVersion=" + version};
int result = cli.doMain(arguments, bundlePath, System.out, System.err);
来源:https://stackoverflow.com/questions/22410706/error-when-execute-mavencli-in-the-loop-maven-embedder