El manifiesto es un fichero especial que puede contener información sobre los otros ficheros empaquetados en un fichero JAR. Personalizar la información "meta" del manifiesto, te permite utilizar los ficheros JAR para una gran variedad de propósitos.
Antes de ver algunas de las formas en que puede ser modificado el manifiesto para permitir funcionalidades especiales a los ficheros JAR, echemos un vitazo a la línea base del manifiesto por defecto.
META-INF/MANIFEST.MF
Cuando un fichero JAR es creado con la versión 1.2 del JDK, el manifiesto por defecto es muy sencillo. Aquí tienes todo su contenido:
Manifest-Version: 1.0
Created-By: Manifest JDK1.2
Como puedes ver en este ejemplo, las entradas de un fichero de manifiesto tienen la forma de parejas: "cabecera:valor". El nombre de una cabecera está separado de su valor por dos puntos.
El manifiesto mostrado arriba es conforme a la versión 1.0 de la especificación de manifiesto y ha sido creado con la versión 1.2 del JDK, Estas son propiedades del propio manifiesto, pero también puede contener información sobre otros ficheros empaquetados en el archivo.
La información exacta grabada en el fichero de manifiesto depende del uso previsto del fichero JAR. El fichero de manifiesto por defecto no asume nada sobre la información que debería almacenar sobre otros ficheros, por eso sólo contiene datos sobre él mismo.
El formato del fichero de manifiesto por defecto cambia de la versión 1.1 a la versión 1.2 del JDK. Si creas un fichero JAR para el paquete, java.math, por ejemplo, el fichero de manifiesto por defecto del JDK 1.1 se parecería a esto:
Manifest-Version: 1.0
Name: java/math/BigDecimal.class
Digest-Algorithms: SHA MD5
SHA-Digest: TD1GZt8G11dXY2p4olSZPc5Rj64=
MD5-Digest: z6z8xPj2AW/Q9AkRSPF0cg==
Name: java/math/BigInteger.class
Digest-Algorithms: SHA MD5
SHA-Digest: oBmrvIkBnSxdNZzPh5iLyF0S+bE=
MD5-Digest: wFymhDKjNreNZ4AzDWWg1Q==
Al contrario que el manifiesto del JDK 1.2 el del JDK 1.1 tiene entradas para cada uno de los ficheros contenidos en el archivo, incluyendo los paths de los ficheros y valores digest. Estos últimos valores son solo importantes con respecto a la firma de ficheros JAR. De echo, el por qué la información digest no está en el fichero de manifiesto del JDK 1.2 - es porque nunca la necesita. Para aprender más sobre la firma, puedes ver la lección Firmar y Autentificar ficheros JAR.
La mayoría de los usos de los ficheros JAR que van más allá del simple archivado y comprensión necesitan que alguna información especial sea almacenada en el fichero de manifiesto. Abajo tienes una breve descripción de las cabeceras requeridas para algunas funciones de propósito especial de los ficheros JAR:
Aplicaciones empaquetadas en ficheros JAR - sólo versión 1.2
Si tienes una aplicación en un fichero JAR, necesitas indicar de alguna forma que clase es el punto de entrada de las que se incluyen en el fichero JAR. (Recuerda que el punto de entrada es una clase que tenga un método con la firma: public static void main(String[] args).)
Esta información se proporciona con la cabecera Main-Class, que tiene esta forma general:
Main-Class: classname
donde classname es el nombre de la clase que es el punto de entrada de la aplicación.
Descarga de Extensiones - sólo versión 1.2
La descarga de extensiones son ficheros JAR que son referenciados por el fichero de manifiesto de otros ficheros JAR. En una situación típica, un applet estaría empaquetado en un fichero JAR cuyo manifiesto referenciara a un fichero JAR (o a varios ficheros JAR) que servirán como una extensión para los propósitos del applet. Las extensiones pueden referenciarse unas a otras de la misma forma.
La descarga de extensiones se especifica en el campo de cabecera Class-Path en el fichero de manifiesto del applet, aplicación, u otra extensión. Una cabecera Class-Path se podría parecer a esto, por ejemplo:
Class-Path: servlet.jar infobus.jar acme/beans.jar
Con esta cabcera, las clases de los ficheros servlet.jar, infobus.jar, y acme/beans.jar servirán como extensiones para los propósitos del applet o aplicación. Las URLs en la cabecera Class-Path son relativas a la URL del fichero JAR del applet o de la aplicación.
Sellado de Paquetes - sólo versión 1.2
Los paquetes almacenados en ficheros JAR pueden ser sellados opcionalmente para que el paquete pueda reforzar su consistencia. El sellado de un paquete dentro de un fichero JAR significa que todas las clases definidas en ese paquete deben encontrarse dentro del mismo fichero JAR.
Un paquete puede sellarse añadiendo la cabecera Sealed:
Name: myCompany/myPackage/
Sealed: true
Versionado de Paquetes - sólo versión 1.2
La pagina Especificación de Versionado de Paquetes define varias cabeceras de manifiesto para contener información del versionado. Un conjunto de dichas cabeceras puede ser asignado a cada paquete. Las cabeceras de versionado deberían aparecer directamente debajo de la cabecera name del paquete. Este ejemplo muestra las cabeceras de versionado:
Name: java/util/
Specification-Title: "Java Utility Classes"
Specification-Version: "1.2"
Specification-Vendor: "Sun Microsystems Inc.".
Implementation-Title: "java.util"
Implementation-Version: "build57"
Implementation-Vendor: "Sun Microsystems. Inc."