【问题标题】:How to embed archetype project version in Maven archetype?如何在 Maven 原型中嵌入原型项目版本?
【发布时间】:2011-08-28 18:32:53
【问题描述】:

我正在创建一个 Maven 原型,它会生成一个项目骨架 将包括对原型的项目的依赖 起源。

例如,源项目看起来像:

origin/archetype/... archetype for generating project 
      /core/... core services 
      /extra/... extra services 

并且原型将生成一个带有 POM 的项目,其中包含 像这样的依赖:

<dependencies> 
  <dependency> 
    <groupId>com.foo</groupId> 
    <artifactId>origin-core</artifactId> 
    <version>SOMEVERSION</code> 
  </dependency> 
</dependencies> 

我希望 SOMEVERSION 成为当时原始项目的版本 原型已构建并安装到存储库中。

因此,如果源项目的版本为 1.0-SNAPSHOT 并且是 mvn installed,那么我希望原型生成对 origin-core 1.0-SNAPSHOT。并且当源项目发布时,并自动 碰到 1.0 版,我希望原型生成对 origin-core 1.0

基本上我想在原型中使用${archetypeVersion} 作为速度变量 POM,但这似乎不可能。

还有其他方法可以完成我在这里尝试做的事情吗?

【问题讨论】:

    标签: java maven maven-archetype


    【解决方案1】:

    几天前我在 Maven 邮件列表上问了上述问题,得到了风滚草。幸运的是,我最终自己想通了。这里至少有一种明智的方法可以做到这一点:

    在构建原型时,对您的 src/main/resources/archetype-resources/pom.xml 文件使用 Maven 过滤以替换当前项目版本。

    这是如何完成的:

    修改您的 archetype/pom.xml 文件以启用过滤 archetype-resources/pom.xml 文件而不是其他任何文件(因为您的原型文件自然会到处都有 ${variable}s 并且您不希望那些被替换为构建时,您希望在创建原型时替换它们)。

    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>archetype-resources/pom.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <excludes>
          <exclude>archetype-resources/pom.xml</exclude>
        </excludes>
      </resource>
    </resources>
    

    在过滤时启用转义字符,以便您可以转义原型 pom 中需要保持原样的所有变量,以便在原型生成时替换它们:

    <pluginManagement>
      <plugins>
        ...
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-resources-plugin</artifactId>
          <version>2.5</version>
          <configuration>
            <escapeString>\</escapeString>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
    

    (请注意,上面显示的 &lt;resources&gt;&lt;pluginManagement&gt; 元素应放在 POM 的 &lt;build&gt; 元素内。)

    在您的原型 pom 中使用 ${project.version},您希望在其中插入原型项目的版本,并转义在原型生成时间之前应该保持未被替换的所有其他变量:

    <?xml version="1.0" encoding="UTF-8"?>
    <project ...>
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>\${groupId}</groupId>
      <artifactId>\${artifactId}</artifactId>
      <version>\${version}</version>
      <packaging>jar</packaging>
    
      <dependencies>
        <dependency>
          <groupId>com.foo</groupId>
          <artifactId>origin-core</artifactId>
          <version>${project.version}</version>
        </dependency>
      </dependencies>
    
    </project>
    

    【讨论】:

    • 正是我所需要的。非常感谢。
    • 像魅力一样工作!谢谢。
    • 很好的解决方案!谢谢。
    • 无法相信这是多么容易。谢谢你!仔细想想,问题在于原型也是一个 Maven 项目。所以...使用 Maven 构建一个项目,然后生成一个 Maven 项目。一旦我弄清楚了,我发现很难向我的同事解释这一点。
    • 很好的解决方案。但是,这意味着您必须转义所有原始速度样式变量。即:对于速度 => \${groupId};用于 Maven 过滤 => ${project.version}。如果你更喜欢相反的,它也是可能的。例如:对于速度 => ${groupId};用于 Maven 过滤 => @project.version@。为此,您可以在 pom.xml > plugins > plugin > maven-resources-plugin > configuration: delimiters 中使用。例如。只有&lt;delimiters&gt; &lt;delimiter&gt;@*@&lt;/delimiter&gt; &lt;/delimiters&gt;
    【解决方案2】:

    接受答案的另一种解决方案是过滤 archetype's descriptor/metadata 文件中的默认属性

    这样做是这样的:

    maven过滤只过滤这个文件:

    <resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>META-INF/maven/archetype-metadata.xml</include>
        </includes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering>
        <excludes>
            <exclude>META-INF/maven/archetype-metadata.xml</exclude>
        </excludes>
    </resource>
    </resources>
    

    原型元数据文件:

    <archetype-descriptor ...>
        <requiredProperties>
            <requiredProperty key="projectVersion">
                <defaultValue>${project.version}</defaultValue>
             </requiredProperty>
        </requiredProperties>
    
        ...
    </archetype-descriptor>
    

    并且原型的 POM 将与之前类似,只是它将使用 projectVersion 所需的属性值作为项目版本:

    <?xml version="1.0" encoding="UTF-8"?>
    <project ...>
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>${groupId}</groupId>
      <artifactId>${artifactId}</artifactId>
      <version>${version}</version>
      <packaging>jar</packaging>
    
      <dependencies>
        <dependency>
          <groupId>com.foo</groupId>
          <artifactId>origin-core</artifactId>
          <version>${projectVersion}</version>
        </dependency>
      </dependencies>
    
    </project>
    

    这种方法的优点是它避免了必须转义原型的 POM 中的所有属性值以及随之而来的资源插件配置。就个人而言,我发现所有这些都非常丑陋且容易出错。

    这确实意味着在生成原型时要求用户确认或更改项目版本。根据情况,我想这可能被认为是好事或坏事。

    【讨论】:

    • 这个解决方案肯定比公认的要好。非常感谢你。它节省了我很多时间
    【解决方案3】:

    我尝试了一些相当愚蠢的方法,它似乎奏效了。我在 META-INF/maven/archetype-metadata.xml 文件中添加了以下内容:

    <requiredProperties>
        <requiredProperty key="archetypeVersion"> </requiredProperty>
    </requiredProperties>
    

    您会认为默认情况下它会知道它,但它不会,所以这似乎提醒它使用它。可能是由于 Maven 中的一个错误。

    【讨论】:

    • 如果你使用交互模式是不行的,你必须过滤原型测试资源。您可以选择依靠@PhilMander 的回答来完成这项工作。
    猜你喜欢
    • 2011-03-15
    • 1970-01-01
    • 2023-03-23
    • 2011-06-28
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多