Мне нужно прочитать Manifest
файл, в котором был доставлен мой класс, но когда я использую:
getClass().getClassLoader().getResources(...)
Я получаю MANIFEST
из первого .jar
загруженного в Java Runtime.
Мое приложение будет запускаться из апплета или веб-старта,
поэтому я полагаю, что у меня не будет доступа к моему собственному .jar
файлу.
Я действительно хочу прочитать Export-package
атрибут из .jar
файла, который запустил Felix OSGi, чтобы я мог предоставить эти пакеты Феликсу. Любые идеи?
java
osgi
manifest.mf
apache-felix
Houtman
источник
источник
Ответы:
Вы можете сделать одну из двух вещей:
Вызовите
getResources()
и переберите возвращенную коллекцию URL-адресов, считывая их как манифесты, пока не найдете свой:Вы можете попробовать проверить,
getClass().getClassLoader()
является ли он экземпляромjava.net.URLClassLoader
. Большинство загрузчиков классов Sun, в том числеAppletClassLoader
. Затем вы можете преобразовать его и вызватьfindResource()
, по крайней мере, для апплетов, чтобы напрямую вернуть необходимый манифест:источник
Сначала вы можете найти URL-адрес вашего класса. Если это JAR, вы загружаете манифест оттуда. Например,
источник
classPath.replace("org/example/MyClass.class", "META-INF/MANIFEST.MF"
getSimpleName
удаляет имя внешнего класса. Это будет работать для внутренних классов:clazz.getName().replace (".", "/") + ".class"
.Вы можете использовать
Manifests
from jcabi-manifestests и прочитать любой атрибут из любого из доступных файлов MANIFEST.MF, используя всего одну строку:Единственная нужная вам зависимость:
Также см. Это сообщение в блоге для получения более подробной информации: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
источник
<logger name="com.jcabi.manifests" level="OFF"/>
Я сразу признаю, что этот ответ не отвечает на исходный вопрос о возможности доступа к манифесту. Однако, если на самом деле требуется прочитать один из ряда «стандартных» атрибутов манифеста, следующее решение намного проще, чем те, что опубликованы выше. Так что я надеюсь, что модератор это разрешит. Обратите внимание, что это решение находится на Kotlin, а не на Java, но я ожидал, что перенос на Java будет тривиальным. (Хотя я признаю, что не знаю Java-эквивалента ".`package`".
В моем случае я хотел прочитать атрибут «Версия-реализация», поэтому я начал с решений, приведенных выше, чтобы получить поток, а затем прочитал его, чтобы получить значение. Пока это решение работало, коллега, проверявший мой код, показал мне более простой способ сделать то, что я хотел. Обратите внимание, что это решение находится на Kotlin, а не на Java.
Еще раз обратите внимание, что это не отвечает на исходный вопрос, в частности, "Export-package" не кажется одним из поддерживаемых атрибутов. Тем не менее, есть myPackage.name, который возвращает значение. Возможно, кто-то, кто понимает это лучше меня, сможет прокомментировать, возвращает ли это значение, запрашиваемое исходным плакатом.
источник
String implementationVersion = MyApplication.class.getPackage().getImplementationVersion();
Я считаю, что наиболее подходящий способ получить манифест для любого пакета (включая пакет, который загрузил данный класс) - использовать объект Bundle или BundleContext.
Обратите внимание, что объект Bundle также предоставляет
getEntry(String path)
поиск ресурсов, содержащихся в определенном пакете, вместо поиска всего пути к классам этого пакета.В общем, если вам нужна информация, относящаяся к конкретному пакету, не полагайтесь на предположения о загрузчиках классов, просто используйте API OSGi напрямую.
источник
Самый простой способ - использовать класс JarURLConnection:
Поскольку в некоторых случаях
...class.getProtectionDomain().getCodeSource().getLocation();
дает путь с помощьюvfs:/
, с этим следует обращаться дополнительно.источник
Следующий код работает с несколькими типами архивов (jar, war) и несколькими типами загрузчиков классов (jar, url, vfs, ...)
источник
clz.getResource(resource).toString()
иметь обратную косую черту?Вы можете использовать getProtectionDomain (). GetCodeSource () следующим образом:
источник
getCodeSource
может вернутьсяnull
. По каким критериям это сработает? В документации это не объясняется.DataUtilities
привозят? Похоже, этого нет в JDK.Почему вы включаете шаг getClassLoader? Если вы скажете this.getClass (). GetResource (), вы должны получать ресурсы относительно вызывающего класса. Я никогда не использовал ClassLoader.getResource (), хотя при беглом взгляде на документацию Java кажется, что вы получите первый ресурс с таким именем, найденный в любом текущем пути к классам.
источник
class.getResource("myresource.txt")
будет предпринята попытка загрузить этот ресурс изcom/mypackage/myresource.txt
. Как именно вы собираетесь использовать этот подход для получения манифеста?источник
cl.getResourceAsStream("META-INF/MANIFEST.MF")
.classLoader.getResource(..)
иurl.openStream()
совершенно неуместен и подвержен ошибкам, поскольку он пытается делать то же самое, что иclassLoader.getResourceAsStream(..)
делает.ClassLoader classLoader = cl.getClassLoader(); return new Manifest(classLoader.getResourceAsStream("/META-INF/MANIFEST.MF"));
Я использовал решение Anthony Juckel, но в MANIFEST.MF ключ должен начинаться с верхнего регистра.
Итак, мой файл MANIFEST.MF содержит такой ключ, как:
Mykey: значение
Затем в активаторе или другом классе вы можете использовать код Энтони для чтения файла MANIFEST.MF и нужного вам значения.
источник
У меня есть это странное решение, которое запускает военные приложения на встроенном сервере Jetty, но эти приложения также необходимо запускать на стандартных серверах Tomcat, и у нас есть некоторые специальные свойства в manfest.
Проблема заключалась в том, что в Tomcat манифест можно было прочитать, но когда он был на пристани, был выбран случайный манифест (в котором пропущены специальные свойства)
Основываясь на ответе Алекса Коншина, я придумал следующее решение (входной поток затем используется в классе Manifest):
источник