如何以编程方式从 pom.xml 执行特定的插件/Mojo?
Posted
技术标签:
【中文标题】如何以编程方式从 pom.xml 执行特定的插件/Mojo?【英文标题】:How to execute a specific plugin/Mojo from a pom.xml programmatically? 【发布时间】:2015-02-12 08:22:14 【问题描述】:我是其中一个 Maven 插件(不是 Apache/Codehaus,完全独立)的作者。有时我收到支持请求或测试用例,我真的需要使用现有的pom.xml
调试我的插件的执行。基本上我得到的测试用例是样本/测试项目(pom.xml
和src/main/resoures
、src/main/java
等等)。
我需要的是一种方法:
加载现有的pom.xml
。
在那里找到我的插件的特定执行(通常是唯一的)。
获取MyMojo
的实例 - 完全初始化/配置,所有组件和参数都正确注入。
执行MyMojo
。
重要的是测试项目是独立的项目,我不想将它们复制到插件的 Maven 模块中。
我希望无需远程调试也能做到这一点。
通过调试,我的意思是能够设置和暂停断点(也是有条件的),在源代码上单步执行/退出/跳过。
理想情况下,我希望能够 executeMyMojoFrom(new File("pom.xml"))
- 例如在 JUnit 测试或某个类的 main
方法中。 (我可以提供groupId
、artifactId
等。所有其他定义都应该从pom.xml
加载。)
我怎样才能做到这一点?
到目前为止我已经尝试过:
Eclipse 中pom.xml
上的 Debug As...
- 运行不佳(未找到源代码,断点不起作用,因为它不是 Java 项目上下文)
Maven Embedder/Invoker 解决方案 - 通过 CLI 在单独的进程中生成事物。忘记断点,无需调试。
使用 mvnDebug
进行远程调试,然后按照 Pascal Thivent here 的建议从 Eclipse 进行远程调试。这是迄今为止最好的选择。但是,远程调试意味着单独启动mvnDebug
,也不能保证我在Eclipse 中的JAR 与mvnDebug
使用的完全一样。所以这里有一定的距离。
maven-plugin-testing-harness
- 我实际上认为这可以完成任务。但首先我要跳几个小时才能开始。所有重要的依赖项都是“提供”的,所以我首先必须找出这些工件的正确版本组合。然后 - 才发现 AbstractMojoTestCase
仅在您要测试的插件模块中工作。当我认为maven-plugin-testing-harness
是 Maven 插件的测试工具时,可能我错了。似乎它是该插件模块中插件的测试工具。这不是不合逻辑的,但对我的情况没有帮助。我想在 other 模块中测试我的插件。
所以现在我使用远程调试解决方案获得了最好的结果。但我正在寻找的实际上是 maven-plugin-testing-harness
之类的东西,但没有硬连线到插件模块。如果 Maven 工件中某处存在这样的方法,是否有人碰巧有提示?
更具体地说,我想写一些类似的东西:
public void testSomething()
throws Exception
File pom = getTestFile( "pom.xml" );
assertNotNull( pom );
assertTrue( pom.exists() );
MyMojo myMojo = (MyMojo) lookupMojo( "myGroupId", "myArtifactid", ...,
"myGoal", pom );
assertNotNull( myMojo );
myMojo.execute();
...
将其与 MyMojoTest
here 进行比较 - 它几乎就在那里。不应该硬连线到mymojo
Maven 模块中(就像在maven-plugin-testing-harness
中一样)。
更新
cmets中问题的几个答案:
您的意思是您不希望这样的测试类,即
MyMojoTest
与MyMojo
驻留在同一个项目中,即您的插件项目?这是为什么呢?
没错。我想调试现有 Maven 项目中的插件执行,我不想将该项目移动到我的插件项目 first 以便能够运行测试。我希望能够测试/调试现有项目。理想情况下,我只需要在项目的 src/test/jaca 中添加 my-maven-plugin-testing
依赖项和子类 MyMojoTest
。这将是调试执行的好工具。将目标项目拖到我的 Mojo 项目中的开销太大——而且大多数情况下,这些并不是我想要长期保留的测试用例。我希望,这个答案,为什么。
无论如何,将
project-to-test/pom.xml
保留在插件模块的src/test/resources
内只是一个惯例,而不是规则...
我的问题不是project-to-test
的pom.xml
的位置,这很容易配置。我的困难是maven-plugin-testing-harness
以某种方式被硬编码为Mojo 的项目。它使用 Mojo 的pom.xml
,在包含的项目中查找其他特殊文件/描述符。所以我不能在非 Mojo 项目中使用它,或者我可以吗?这是我的问题。
我不知道为什么
Debug as...
没有帮助你...
也不确定,但是 (1) 断点不起作用并且 (2) 源代码由于某种原因没有“附加”。
【问题讨论】:
我建议在这里更深入地了解一下:github.com/ifedorenko/com.ifedorenko.m2e.mavendev BTW:您开发的是哪个插件? @khmarbaise 谢谢,我去看看。我开发了maven-jaxb2-plugin
。
@khmarbaise我查过了,这也太m2e
-centric,我可以实现与远程调试相同类型的调试。我想要的是在测试中从特定的pom.xml
执行 mojo 的可能性。不过还是谢谢你的提示。
您的意思是您不希望这样的测试类,即MyMojoTest
与MyMojo
驻留在同一个项目中,即您的插件项目?这是为什么?无论如何,将project-to-test/pom.xml
保留在插件模块的src/test/resources
中只是一种约定,而不是规则,就像在src/test/java/org/apache/maven/plugin/my
目录中创建MyMojoTest
一样。
我不知道为什么Debug as...
没有帮助你 - 每当我想调试我的插件或任何 maven 插件时,它总是对我有用。
【参考方案1】:
如果 Debug as
对您的工作效果不佳,您可以尝试使用 mojo-executor
并稍作调整。
https://github.com/TimMoore/mojo-executor
这就是您将如何以编程方式执行Maven Dependency Plugin
的copy-dependencies
目标:
executeMojo(
plugin(
groupId("org.apache.maven.plugins"),
artifactId("maven-dependency-plugin"),
version("2.0")
),
goal("copy-dependencies"),
configuration(
element(name("outputDirectory"), "$project.build.directory/foo")
),
executionEnvironment(
mavenProject,
mavenSession,
pluginManager
)
);
project
、session
和 pluginManager
变量应该通过正常的 Mojo 注入来注入。是的,这意味着这应该从另一个 Maven 插件的上下文中执行。现在我想了想,这是否对您有任何帮助仍然是一个问题,因为这仍然依赖于底层plexus
容器对此类组件的注入。
我最初的想法是让你构建一个 maven 插件,它会像上面一样通过 mojo-executor
调用你的 jaxb2
插件,然后序列化 mavenProject
、mavenSession
、pluginManager
,即所有plexus
注入组件,然后使用这些对象在将来从没有您构建的插件的独立类中调用您的 jaxb2
插件。
【讨论】:
以上是关于如何以编程方式从 pom.xml 执行特定的插件/Mojo?的主要内容,如果未能解决你的问题,请参考以下文章
在 pom.xml 中使用 Apache CXF Codegen 插件时出错。尝试更新 maven 时执行标记中出错。如何解决这个问题?