java文件中的Maven版本号

Posted

技术标签:

【中文标题】java文件中的Maven版本号【英文标题】:Maven Version number in java file 【发布时间】:2012-02-08 09:24:18 【问题描述】:

我来自 ANT,您可以在其中调用 .java 文件通过执行某些方法来获取版本号。我想在我的新 pom.xml 中做类似的事情来自动获取正确的版本号。我需要该应用程序了解它自己的版本,同时 Maven 了解该版本得到正确的构建。将版本信息加倍是不行的。

或者 Maven 可以在构建期间/之前创建一个新的 .java 文件吗?

我可以想象很多方法来实现这一点,但是在 Maven 项目中是否有最佳实践方法来做到这一点?

【问题讨论】:

可以在maven的配置文件中指定版本-pom.xml 是的,我知道,但我需要应用程序也知道版本号,因此 pom.xml 应该从 java 文件中读取版本号,或者 pom.xml 应该触发创建带有版本号的 java 文件。 Maven 有一个“过滤资源”功能,它可以在构建过程中将代码文件中的一些内容替换为 Maven 变量,您需要在文件中添加 $project.version 之类的标记。您可以通过maven.apache.org/plugins/maven-resources-plugin/examples/…获得它 【参考方案1】:

在构建 JAR 时,Maven 将pom.xmlpom.properties 文件写入META-INF/maven/[group ID]/[artifact ID] 目录。然后,您可以在您的应用程序中读取其中之一的版本。

或者,您可以使用 resource filtering 显式编写新的 version.properties 文件。

如果您将以下内容放入您的 POM:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

然后将version.properties 模板放入 src/main/resources 目录,如下所示:

version = $project.version

Maven 将替换从 POM 中读取的版本,然后您的应用程序只需要读取 version.properties 资源并查询 version 键。

【讨论】:

这种方法听起来不错,但有一件事我想不通:如果我在 Ecplise 中开发并直接使用运行按钮启动项目,Maven 将不会替换该值。还是我必须始终通过 Maven 启动项目? @Franz 是的,Maven 需要运行并重写该文件以供 Eclipse 获取。您可以将 target/build/classes 目录添加为源文件夹,以便 Eclipse 获取重写的文件,或者您可以显式地使资源插件运行并将其输出文件生成到不同的目录,并将其作为源文件夹包含在 Eclipse 中.另外,我不知道最新的 M2Eclipse 有多复杂,但也许它可以处理过滤的资源。 (见***.com/questions/2773474/…)【参考方案2】:

我会在 SO:How to read an external properties file in Maven 上向您推荐这个帖子。特别是,查看 Dougnukem 的答案,该答案描述了如何将外部属性文件读入 Maven。您可以使用它作为共享源来控制 Maven 构建脚本和 Java 应用程序中的版本号。

【讨论】:

【参考方案3】:

也许如果您详细说明此要求,我们可以提供更多帮助,为您的问题提供更优雅的专业解决方案。 Nmely,第二个应用程序是什么,它是从 Maven 启动的,如果是,它是在构建过程的哪个阶段启动的?这个应用程序和 Maven 有什么交互?

有很多方法可以实现这一点,但选择正确的很大程度上取决于您的具体情况,您的问题中没有足够的信息来深入挖掘更全面的解决方案。也就是说,我想到了以下内容:

External properties :您可以在外部或直接从 Maven 构建过程创建属性文件。然后,您可以从其他应用程序中读取此属性文件。

过滤:正如其他人所提到的,可以让 Maven 过滤资源文件。此文件可以是一个 java 文件,您可以在其中插入当前版本号并从您的其他应用程序调用此文件。

从 Maven 构建调用您的应用程序并传递参数:您可以使用 exec 插件并将您的应用程序作为 Maven 的子进程调用,并传递当前版本号 $project.version。

Integrate您在 Maven 中的旧 Ant 构建:您可以直接调用一些 Ant sn-ps 或从 Maven 完成 ant 构建。这将为您提供一个混合构建系统,它可能不是最好的,但仍然允许您在迁移过程中留有一些余地,并管理较旧的 Ant 脚本,将功能片慢慢迁移到 Maven。并不是说混合使用这两者不一定是坏事,只是 Maven 提供了许多 Ant 脚本可能会干扰的硬连线或准硬连线配置约定。在这方面,很难让双方都相处融洽。

从 ant 驱动您的 Maven 构建:您也可以做相反的事情,即从 ant 驱动 Maven 构建过程,从而控制您如何调用其他系统。通过集成正确的东西(例如属性或过滤器),您可以确保 Maven 从特定项目中生成必要的工件,您以后可以在 Ant 脚本中使用这些工件。请注意,此任务的文档不是很详细,您可能需要花点时间才能使其正常工作,但至少您会处于熟悉的环境中。

如果没有关于这两个系统如何交互以及为什么需要这些信息的更多信息,很难为您深入挖掘。

希望对你有帮助

【讨论】:

【参考方案4】:

不清楚您指的是哪个版本号,以及为什么它会在 java 文件中。 但是,如果您尝试为项目分配版本号而不是遵循标准 Maven 约定。这是一个例子:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myco.abc</groupId>
  <artifactId>myapp</artifactId>
  <packaging>war</packaging>
  <version>1.0.0-SNAPSHOT</version>

  <name>My App</name>
  <description>My application description.</description>
  <url>http://myapp.myco.com</url>
....

【讨论】:

我指的是 1.0.0-SNAPSHOT。与旧版本的应用程序通信时,应用程序需要版本号以不同的方式工作,因为例如接口可能已经改变。【参考方案5】:

我知道这个问题很久以前就已经回答过了,但是我对这个答案提出了一个新的转折,有些人可能会觉得有用。

我让替换插件在每个 MAVEN 构建时更改 Java 文件中的字符串。因此,如果pom.xml 更新了 pom 项目版本号,它会自动反映在 java 源文件中。

告诉 MAVEN replace 目标:

<build>
    ...
    <pluginManagement>
        <plugins>
            <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
            <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>
                                        com.google.code.maven-replacer-plugin
                                    </groupId>
                                    <artifactId>
                                        replacer
                                    </artifactId>
                                    <versionRange>
                                        [1.5.3,)
                                    </versionRange>
                                    <goals>
                                        <goal>replace</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <execute />
                                    <runOnIncremental>true</runOnIncremental>
                                </action>
                            </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
    ...
</build>

告诉 Maven 填写当前名称和版本:

(如果您愿意,请将完整的子路径放入 basedir 并从包含的文件名中删除 **/。)

<build>
    ...
    <plugins>
        <plugin>
            <groupId>com.google.code.maven-replacer-plugin</groupId>
            <artifactId>replacer</artifactId>
            <version>1.5.3</version>
            <executions>
                <execution>
                    <id>replace-version-number</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>replace</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <basedir>$project.basedir/src/main/java</basedir>
                <includes>
                    <include>**/Constants.java</include>
                </includes>
                <preserveDir>true</preserveDir>
                <replacements>
                    <replacement>
                        <token>mavenProjectName = ".*"</token>
                        <value>mavenProjectName = "$project.name"</value>
                    </replacement>
                    <replacement>
                        <token>mavenProjectVersion = ".*"</token>
                        <value>mavenProjectVersion = "$project.version"</value>
                    </replacement>
                </replacements>
            </configuration>
        </plugin>
        ....
    </plugins>
    ...
</build>

输入常量.java:

...
private static final String mavenProjectName = "";
private static final String mavenProjectVersion = "";
...

在编译阶段之前,generate_sources 阶段中​​的值被 POM 的值填充。

替换者令牌中的通配符.* 表示即使您将更新的副本签入源代码管理,该值也会更新。

【讨论】:

以上是关于java文件中的Maven版本号的主要内容,如果未能解决你的问题,请参考以下文章

Java工程化--Maven实践

使用 maven 将版本号输出到文本文件

为啥有时会跳过 maven 依赖项中的版本号?

maven配置tomcat插件,及在maven打包时文件名不包含版本号

[转] Maven更新父子模块的版本号, mvn versions:set

maven配置文件pom增加变量取版本号