При компиляции 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 списка.
Никогда не пытайтесь читать MANIFEST.MF
как ресурс, поскольку у вас в classpath может быть несколько JAR файлов и у каждого из них будет свой META-INF/MANIFEST.MF
. Чтение MANIFEST.MF
в рантайме - это путь к багам и к неопределённому поведению вашей программы. Говорю из личного опыта работы в проекте, где кто-то тоже решил так делать. Вместо этого создайте файл properties
во время сборки и записывайте туда дату сборки.
Не знаю как это сделать в Ant. В Maven это делается достаточно просто:
Создаёте ещё одну директорию ресурсов src/main/resources-filtered
и в ней, скажем, com/example/myprog/build.properties
следующего содержания:
build.date=${build.date}
В pom.xml
в секции <build>
прописываете обе директории ресурсов и в какой из них включён режим обработки ресурсов во время их копирования:
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/resources-filtered</directory>
<filtering>true</filtering>
</resource>
</resources>
Там же в 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
и читаете от тудё всё что вы туда записали.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть 3 фильтра: Filter1, Filter2, Filter3Каждый из них помечен аннотацией @WebFilter("/main")
Мне нужно выполнить определенные действия в активити запущенном через Intent, но по каким то причинам информация присоединенная к интенту (в которой...
Необходимо организовать рассылку почты следующим образомПредположительно что модуль рассылки является частью существующего приложения
Почему при старте виджета с интегрированным Firebase Crashlytics выпадает это?