【问题标题】:Version information for Java library, accessible at runtimeJava 库的版本信息,可在运行时访问
【发布时间】:2014-01-19 03:20:42
【问题描述】:

出于支持目的,我需要向我们的 Java 库添加版本和构建标识符。该库本身是一个无需用户交互的工具包,可用于不同的环境(独立的 Java 应用程序、Web 应用程序、Eclipse 应用程序、Maven 依赖项......)。

我想要的是一个带有一些常量的类,它为我提供上述信息(例如MyAppVersion.BUILD,...),以便可以显示它们,例如在对话框,命令行输出等。经过我的研究,似乎有以下几种做法:

  • 为文件名添加版本控制,如myLibrary-0.1.2.jar;在我们的情况下不可行,因为部署时我无法控制文件名
  • MANIFEST.MF 添加信息并以编程方式读取它,如here 所述。但是,我不确定这种方法对于不同的类加载器(Eclipse、OSGi、应用程序服务器等)有多健壮,如果 JAR 文件被重新打包,这些信息就会丢失
  • 使用保存版本的version.properties 文件,如here 所述,并在构建期间使用脚本更新version.properties 文件
  • 将版本信息直接硬编码到类中,并使用脚本更新此信息

还有其他方法吗?最后一个选项对我来说似乎最“强大”,对这个变体有任何反对意见吗?是否有 Maven 插件支持在构建期间更新 MyAppVersion.java 文件中的这些信息?

【问题讨论】:

  • This answer 提供了一种更简洁的方式来从清单中获取版本。简而言之:String version = this.getClass().getPackage().getImplementationVersion();
  • 使用属性文件并用 maven 过滤它,要求它插入版本号。

标签: java maven jar


【解决方案1】:

我建议使用专门为此目的创建的templating-maven-plugin

您最多创建一个单独的模块,其中包含这样的模板类(或在您的模块中):

public final class Version {

    private static final String VERSION = "${project.version}";
    private static final String GROUPID = "${project.groupId}";
    private static final String SVN = "${project.scm.developerConnection}";
    private static final String SVN_BRANCH = "${scmBranch}";
    private static final String REVISION = "${buildNumber}";

    public static String getVersion() {
        return VERSION;
    }

    public static String getGroupId() {
        return GROUPID;
    }

    public static String getSVN() {
        return SVN;
    }

    public static String getRevision() {
        return REVISION;
    }

    public static String getSVNBranch() {
        return SVN_BRANCH;
    }
}

您只需将其放入 src/main/java-templates 文件夹以及适当的包名称即可。此外,您可以在 pom 文件中配置 template-maven-plugin,如下所示:

   <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>templating-maven-plugin</artifactId>
        <version>1.0-alpha-3</version>
        <executions>
          <execution>
            <goals>
              <goal>filter-sources</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

这将生成一个类Version,其他人可以使用它并包含给定的版本。在上面的模板类中,您可以使用构建中可用的任何属性(例如 JENKINS_ID 等)或您可能自己定义的东西。

结果是这个类被编译打包到你的jar文件中。

除此之外,您还可以将其与buildnumber-maven-plugin 结合起来创建需要添加到您的 pom 文件中的 buildNumber,如下所示:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>buildnumber-maven-plugin</artifactId>
    <version>1.2</version>
    <configuration>
      <revisionOnScmFailure>UNKNOWN</revisionOnScmFailure>
      <getRevisionOnlyOnce>true</getRevisionOnlyOnce>
    </configuration>
    <executions>
      <execution>
        <goals>
          <goal>create</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

【讨论】:

  • 太棒了,看起来正是我想要的!谢谢!
【解决方案2】:

硬编码版本的最后一个选项是最强大的,这对您来说似乎很重要。 如果您使用 ant 构建,您可以编写一个类(我们称之为 VersionGenerator),它将生成一个带有版本的 java 文件:

package my.cool.package;
public interface Version {
    String VERSION = "1.2.3";
}

从 ant 调用 VersionGenerator 然后编译所有代码并将其放入 jar 中。您的 jar 将包含一个新生成和编译的 Version.class! VersionGenerator 会有如何命名和增加版本的逻辑

【讨论】:

  • 更好地使用基于 Maven 的工具,例如建议的模板化 maven-plugin。
  • 谢谢,但我使用的是 Maven,khmarbaise 的解决方案对我来说看起来很完美!
猜你喜欢
  • 2021-12-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多