我创建了用于包装MavenCli的小util,它使用快速启动原型生成了一个新的Maven项目。
当将Util作为单元测试执行时,它运行得很好(只生成一个空的Maven项目)。
现在,我想将这个小包装器集成到一个Maven插件中。但是,当我执行mojo (在第三个Maven项目中)时,MavenCli调用会异常失败:
[ERROR] Error executing Maven.
[ERROR] java.util.NoSuchElementException
role: org.apache.maven.eventspy.internal.EventSpyDispatcher
roleHint:
[ERROR] Caused by: null它看起来像:
public void createProject() {
final MavenCli cli = new MavenCli();
System.setProperty("maven.multiModuleProjectDirectory", "/usr/share/maven");
cli.doMain(new String[] { "archetype:generate", "-DgroupId=com.my.company",
"-DartifactId=hello-world", "-DarchetypeArtifactId=maven-archetype-quickstart",
"-DinteractiveMode=false" }, "/tmp", System.out, System.out);
}与该用途有关的依赖性:
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>mojo代码看起来像:
@Mojo(name = "custommojo", requiresProject = false)
public class CustomMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Util.createProject();
}
}mojo的POM只包括对相关Maven工件的依赖(plugin、plugin-注释等)。还有功用。
我提到的第三个项目是一个空的“maven-快速启动”项目,它依赖于mojo -项目,并配置了在编译阶段执行的mojo。
我不知道为什么它在单元测试的上下文中工作,但不知道它为什么在一个mojo上下文中工作。
有人能帮忙吗?
发布于 2016-11-14 14:16:45
这是一个类加载问题。
MavenCli将尝试从当前线程的上下文类加载器加载类。在Maven插件中,有一种特殊的、受限的类装入器,它可以访问:
但是,特定的类org.apache.maven.eventspy.internal.EventSpyDispatcher是Maven核心的一部分,但是它不是导出的APIs的一部分。 (包org.apache.maven.eventspy没有被列为exportedPackage)。所以插件不能加载该类。这也是它在您的测试中工作的原因:您不在插件中,所以类加载程序是不同的,并且可以访问该类。
您甚至都无法通过为插件添加一个对maven-core的依赖说明而逃脱:因为它应该已经提供了,所以它将被删除。
这里有两个解决方案:
archetype:generate Mojo。发布于 2017-12-07 08:21:19
这在自定义maven插件(使用Maven 3.5.0)中适用于我:
ClassRealm classRealm = (ClassRealm) Thread.currentThread().getContextClassLoader();
MavenCli cli = new MavenCli(classRealm.getWorld());
cli.doMain( ... );丛启动器设置上下文类加载器。到它的ClassRealm,它可以访问“全局”ClassWorld。
不确定这个解决方案有多稳定,但到目前为止看起来还不错。
二手进口品:
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.apache.maven.cli.MavenCli;发布于 2018-12-20 22:58:52
@Alexander:
您的回答
但是,您的代码给了我一个ClassCast异常:
Exception in thread "main" java.lang.ClassCastException: sun.misc.Launcher$AppClassLoader cannot be cast to org.codehaus.plexus.classworlds.realm.ClassRealm
at com.misys.tools.integration.codegen.cli.cmd.InstallApi.mavenInstallMchApi(InstallApi.java:58)
at com.misys.tools.integration.codegen.cli.cmd.InstallApi.run(InstallApi.java:50)
at com.misys.tools.integration.codegen.cli.OpenApiGen.main(OpenApiGen.java:26)我成功地将代码重写为:
MavenCli cli = new MavenCli(new ClassWorld("maven",Thread.currentThread().getContextClassLoader()));然后,随后对嵌入式maven的2次doMain调用成功!
https://stackoverflow.com/questions/40587683
复制相似问题