编译Java应用程序时,会将数据输入到MANIFEST.MF文件中,然后在启动应用程序时使用该文件。清单文件包含编译后所需的所有内容。
Ant 脚本的部分代码:
<manifest>
<attribute name="Built-By" value="${user.name}" />
<attribute name="Built-Date" value="${build.tstamp}" />
<attribute name="Implementation-Version" value="1.0.0.0" />
<attribute name="Implementation-URL" value="http://example.com/" />
<attribute name="Main-Class" value="src.app.MyApp" />
<attribute name="Class-Path" value="${manifest.libs}" />
</manifest>
编译后的清单内容:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.1
Created-By: 1.8.0_151-b12 (Oracle Corporation)
Built-By: Rootware
Built-Date: 2018-09-21 21:59:11
Implementation-Version: 1.0.0.0
Implementation-URL: http://example.com/
Main-Class: src.app.MyApp
Class-Path: ../libs/c3p0-0.9.6-pre1.jar ../libs/json-simple-1.1.1.jar
../libs/mchange-commons-java-0.2.12.jar ../libs/mysql-connector-java-
5.1.46.jar
读取属性的Java代码:
private static void getBuildDate()
{
try (InputStream stream = MyApp.class.getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"))
{
final Manifest manifest = new Manifest();
manifest.read(stream);
final Attributes attributes = manifest.getMainAttributes();
if (attributes.getValue("Built-Date") != null)
BUILD_DATE = attributes.getValue("Built-Date");
else
_log.info("Null attribute.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
读取Built-Date属性时始终为null。告诉我在阅读清单时我做错了什么?如果您尝试阅读Implementation-Version,则会显示Class-Path列表中的库列表中指定的第一个库的0.9.6-pre1版本。
永远不要尝试将其
MANIFEST.MF
作为资源读取,因为您的类路径中可以有多个 JAR 文件,并且每个都有自己的META-INF/MANIFEST.MF
. 运行时读取MANIFEST.MF
是程序中出现错误和未定义行为的途径。我是根据在一个项目中工作的个人经验说的,该项目也有人决定这样做。相反,properties
在构建时创建一个文件并在那里记录构建日期。我不知道如何在 Ant 中做到这一点。在 Maven 中,这很简单:
创建另一个资源目录
src/main/resources-filtered
,并在其中com/example/myprog/build.properties
包含以下内容:在
pom.xml
该部分中,<build>
指定两个资源目录以及在其复制期间启用资源处理模式的资源目录:在同
pom.xml
一部分中,您<properties>
编写了两个新参数:接下来,在您的代码中,打开资源
com/example/myprog/build.properties
,从中创建一个实例Properties
并从那里读取您在那里编写的所有内容。