Maven 原型 - 可选 属性,默认为空

Maven archetype - optional property, empty by default

我希望能够从我的原型生成一个项目,其中其中一个属性默认为空,或者如果在命令行中指定则进行填充。

这是我的 archetype-metadata.xml:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="basic">
    <requiredProperties>
        <requiredProperty key="compilerVersion"/>
        <requiredProperty key="dependencyClassifier">
            <defaultValue></defaultValue>
        </requiredProperty>
    </requiredProperties>
</archetype-descriptor>

这是行不通的。如果 dependencyClassifier 中有任何非空白值,那么它就可以完美地工作。但是,我无法让它与默认值 "empty" 一起工作。

defaultValue 为 empty/null 时我得到的错误是:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:2.4:generate (default-cli) on project standalone-pom: Archetype com.avast.archetype:compile-java:1.0.21 is not configured
[ERROR] Property dependencyClassifier is missing.
[ERROR] -> [Help 1]

或者,我会接受能够在命令行上传递空值(或 "whitespace" 值)。同样,使用 "-DdependencyClassifier= " 不起作用。

如何指定 属性 默认为空?

谢谢


我想以此实现的是能够从原型创建项目,其中包含依赖项声明:

    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>artifact</artifactId>
            <version>${dependencyVersion}</version>
            <classifier>${dependencyClassifier}</classifier>
        </dependency>
    </dependencies>

而且我需要能够在原型创建时实例化 ${dependencyClassifier}。这对于 ${dependencyVersion} 是可能的,因为它永远不会为空。但是,分类器默认情况下应为空。

这就是我如何成功满足您的要求:

在待生成的Maven项目的模板pom.xml文件中,放置一个空的属性,但不要将其作为classifier值的占位符,在那里你仍然会使用原型 requiredProperty 占位符如下:

<properties>
    <!-- empty placeholder, document it accordingly -->
    <empty.property></empty.property>
</properties>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
        <classifier>${dependencyClassifier}</classifier>
    </dependency>
</dependencies>

然后,在你的 archetype-metadata.xml 中有以下内容:

<requiredProperties>
    <requiredProperty key="dependencyClassifier">
        <defaultValue>${empty.property}</defaultValue>
    </requiredProperty>
</requiredProperties>

注意匹配:

  • 此处的 ${empty.property} 默认值只是 Archetype 插件的一个不存在的 属性,它被接受(空值确实不起作用)。
  • dependencyClassifier现在有一个默认值,即${empty.property}
  • 但是在生成的项目中,empty.property 将是空的(如果在 mvn archetype:generate 调用期间未指定 dependencyClassifier),因为它作为 Maven 属性 存在,具有空值,这使得整个 Maven 有效:原型注入的 属性 值是在最终 pom 中声明的 属性,因此不会破坏任何东西。
  • 分类器因此将具有 dependencyClassifier 值(在运行时指定)或 empty.property(其默认值),它是空的
  • Maven 将空分类器视为无分类器,因此为我们提供了两种行为。

总结一下:

正在调用

mvn archetype:generate ... -DdependencyClassifier=something

将在运行时使用我们所需的分类器 something 有效地填充 classifier 元素。

相反,不指定任何值将使 classifier 保留为 ${empty.property},即为空。 Maven 不会寻找任何分类器(也不会抱怨)。

这种方法的唯一缺点是在最后的 pom.xml 中保留 empty.property 属性 没有多大意义,这个技巧可能会让一些纯粹主义者感到震惊,但是工作。

我有一个类似的案例,并应用于您的用例,这样解决了:

archetype-metadata.xml 中,将 _UNDEFINED_(或其他一些魔术字符串)定义为默认值:

<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="basic">
  <requiredProperties>
    <requiredProperty key="compilerVersion"/>
    <requiredProperty key="dependencyClassifier">
      <defaultValue>_UNDEFINED_</defaultValue>
    </requiredProperty>
  </requiredProperties>
</archetype-descriptor>

在模板 pom.xml<dependency> 部分,使用 VTL #if 指令:

<dependencies>
  <dependency>
    <groupId>com.example</groupId>
    <artifactId>artifact</artifactId>
    <version>${dependencyVersion}</version>
#if( ${dependencyClassifier} != "_UNDEFINED_" )
    <classifier>${dependencyClassifier}</classifier>
#end
  </dependency>
</dependencies>

所以你的最终 pom.xml 根本不包含 <classifier> 定义 如果你用 archetype:generate 省略 -DdependencyClassifier=something .我想这绝对能让纯粹主义者满意。即使原型中的代码本身可能不会。

注:根据dependency list of archetype-common, the current version 3.1.2 of Maven archetype plugin uses Apache Velocity Engine 1.7.