Maven 插件 - 将参数传递给生命周期阶段
Maven plugin - pass parameters to a lifecycle phase
我们有一个自定义的 Maven 插件,可以为我们的项目生成一些代码工件。该插件已经像这样配置了生命周期,'generate-resources' 阶段调用我们的自定义 class。
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>zip</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<generate-resources>com.b.e:productconfig-maven-plugin:generate</generate-resources>
<package>com.b.e:productconfig-maven-plugin:zip</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
我们对 运行 这个 'generate-resources' 阶段提出了新要求,参数略有不同。我曾希望我们可以定义第二阶段并传入像这样的 mojo 自定义属性
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>zip</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=A</generate-resources>
<generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=B</generate-resources>
<package>com.b.e:productconfig-maven-plugin:zip</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
但这会引发此错误。
[ERROR] Could not find goal 'generate -Dmojo.param=A' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals generate, zip -> [Help 1]
org.apache.maven.plugin.MojoNotFoundException: Could not find goal 'generate -DoutputFileBaseDir=/home/poc/b/product_configuration/productconfig-maven-plugin/target/generated/delta' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals export, generate
at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getMojoDescriptor(DefaultMavenPluginManager.java:267)
at org.apache.maven.plugin.DefaultBuildPluginManager.getMojoDescriptor(DefaultBuildPluginManager.java:185)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecution(DefaultLifecycleExecutionPlanCalculator.java:152)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecutions(DefaultLifecycleExecutionPlanCalculator.java:139)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:116)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:129)
at org.apache.maven.lifecycle.internal.BuilderCommon.resolveBuildPlan(BuilderCommon.java:92)
有人知道将参数正确传递到生命周期阶段的方法吗?
有两个题目要求基本相同,none个答案:
- Providing configuration for existing plugins in maven lifecycle mapping
- Change default mojo configuration in lifecycle mapping
我很确定这个 "lifecycle mapping with property/parameter definition" 不会起作用。
component.xml
中的声明指定哪个目标绑定到生命周期的某个阶段,a.k.a。 生命周期映射。换句话说,根据我的理解:
- 这是关于如果在构建过程中通过一个阶段运行执行什么。
- 不是关于如何完成的。
None 个参考文献:
- Sonatype Blog: Create a Customized Build Process in Maven
- JBossDevloper: Creating a Custom Lifecycle in Maven
提到:
将多个目标绑定到一个阶段。
因为 DefaultLifecycleMapping.getPhases(...)
returns a Map
其中键表示阶段,这根本不可能。
具有 property/parameter 定义的目标到阶段绑定。
您的错误消息的 Could not find goal 'generate -Dmojo.param=A'
部分告诉我 goal 部分的完整字符串被视为目标名称,没有应用进一步的参数提取。
对于Binding more than one goal to a phase
:
您可以在目标之间放置一个逗号,这当然适用于 Maven 3.6.1,但我不能说这是否是一个新功能。即:
<package>org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg</package>
对于A goal-to-phase binding with a property/parameter definition
:
我能够以编程方式完成您的要求。
对于我的插件,我希望能够选择先编译 Java 类 并将其放入 Jar 中,但最终的包格式是 Xar,将其视为包装器,它将包含 Jar 和其他东西。
我没有使用 components.xml
中的 DefaultLifecycleMapping
,而是创建了自己的 LifecycleMapping
组件,它指定了默认生命周期,并且从那里我能够设置配置(对于我的 use-case) Jar 插件。
我的自定义生命周期组件:
@Component(role = LifecycleMapping.class, hint = "xar", description = "EXPath Pkg Lifecycle Mapping")
public class PkgLifecycleMapping implements LifecycleMapping {
private final Map<String, Lifecycle> lifecycleMap = new HashMap<>();
public PkgLifecycleMapping() {
final Map<String, LifecyclePhase> phases = new HashMap<>();
phases.put("process-resources", new LifecyclePhase("org.apache.maven.plugins:maven-resources-plugin:resources"));
phases.put("compile", new LifecyclePhase("org.apache.maven.plugins:maven-compiler-plugin:compile"));
final LifecyclePhase packageLifecyclePhase = new LifecyclePhase("org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg");
// configure the maven-jar-plugin mojo
final LifecycleMojo jarLifecyclePhase = packageLifecyclePhase.getMojos().get(0);
Xpp3Dom config = jarLifecyclePhase.getConfiguration();
if (config == null) {
config = new Xpp3Dom("configuration");
}
final Xpp3Dom skipIfEmpty = new Xpp3Dom("skipIfEmpty");
skipIfEmpty.setValue("true");
config.addChild(skipIfEmpty);
jarLifecyclePhase.setConfiguration(config);
phases.put("package", packageLifecyclePhase);
phases.put("install", new LifecyclePhase("org.apache.maven.plugins:maven-install-plugin:install"));
phases.put("deploy", new LifecyclePhase("org.apache.maven.plugins:maven-deploy-plugin:deploy"));
final Lifecycle lifecycle = new Lifecycle();
lifecycle.setId("default");
lifecycle.setLifecyclePhases( phases );
lifecycleMap.put("default", lifecycle );
}
@Override
public Map<String, Lifecycle> getLifecycles() {
return lifecycleMap;
}
@Override
@Deprecated
public List<String> getOptionalMojos(final String lifecycle) {
return null;
}
@Override
@Deprecated
public Map<String, String> getPhases(final String lifecycle) {
final Lifecycle lifecycleMapping = lifecycleMap.get(lifecycle);
if (lifecycleMapping != null) {
return LifecyclePhase.toLegacyMap(lifecycleMapping.getLifecyclePhases());
} else {
return null;
}
}
}
您还需要将 plexus 元数据插件添加到 pom.xml
中的构建插件中:
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<goals>
<goal>generate-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
我的 src/main/resources/META-INF/plexus/components.xml
看起来像:
<component-set>
<components>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>xar</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<type>xar</type>
<extension>xar</extension>
<packaging>xar</packaging>
</configuration>
</component>
</components>
</component-set>
构建后我生成的 target/classes/META-INF/plexus/components.xml
看起来像:
<component-set>
<components>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>xar</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<type>xar</type>
<extension>xar</extension>
<packaging>xar</packaging>
</configuration>
</component>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>xar</role-hint>
<implementation>org.expath.pkg.maven.PkgLifecycleMapping</implementation>
<description>EXPath Pkg Lifecycle Mapping</description>
<isolated-realm>false</isolated-realm>
</component>
</components>
</component-set>
我们有一个自定义的 Maven 插件,可以为我们的项目生成一些代码工件。该插件已经像这样配置了生命周期,'generate-resources' 阶段调用我们的自定义 class。
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>zip</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<generate-resources>com.b.e:productconfig-maven-plugin:generate</generate-resources>
<package>com.b.e:productconfig-maven-plugin:zip</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
我们对 运行 这个 'generate-resources' 阶段提出了新要求,参数略有不同。我曾希望我们可以定义第二阶段并传入像这样的 mojo 自定义属性
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>zip</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=A</generate-resources>
<generate-resources>com.b.e:productconfig-maven-plugin:generate -Dmojo.param=B</generate-resources>
<package>com.b.e:productconfig-maven-plugin:zip</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
但这会引发此错误。
[ERROR] Could not find goal 'generate -Dmojo.param=A' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals generate, zip -> [Help 1]
org.apache.maven.plugin.MojoNotFoundException: Could not find goal 'generate -DoutputFileBaseDir=/home/poc/b/product_configuration/productconfig-maven-plugin/target/generated/delta' in plugin com.b.e:productconfig-maven-plugin:1.0.6-SNAPSHOT among available goals export, generate
at org.apache.maven.plugin.internal.DefaultMavenPluginManager.getMojoDescriptor(DefaultMavenPluginManager.java:267)
at org.apache.maven.plugin.DefaultBuildPluginManager.getMojoDescriptor(DefaultBuildPluginManager.java:185)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecution(DefaultLifecycleExecutionPlanCalculator.java:152)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.setupMojoExecutions(DefaultLifecycleExecutionPlanCalculator.java:139)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:116)
at org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator.calculateExecutionPlan(DefaultLifecycleExecutionPlanCalculator.java:129)
at org.apache.maven.lifecycle.internal.BuilderCommon.resolveBuildPlan(BuilderCommon.java:92)
有人知道将参数正确传递到生命周期阶段的方法吗?
有两个题目要求基本相同,none个答案:
- Providing configuration for existing plugins in maven lifecycle mapping
- Change default mojo configuration in lifecycle mapping
我很确定这个 "lifecycle mapping with property/parameter definition" 不会起作用。
component.xml
中的声明指定哪个目标绑定到生命周期的某个阶段,a.k.a。 生命周期映射。换句话说,根据我的理解:
- 这是关于如果在构建过程中通过一个阶段运行执行什么。
- 不是关于如何完成的。
None 个参考文献:
- Sonatype Blog: Create a Customized Build Process in Maven
- JBossDevloper: Creating a Custom Lifecycle in Maven
提到:
将多个目标绑定到一个阶段。
因为
DefaultLifecycleMapping.getPhases(...)
returns aMap
其中键表示阶段,这根本不可能。具有 property/parameter 定义的目标到阶段绑定。
您的错误消息的
Could not find goal 'generate -Dmojo.param=A'
部分告诉我 goal 部分的完整字符串被视为目标名称,没有应用进一步的参数提取。
对于
Binding more than one goal to a phase
:您可以在目标之间放置一个逗号,这当然适用于 Maven 3.6.1,但我不能说这是否是一个新功能。即:
<package>org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg</package>
对于
A goal-to-phase binding with a property/parameter definition
:我能够以编程方式完成您的要求。
对于我的插件,我希望能够选择先编译 Java 类 并将其放入 Jar 中,但最终的包格式是 Xar,将其视为包装器,它将包含 Jar 和其他东西。
我没有使用
components.xml
中的DefaultLifecycleMapping
,而是创建了自己的LifecycleMapping
组件,它指定了默认生命周期,并且从那里我能够设置配置(对于我的 use-case) Jar 插件。我的自定义生命周期组件:
@Component(role = LifecycleMapping.class, hint = "xar", description = "EXPath Pkg Lifecycle Mapping") public class PkgLifecycleMapping implements LifecycleMapping { private final Map<String, Lifecycle> lifecycleMap = new HashMap<>(); public PkgLifecycleMapping() { final Map<String, LifecyclePhase> phases = new HashMap<>(); phases.put("process-resources", new LifecyclePhase("org.apache.maven.plugins:maven-resources-plugin:resources")); phases.put("compile", new LifecyclePhase("org.apache.maven.plugins:maven-compiler-plugin:compile")); final LifecyclePhase packageLifecyclePhase = new LifecyclePhase("org.apache.maven.plugins:maven-jar-plugin:jar,org.expath.pkg:expath-pkg-maven-plugin:pkg"); // configure the maven-jar-plugin mojo final LifecycleMojo jarLifecyclePhase = packageLifecyclePhase.getMojos().get(0); Xpp3Dom config = jarLifecyclePhase.getConfiguration(); if (config == null) { config = new Xpp3Dom("configuration"); } final Xpp3Dom skipIfEmpty = new Xpp3Dom("skipIfEmpty"); skipIfEmpty.setValue("true"); config.addChild(skipIfEmpty); jarLifecyclePhase.setConfiguration(config); phases.put("package", packageLifecyclePhase); phases.put("install", new LifecyclePhase("org.apache.maven.plugins:maven-install-plugin:install")); phases.put("deploy", new LifecyclePhase("org.apache.maven.plugins:maven-deploy-plugin:deploy")); final Lifecycle lifecycle = new Lifecycle(); lifecycle.setId("default"); lifecycle.setLifecyclePhases( phases ); lifecycleMap.put("default", lifecycle ); } @Override public Map<String, Lifecycle> getLifecycles() { return lifecycleMap; } @Override @Deprecated public List<String> getOptionalMojos(final String lifecycle) { return null; } @Override @Deprecated public Map<String, String> getPhases(final String lifecycle) { final Lifecycle lifecycleMapping = lifecycleMap.get(lifecycle); if (lifecycleMapping != null) { return LifecyclePhase.toLegacyMap(lifecycleMapping.getLifecyclePhases()); } else { return null; } } }
您还需要将 plexus 元数据插件添加到
pom.xml
中的构建插件中:<plugin> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-component-metadata</artifactId> <version>2.0.0</version> <executions> <execution> <goals> <goal>generate-metadata</goal> </goals> </execution> </executions> </plugin>
我的
src/main/resources/META-INF/plexus/components.xml
看起来像:<component-set> <components> <component> <role>org.apache.maven.artifact.handler.ArtifactHandler</role> <role-hint>xar</role-hint> <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation> <configuration> <type>xar</type> <extension>xar</extension> <packaging>xar</packaging> </configuration> </component> </components> </component-set>
构建后我生成的
target/classes/META-INF/plexus/components.xml
看起来像:<component-set> <components> <component> <role>org.apache.maven.artifact.handler.ArtifactHandler</role> <role-hint>xar</role-hint> <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation> <configuration> <type>xar</type> <extension>xar</extension> <packaging>xar</packaging> </configuration> </component> <component> <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role> <role-hint>xar</role-hint> <implementation>org.expath.pkg.maven.PkgLifecycleMapping</implementation> <description>EXPath Pkg Lifecycle Mapping</description> <isolated-realm>false</isolated-realm> </component> </components> </component-set>