¿Cuál es el propósito de META-INF?

Respuestas:

65

En términos generales, no debe poner nada en META-INF usted mismo. En su lugar, debe confiar en lo que utilice para empaquetar su JAR. Esta es una de las áreas en las que creo que Ant realmente se destaca: especificando los atributos de manifiesto del archivo JAR. Es muy fácil decir algo como:

<jar ...>
    <manifest>
        <attribute name="Main-Class" value="MyApplication"/>
    </manifest>
</jar>

Al menos, creo que es fácil ... :-)

El punto es que META-INF debería considerarse como una interna de Java meta directorio. ¡No te metas con eso! Cualquier archivo que desee incluir con su JAR debe colocarse en algún otro subdirectorio o en la raíz del JAR mismo.

Daniel Spiewak
fuente
17
¿Qué hay de los servicios? ¿Descriptores de biblioteca de etiquetas? Poner algo en la raíz de un JAR es una mala idea. En ausencia de una convención clara, es muy probable que los recursos en la raíz choquen.
Erickson
13
Si está utilizando JPA, entonces debe poner un persistence.xml en esa carpeta, eso es algo que no sucede automáticamente.
JRSofty
44
Esta sería una buena respuesta, excepto que en una aplicación Spring MVC simple, META-INF es el único directorio donde los archivos de configuración pueden ser referenciados tanto por las pruebas unitarias como por los controladores. Si otro directorio funcionara, sería genial, no lo hace (al menos no directamente). Para mí, construir un archivo Jar solo para probar un archivo de guerra es como construir un auto para que puedas caminar a la cocina. Al menos para mi. Pero pasé un tiempo haciendo Ruby, y pueden haberme arruinado en lo que respecta a los archivos de configuración (aunque cambiaré un pequeño infierno XML por saber cuáles son los tipos de mis parámetros). :)
John Lockwood
¿Puede darnos algún ejemplo sobre los tipos de archivos que debe contener esta carpeta?
Menai Ala Eddine - Aladdin
3
Esto no responde qué es META-INF. Si tuviera una respuesta a eso, entonces quizás podría juzgar si poner algo en esa carpeta "nunca" debería hacerse, yo mismo.
Kröw
164

De la especificación oficial de archivos JAR (el enlace va a la versión de Java 7, pero el texto no ha cambiado desde al menos v1.3):

El directorio META-INF

La Plataforma Java 2 reconoce e interpreta los siguientes archivos / directorios en el directorio META-INF para configurar aplicaciones, extensiones, cargadores de clases y servicios:

  • MANIFEST.MF

El archivo de manifiesto que se utiliza para definir la extensión y el paquete de datos relacionados.

  • INDEX.LIST

Este archivo es generado por la nueva " -i" opción de la herramienta jar, que contiene información de ubicación para los paquetes definidos en una aplicación o extensión. Es parte de la implementación de JarIndex y es utilizado por los cargadores de clases para acelerar su proceso de carga de clases.

  • x.SF

El archivo de firma para el archivo JAR. 'x' representa el nombre del archivo base.

  • x.DSA

El archivo de bloque de firma asociado con el archivo de firma con el mismo nombre de archivo base. Este archivo almacena la firma digital del archivo de firma correspondiente.

  • services/

Este directorio almacena todos los archivos de configuración del proveedor de servicios.

aku
fuente
3
Los TLD también deben pasar por META-INF.
Erickson
@erickson, ¿elaborado?
Pacerier
Los descriptores de la biblioteca de etiquetas @Pacerier para las bibliotecas de etiquetas JSP deben ubicarse en el directorio META-INF. Había olvidado lo que representaba TLD en 2008.
erickson
27

Me di cuenta de que algunas bibliotecas Java han comenzado a usar META-INF como un directorio en el que incluir archivos de configuración que deberían empaquetarse e incluirse en CLASSPATH junto con JAR. Por ejemplo, Spring le permite importar archivos XML que están en el classpath usando:

<import resource="classpath:/META-INF/cxf/cxf.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extensions-*.xml" />

En este ejemplo, estoy citando directamente de la Guía del usuario de Apache CXF . En un proyecto en el que trabajé en el que teníamos que permitir múltiples niveles de configuración a través de Spring, seguimos esta convención y pusimos nuestros archivos de configuración en META-INF.

Cuando reflexiono sobre esta decisión, no sé qué sería exactamente incorrecto simplemente incluir los archivos de configuración en un paquete Java específico, en lugar de en META-INF. Pero parece ser un estándar de facto emergente; o eso, o un antipatrón emergente :-)

usuario38748
fuente
44
Configuraton no pertenece a una biblioteca. Creo que lo has clavado con un "antipatrón emergente". Es realmente bastante fácil localizar archivos de configuración relativos a una biblioteca; no necesitan ir físicamente en el mismo JAR para ser encontrados.
Erickson
24
No estoy de acuerdo con la afirmación de que la configuración no pertenece a una biblioteca. Creo que la configuración, especialmente cuando se trata de valores predeterminados, está bien empaquetada en una biblioteca. En realidad, me alegro de que más marcos eligieran trabajar de esta manera en lugar de obligarlo a incluir todo tipo de archivos de configuración externos como era común no hace mucho tiempo.
Eelco
1
También he visto muchos archivos tipo LICENSE.TXT en META_INF, lo que me parece molesto.
Ti Strga
@Eelco, el código y los datos no deben mezclarse. Incluir archivos de configuración externos no necesariamente significa un desastre de usabilidad. Depende de cómo esté estructurado.
Pacerier
1
Es algo bastante arbitrario decir @Pacerier. Como una declaración general, es en gran medida preferencia.
Eelco
13

La carpeta META-INF es el hogar del archivo MANIFEST.MF . Este archivo contiene metadatos sobre el contenido del JAR. Por ejemplo, hay una entrada llamada Main-Class que especifica el nombre de la clase Java con el estático main () para los archivos JAR ejecutables.

Brian Matthews
fuente
10

También puede colocar recursos estáticos allí.

Por ejemplo:

META-INF/resources/button.jpg 

y obtenerlos en el contenedor web3.0 a través de

http://localhost/myapp/button.jpg

> Leer más

/META-INF/MANIFEST.MF tiene un significado especial:

  1. Si ejecuta un jar usando java -jar myjar.jar org.myserver.MyMainClasspuede mover la definición de clase principal al jar para que pueda reducir la llamada java -jar myjar.jar.
  2. Puede definir Metainformaciones a paquetes si lo usa java.lang.Package.getPackage("org.myserver").getImplementationTitle().
  3. Puede hacer referencia a los certificados digitales que desea utilizar en el modo Applet / Webstart.
Severo
fuente
Por lo tanto, cualquier elemento estático en la aplicación debe colocarse en este directorio como imágenes u otros elementos.
Menai Ala Eddine - Aladdin
6

META-INF en Maven

En Maven, la carpeta META-INF se entiende por el diseño de directorio estándar , que por convención de nombre empaqueta los recursos de su proyecto dentro de los JAR: cualquier directorio o archivo ubicado dentro del directorio $ {basedir} / src / main / resources se empaqueta en su JAR con exactamente la misma estructura comenzando en la base del JAR. La carpeta $ {basedir} / src / main / resources / META-INF generalmente contiene archivos .properties , mientras que en el jar contiene un MANIFEST.MF , pom.properties , pom.xml , entre otros archivos. También los marcos como Spring usan classpath:/META-INF/resources/para servir recursos web. Para más información, ver¿Cómo agrego recursos a mi Proyecto Maven ?

EliuX
fuente
5

Solo para agregar a la información aquí, en el caso de un archivo WAR, el archivo META-INF / MANIFEST.MF proporciona al desarrollador una facilidad para iniciar una verificación de tiempo de implementación por el contenedor que garantiza que el contenedor pueda encontrar todas las clases de su aplicación depende de. Esto garantiza que, en caso de que se haya perdido un JAR, no tendrá que esperar hasta que su aplicación explote en tiempo de ejecución para darse cuenta de que falta.

sasuke
fuente
5

He estado pensando en este tema recientemente. Realmente no parece haber ninguna restricción en el uso de META-INF. Existen ciertas restricciones, por supuesto, sobre la necesidad de poner el manifiesto allí, pero no parece haber ninguna prohibición sobre poner otras cosas allí.

¿Por qué es este el caso?

El caso cxf puede ser legítimo. Aquí hay otro lugar donde se recomienda este no estándar para evitar un error desagradable en JBoss-ws que impide la validación del lado del servidor contra el esquema de un wsdl.

http://community.jboss.org/message/570377#570377

Pero realmente no parece haber ningún estándar, ningún deberías. Por lo general, estas cosas están muy rigurosamente definidas, pero por alguna razón, parece que no hay estándares aquí. Impar. Parece que META-INF se ha convertido en un lugar ideal para cualquier configuración necesaria que no pueda manejarse fácilmente de otra manera.

Steve Cohen
fuente
5

Además de la información aquí, META-INF es una carpeta especial que ClassLoadertrata de manera diferente a otras carpetas en el frasco. Los elementos anidados dentro de la carpeta META-INF no se mezclan con los elementos fuera de ella.

Piense en ello como otra raíz. Desde el Enumerator<URL> ClassLoader#getSystemResources(String path)método et al perspectiva:

Cuando la ruta dada comienza con "META-INF", el método busca recursos que están anidados dentro de las carpetas META-INF de todos los archivos jar en la ruta de clase.

Cuando la ruta dada no comienza con "META-INF", el método busca recursos en todas las demás carpetas (fuera de META-INF) de todos los archivos jar y directorios en la ruta de clase.

Si conoce otro nombre de carpeta que el getSystemResourcesmétodo trata especialmente, comente al respecto.

Readren
fuente
3

Si está utilizando JPA1, es posible que deba colocar un persistence.xmlarchivo que especifique el nombre de una unidad de persistencia que desee utilizar. Una unidad de persistencia proporciona una manera conveniente de especificar un conjunto de archivos de metadatos, y clases y frascos que contienen todas las clases que se conservarán en un grupo.

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

Ver más aquí: http://www.datanucleus.org/products/datanucleus/jpa/emf.html

f0ster
fuente
1

Todas las respuestas son correctas. Meta-inf tiene muchos propósitos. Además, aquí hay un ejemplo sobre el uso del contenedor Tomcat.

Vaya a Tomcat Doc y marque el atributo " Implementación estándar> copyXML ".

La descripción está abajo.

Establézcalo en verdadero si desea que un descriptor XML de contexto incrustado dentro de la aplicación (ubicado en /META-INF/context.xml) se copie en la xmlBase del Host propietario cuando se implemente la aplicación. En inicios posteriores, el descriptor XML de contexto copiado se utilizará con preferencia a cualquier descriptor XML de contexto incrustado dentro de la aplicación, incluso si el descriptor incrustado dentro de la aplicación es más reciente. El valor de la bandera por defecto es falso. Tenga en cuenta que si el atributo deployXML del Host propietario es falso o si el atributo copyXML del Host propietario es verdadero, este atributo no tendrá ningún efecto.

Tugrul
fuente
0

Tiene el archivo MANIFEST.MF dentro de su carpeta META-INF. Puede definir dependencias opcionales o externas a las que debe tener acceso.

Ejemplo:

Considere que ha implementado su aplicación y su contenedor (en tiempo de ejecución) descubrió que su aplicación requiere una versión más nueva de una biblioteca que no está dentro de la carpeta lib, en ese caso, si ha definido la versión más nueva opcional, MANIFEST.MFentonces su aplicación hará referencia a la dependencia desde allí (y no se bloqueará).

Source: Head First Jsp & Servlet

Prateek Joshi
fuente
1
No está claro cuánto de esto se cita de la fuente, y no parece textual. Se eliminó el formato extraño. No use el formato de código para texto que no sea código. Utilice el formato de comillas para el texto que se cita.
Marqués de Lorne