java - 当您在生产环境中测试和运行 jar 时,如何创建可用的 MANIFEST.MF?

标签 java ant jar versioning manifest.mf

我花了太多时间试图弄清楚这一点。这应该是最简单的事情,每个在 jar 中分发 Java 应用程序的人都必须处理它。

我只想知道将版本控制添加到我的 Java 应用程序的正确方法,以便我可以在测试时访问版本信息,例如在 Eclipse 中调试从 jar 中运行。

这是我的 build.xml 中的内容:

<target name="jar" depends = "compile">
    <property name="version.num" value="1.0.0"/>
    <buildnumber file="build.num"/>
    <tstamp>
        <format property="TODAY" pattern="yyyy-MM-dd HH:mm:ss" />
    </tstamp>

    <manifest file="${build}/META-INF/MANIFEST.MF">
        <attribute name="Built-By" value="${user.name}" />
        <attribute name="Built-Date" value="${TODAY}" />                   
        <attribute name="Implementation-Title" value="MyApp" />
        <attribute name="Implementation-Vendor" value="MyCompany" />                
        <attribute name="Implementation-Version" value="${version.num}-b${build.number}"/>                              
    </manifest>

    <jar destfile="${build}/myapp.jar" basedir="${build}" excludes="*.jar" />                   
</target>

这会创建/META-INF/MANIFEST.MF,因此我在 Eclipse 中调试时可以读取这些值:

public MyClass()
{
    try
    {                        
        InputStream stream = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");
        Manifest manifest = new Manifest(stream);            

        Attributes attributes = manifest.getMainAttributes();

        String implementationTitle = attributes.getValue("Implementation-Title");
        String implementationVersion = attributes.getValue("Implementation-Version");
        String builtDate = attributes.getValue("Built-Date");
        String builtBy = attributes.getValue("Built-By");
   }
   catch (IOException e)
   {            
        logger.error("Couldn't read manifest.");
   }        

}

但是,当我创建 jar 文件时,它会加载另一个 jar 的 list (大概是应用程序加载的第一个 jar - 在我的例子中是 activation.jar)。

此外,尽管所有正确的值都在 list 文件中,但以下代码也不起作用。

    Package thisPackage = getClass().getPackage();
    String implementationVersion = thisPackage.getImplementationVersion();

有什么想法吗?

最佳答案

您可以在任意 jar 中获取任意类的 list ,而无需解析类 url(这可能很脆弱)。只需在所需的 jar 中找到您知道的资源,然后将连接强制转换为 JarURLConnection。

如果您希望代码在类未捆绑在 jar 中时工作,请添加一个 instanceof 检查返回的 URL 连接类型。未打包类层次结构中的类将返回内部 Sun FileURLConnection 而不是 JarUrlConnection。然后,您可以使用其他答案中描述的 InputStream 方法之一加载 Manifest。

@Test
public void testManifest() throws IOException {
    URL res = org.junit.Assert.class.getResource(org.junit.Assert.class.getSimpleName() + ".class");
    JarURLConnection conn = (JarURLConnection) res.openConnection();
    Manifest mf = conn.getManifest();
    Attributes atts = mf.getMainAttributes();
    for (Object v : atts.values()) {
        System.out.println(v);
    }
}

关于java - 当您在生产环境中测试和运行 jar 时,如何创建可用的 MANIFEST.MF?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/84486/

相关文章:

java - JMS list 文件,jar 的特定顺序是否重要

java - Android Studio 3.0 - "Failed to transform file ' gson-2.2.4.jar' 匹配属性 {artifactType=android-classes}”

java - Gradle:将多项目依赖项压缩到应用程序JAR文件中?

java - 需要来自整个组合层次结构的数据的操作模式

java - 如何获取 Tomcat 的连接池统计信息?

java - 登录表单错误 + JDBC CONNECTIVITY(JAVA-MYSQL)

java - 建立 SSL 连接时 PKIX 路径构建失败

java - Java 文件上的 Dos2unix

java - 如何在 ant build 创建的 jar 的错误堆栈跟踪中获取源代码行号?

android - UnsatisfiedLinkError - Android 版 Tesseract