【问题标题】:Maven archetype - optional property, empty by defaultMaven 原型 - 可选属性,默认为空
【发布时间】:2016-12-14 08:13:42
【问题描述】:

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

这是我的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 中有任何非空白值,那么它可以完美运行。但是,我无法让它在默认值为“空”的情况下工作。

defaultValue 为空/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]

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

如何指定属性默认为空?

谢谢


我想要实现的是能够从包含依赖声明的原型创建项目:

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

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

【问题讨论】:

    标签: maven maven-3 pom.xml maven-archetype


    【解决方案1】:

    这就是我成功满足您的要求的方式:

    在要生成的 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 属性没有多大意义,这是一个可能会让一些纯粹主义者感到震惊的技巧,但确实有效。

    【讨论】:

    • 我没有意识到我可以将属性传递给&lt;defaultValue&gt;!我将对此进行测试并在我开始工作后立即接受答案。
    • @MartinMelka 您可以传递一个属性,但它不会被 Archetype 插件(或 Velocity 模板)视为属性,而只是作为字符串。当然,一旦它进入最终的真实pom.xml,它将被视为一个属性,并且有诀窍:)
    • 如果您尝试有条件地将整个依赖项添加为一个整体,这对您没有帮助。就我而言,如果设置了“-DdatabaseType=mysql”,我想添加 mysql jdbc 驱动程序。如果没有设置 databaseType,我根本不希望添加依赖项
    • 这是一个很好的解决问题的方法,虽然它不会产生 clean 输出文件(但它可以工作......)。
    【解决方案2】:

    我有一个类似的案例,应用到你的用例,这样解决它:

    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&lt;dependency&gt; 部分,使用VTL #if 指令:

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

    因此,如果您在 archetype:generate 中省略了 -DdependencyClassifier=something,那么您最终的 pom.xml 就根本不包含 &lt;classifier&gt; 定义。我想这绝对是让纯粹主义者满意的。即使原型中的代码本身可能不会。

    注意:根据dependency list of archetype-common,当前版本3.1.2的Maven原型插件使用Apache Velocity Engine 1.7

    【讨论】:

    • 对我来说这个解决方案更好,因为它生成一个干净的生成文件,没有任何怪癖。您需要学习一点 Velocity #if/#else/#end 但这实际上很好。 +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多