Attributes Class
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
The Attributes class maps Manifest attribute names to associated string values.
[Android.Runtime.Register("java/util/jar/Attributes", DoNotGenerateAcw=true)] public class Attributes : Java.Lang.Object, IDisposable, Java.Interop.IJavaPeerable, Java.Lang.ICloneable, Java.Util.IMap
[] type Attributes = class inherit Object interface ICloneable interface IJavaObject interface IDisposable interface IJavaPeerable interface IMap
Remarks
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Constructors
Constructs a new, empty Attributes object with default size.
Constructs a new Attributes object with the same attribute name-value mappings as in the specified Attributes.
Constructs a new, empty Attributes object with the specified initial size.
A constructor used when creating managed representations of JNI objects; called by the runtime.
Properties
Returns the runtime class of this Object .
The handle to the underlying Android instance.
Returns true if this Map contains no attributes.
The attribute name-value mappings.
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.
Methods
Removes all attributes from this Map.
Returns a copy of the Attributes, implemented as follows:
Returns true if this Map contains the specified attribute name (key).
Returns true if this Map maps one or more attribute names (keys) to the specified value.
Returns a Collection view of the attribute name-value mappings contained in this Map.
Indicates whether some other object is «equal to» this one.
Returns the value of the specified attribute name, or null if the attribute name was not found.
Returns a hash code value for the object.
Returns the value of the specified attribute name, specified as a string, or null if the attribute was not found.
Returns the value of the specified attribute name, specified as a string, or null if the attribute was not found.
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
Returns a Set view of the attribute names (keys) contained in this Map.
Wakes up a single thread that is waiting on this object’s monitor.
Wakes up all threads that are waiting on this object’s monitor.
Associates the specified value with the specified attribute name (key) in this Map.
Copies all of the attribute name-value mappings from the specified Attributes to this Map.
Associates the specified value with the specified attribute name, specified as a String.
Removes the attribute with the specified name (key) from this Map.
Returns the number of attributes in this Map.
Returns a string representation of the object.
Returns a Collection view of the attribute values contained in this Map.
Causes the current thread to wait until another thread invokes the java.lang.Object#notify() method or the java.lang.Object#notifyAll() method for this object.
Causes the current thread to wait until either another thread invokes the java.lang.Object#notify() method or the java.lang.Object#notifyAll() method for this object, or a specified amount of time has elapsed.
Causes the current thread to wait until another thread invokes the java.lang.Object#notify() method or the java.lang.Object#notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
Explicit Interface Implementations
IJavaPeerable.Disposed() | (Inherited from Object) |
IJavaPeerable.DisposeUnlessReferenced() | (Inherited from Object) |
IJavaPeerable.Finalized() | (Inherited from Object) |
IJavaPeerable.JniManagedPeerState | (Inherited from Object) |
IJavaPeerable.SetJniIdentityHashCode(Int32) | (Inherited from Object) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) | (Inherited from Object) |
IJavaPeerable.SetPeerReference(JniObjectReference) | (Inherited from Object) |
IMap.ContainsKey(Object) | |
IMap.ContainsValue(Object) | |
IMap.Get(Object) | |
IMap.Put(Object, Object) | |
IMap.Remove(Object) |
Extension Methods
Performs an Android runtime-checked type conversion.
Java: торжественное обращение с jar и атрибутами MANIFEST.MF
Полноценно работать с технологией JAR можно как с помощью утилиты jar, входящей в состав JDK (Java Development Kit), так и с использованием классов JAR API.
Первый способ распространен повсеместно, в то время как второй, зачастую незаслуженно, обделен вниманием и, как показывает практика, напрасно – во многих случаях это может существенно облегчить жизнь разработчика. Именно поэтому в данной статье будут описаны несколько способов применения JAR API для вызова произвольных методов из jar-файла, записи и чтения атрибутов манифеста. (Манифест – (устар.) торжественное письменное обращение верховной власти к народу в связи с важным политическим событием, торжественной датой и т. д. (Толковый словарь русского языка).
Прежде всего следует уделить некоторое внимание утилите jar (http://java.sun.com/javase/6/docs/technotes/tools/solaris/jar.html). Это консольное приложение, запускаемое с набором параметров.
jar cf file.jar список_файлов
// Просмотр содержимого архива
// Извлечение содержимого из jar-файла
JAR File Specification (http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html), позволяет расположить в архиве file.jar только один манифест с дополнительной служебной информацией META-INF/MANIFEST.MF, представляющий собой текстовый файл в кодировке UTF-8. Если он не был задан при создании jar-файла, используется манифест, который по умолчанию содержит информацию о своей версии и JDK, в которой был создан конкретный jar-файл:
Created-By: 1.6.0 (Sun Microsystems Inc.)
Условно содержимое можно разделить на главную группу (содержит определенные стандартами атрибуты, некоторые из них приведены в таблице 1) и индивидуальную группу (состав которой определяется произвольно).
Таблица 1. Атрибуты главной группы манифеста
Номер версии файла-манифеста. Определяется спецификацией как регулярное выражение следующего вида: цифра+*
Версия и поставщик платформы Java, с помощью которой был создан манифест. Автоматически генерируется утилитой jar
Версия подписи jar-файла. Определяется так же, как и Manifest-Version
Относительные указатели ресурсов (URL) для всех используемых дополнительных классов и библиотек
Относительный путь к главному классу приложения, который должен содержать точку входа – метод main(String[] args). Значение атрибута не должно содержать расширение .class. Атрибут определяется для автономных настольных приложений, которые собраны в выполняемые jar-файлы, которые могут быть запущены виртуальной машиной Java напрямую командой: java -jar file.jar
Имена произвольных атрибутов могут содержать только цифры, строчные и заглавные буквы латинского алфавита и знак «_», а по длине существует ограничение – 70 символов. К значению атрибута никаких требований, кроме элементарной логики, не предъявляется.
Более подробно структуру и состав JAR и META-INF/MANIFEST.MF в рамках этого текста мы затрагивать не будем по той простой причине, что любой желающий может прочесть более подробно cпецификацию JAR.
В последней на текущий момент Java 1.6 к JAR API относятся классы пакета java.util.jar, а также классы java.net.JarURLConnection и java.net.URLClassLoader. Ограничимся рассмотрением наиболее используемых классов (см. таблицу 2).
Таблица 2. Наиболее используемые классы в JAR API
Таблица соответствий между именем атрибута и его значением
Перечисление в виде констант всех имен атрибутов главной группы
Класс описывает элемент jar-файла, например, файл с расширением .class
Наследник класса java.util.zip.ZipFile с поддержкой манифеста. Используется для чтения содержимого jar-файла
Наследник класса java.util.zip.ZipInputStream с поддержкой манифеста. Используется для чтения содержимого jar-файла из любого входящего потока
Наследник класса java.util.zip.ZipOutputStream с поддержкой записи манифеста. Используется для записи содержимого jar-файла в любой исходящий поток
Класс используется для работы с манифестом и его атрибутами
Соединение с jar-файлом или его элементом с помощью указателя ресурсов вида:
ar:!/, например: jar:http://www.site.org/folder/file.jar!/org/site/Clazz.class
Используется для загрузки классов и ресурсов из classpath (может определяться, к примеру, атрибутом манифеста Class-Path)
Прежде всего рассмотрим пример, который будет запускать метод public static void main(String[] args) из произвольного класса в jar-файле. Предположим, что у нас есть некий файл file.jar, который содержит класс pkg.Main:
public static void main(String[] args)
MANIFEST.MF архива имеет следующий вид:
Created-By: 1.6.0_03-b05 (Sun Microsystems Inc.)
Вначале необходимо получить URL по имени файла:
URL fileUrl = new File(«file.jar»).toURL();
URL url = new URL(«jar», «», fileUrl + «!/»);
Сам вызов осуществляется следующим образом:
public static final String MAIN_METHOD = «main»;
public void runMainMethod(String className) throws Exception
new URLClassLoader(new URL[] < url >);
// Загрузка класса класслоадером
// Получение main-метода и проверка, является ли он точкой входа
mainMethod = clazz.getMethod(MAIN_METHOD, args.getClass());
int mods = mainMethod.getModifiers();
if (mainMethod.getReturnType() != void.class
throw new NoSuchMethodException(MAIN_METHOD);
// Запуск метода с объектом, у которого надо выполнить метод, и параметрами.
// null показывает, что метод статический
Теперь попробуем задействовать JAR API для решения несколько усложненной задачи – теперь необходимо запустить метод main() главного класса jar-файла. Для этого нам надо лишь вызвать уже имеющийся метод runMainMethod() с именем требуемого класса, которое можно получить из манифеста по имени атрибута Main-Class:
private String getMainClassName() throws IOException
JarURLConnection connection = (JarURLConnection) url.openConnection();
Attributes attributes = connection.getMainAttributes();
После вызова метода runMainMethod() в консоли появится надпись:
Генерация манифеста с атрибутами
После того как мы успешно запустили метод main() главного класса jar-файла, попробуем поработать с атрибутами манифеста. Начнем с создания манифеста, а затем попробуем прочитать записанные атрибуты. Итак, класс JarAttributeWriter будет генерировать все атрибуты:
public class JarAttributeWriter
private static final String LINE_TEMPLATE = «%s: %s\n»;
// Метод генерирует текстовый файл – манифест с именем filename
public void generateManifest(String filename)
StringBuffer buf = new StringBuffer();
InputStream inputStream = new ByteArrayInputStream(buf.toString().getBytes(«UTF-8»));
Manifest manifest = new Manifest(inputStream);
OutputStream outputStream = new FileOutputStream(filename);
// Метод возвращает одну строку манифеста. Метод format() — аналог printf
// в C – осуществляет форматированный вывод
private String getLine(String attributeName, String attributeValue)
return String.format(LINE_TEMPLATE, attributeName, attributeValue);
В результате файл манифеста будет содержать:
Чтение атрибутов из манифеста
Получившийся файл можно использовать в качестве манифеста для jar-архива – это довольно просто, поэтому предположим, что этот манифест уже лежит в jar-файле и требуется считать из него все атрибуты или только некоторые. Эту работу будет выполнять класс JarAttributeReader:
public class JarAttributeReader
private static final String OUTPUT_TEMPLATE = «%s=%s»;
// Метод считывает все атрибуты из jar-файла filename
Attributes getAllAttributes(String filename) throws IOException
jarFile = new JarFile(filename);
// Метод печатает в консоли атрибуты со значениями
void printAllAttributesWithValues(String filename)
Attributes attributes = getAllAttributes(filename);
for (Object o : attributes.keySet())
System.out.println(String.format(OUTPUT_TEMPLATE, o, attributes.getValue(o.toString())));
В результате в консоли появится запись следующего вида:
Следует отметить, что JAR API предоставляют довольно мощные средства для работы с JAR вообще и MANIFEST.MF, в частности, которые отнюдь не ограничиваются приведенными выше примерами. Ситуаций, когда правильное использования манифеста может существенно облегчить процесс отладки и/или распространения приложений, довольно много. Например, добавление версии приложения в качестве атрибута MANIFEST.MF позволит точно определить номер сборки приложения. Иными словами, в общем случае, в манифест можно записать различные параметры для последующего их использования при запуске приложения.