Чтение атрибутов из MANIFEST.MF

187
09 января 2019, 10:50

При компиляции 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, то выводится 0.9.6-pre1 версия первой библиотеки указанной в списке библиотек из Class-Path списка.

Answer 1

Никогда не пытайтесь читать MANIFEST.MF как ресурс, поскольку у вас в classpath может быть несколько JAR файлов и у каждого из них будет свой META-INF/MANIFEST.MF. Чтение MANIFEST.MF в рантайме - это путь к багам и к неопределённому поведению вашей программы. Говорю из личного опыта работы в проекте, где кто-то тоже решил так делать. Вместо этого создайте файл properties во время сборки и записывайте туда дату сборки.

Не знаю как это сделать в Ant. В Maven это делается достаточно просто:

  1. Создаёте ещё одну директорию ресурсов src/main/resources-filtered и в ней, скажем, com/example/myprog/build.properties следующего содержания:

    build.date=${build.date}
    
  2. В pom.xml в секции <build> прописываете обе директории ресурсов и в какой из них включён режим обработки ресурсов во время их копирования:

    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>src/main/resources-filtered</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
    
  3. Там же в pom.xml в секции <properties> прописываете два новых параметра:

    <build.date>${maven.build.timestamp}</build.date>
    <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
    

Далее, у себя в коде, открываете ресурс com/example/myprog/build.properties, создаёте из него экземпляр Properties и читаете от тудё всё что вы туда записали.

READ ALSO
Порядок фильтров в сервлетах без web.xml

Порядок фильтров в сервлетах без web.xml

Есть 3 фильтра: Filter1, Filter2, Filter3Каждый из них помечен аннотацией @WebFilter("/main")

159
Не передается extras через Intent

Не передается extras через Intent

Мне нужно выполнить определенные действия в активити запущенном через Intent, но по каким то причинам информация присоединенная к интенту (в которой...

171
Создание задач и их обработка

Создание задач и их обработка

Необходимо организовать рассылку почты следующим образомПредположительно что модуль рассылки является частью существующего приложения

179
Crash в Crashlytics

Crash в Crashlytics

Почему при старте виджета с интегрированным Firebase Crashlytics выпадает это?

215