Qual é o objetivo do META-INF?

Respostas:

65

De um modo geral, você não deve colocar nada no META-INF. Em vez disso, você deve confiar no que quer que use para empacotar seu JAR. Essa é uma das áreas em que acho que o Ant realmente se destaca: especificar atributos de manifesto do arquivo JAR. É muito fácil dizer algo como:

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

Pelo menos, acho que é fácil ... :-)

O ponto é que o META-INF deve ser considerado um meta- diretório Java interno . Não mexa com isso! Todos os arquivos que você deseja incluir no seu JAR devem ser colocados em algum outro subdiretório ou na raiz do próprio JAR.

Daniel Spiewak
fonte
17
E os serviços? Descritores da biblioteca de tags? Colocar algo na raiz de um JAR é uma má ideia. Na ausência de uma convenção clara, é provável que os recursos na raiz colidam.
24680
13
Se você estiver usando o JPA, deverá colocar um persistence.xml nessa pasta, algo que não acontece automaticamente.
JRSofty
4
Essa seria uma boa resposta, exceto que, em um aplicativo Spring MVC simples, o META-INF é o único diretório em que os arquivos de configuração podem ser referenciados pelos testes de unidade e pelos controladores. Se outro diretório funcionasse, seria ótimo - não funciona (pelo menos não diretamente). Para mim, construir um arquivo Jar apenas para testar um arquivo de guerra é como construir um carro para que você possa caminhar até a cozinha. Pelo menos para mim. Mas passei algum tempo fazendo Ruby, e eles podem ter me arruinado no que diz respeito aos arquivos de configuração (embora eu trocarei um pouco de XML por saber quais são os tipos dos meus parâmetros). :)
John Lockwood
Você pode nos dar um exemplo sobre os tipos de arquivos que devem conter esta pasta?
Menai Ala Eddine # Aladdin
3
Isso não responde o que é META-INF. Se eu tivesse uma resposta para isso, talvez eu pudesse julgar se colocar algo nessa pasta "nunca" deveria ser feito, eu mesmo.
Kröw 19/06/19
164

Na especificação oficial do arquivo JAR (o link vai para a versão Java 7, mas o texto não mudou desde pelo menos a v1.3):

O diretório META-INF

Os seguintes arquivos / diretórios no diretório META-INF são reconhecidos e interpretados pela Plataforma Java 2 para configurar aplicativos, extensões, carregadores de classe e serviços:

  • MANIFEST.MF

O arquivo de manifesto usado para definir extensão e pacote de dados relacionados.

  • INDEX.LIST

Este arquivo é gerado pela nova -iopção " " da ferramenta jar, que contém informações de localização dos pacotes definidos em um aplicativo ou extensão. Faz parte da implementação do JarIndex e é usada pelos carregadores de classes para acelerar o processo de carregamento de classes.

  • x.SF

O arquivo de assinatura para o arquivo JAR. 'x' representa o nome do arquivo base.

  • x.DSA

O arquivo de bloco de assinatura associado ao arquivo de assinatura com o mesmo nome de arquivo base. Este arquivo armazena a assinatura digital do arquivo de assinatura correspondente.

  • services/

Este diretório armazena todos os arquivos de configuração do provedor de serviços.

aku
fonte
3
Os TLDs também devem estar sob o META-INF.
24680
@erickson, Elaborado?
Pacerier 16/06/19
Os descritores da biblioteca de tags @Pacerier para bibliotecas de tags JSP devem estar localizados no diretório META-INF. Eu tinha esquecido o que o TLD representava em 2008.
erickson
27

Percebi que algumas bibliotecas Java começaram a usar o META-INF como um diretório no qual incluir arquivos de configuração que devem ser empacotados e incluídos no CLASSPATH junto com os JARs. Por exemplo, o Spring permite importar arquivos XML que estão no caminho de classe usando:

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

Neste exemplo, estou citando diretamente o Guia do usuário do Apache CXF . Em um projeto em que trabalhei, no qual tínhamos que permitir vários níveis de configuração via Spring, seguimos esta convenção e colocamos nossos arquivos de configuração no META-INF.

Quando reflito sobre essa decisão, não sei o que exatamente estaria errado ao incluir simplesmente os arquivos de configuração em um pacote Java específico, em vez de no META-INF. Mas parece ser um padrão emergente de fato; ou isso, ou um anti-padrão emergente :-)

user38748
fonte
4
A configuração não pertence a uma biblioteca. Eu acho que você acertou em cheio com "anti-padrão emergente". É realmente muito fácil localizar arquivos de configuração em relação a uma biblioteca; eles não precisam ir fisicamente no mesmo JAR a ser encontrado.
24580
24
Não concordo com a afirmação de que a configuração não pertence a uma biblioteca. Eu acho que a configuração, especialmente quando se trata de padrões, são compactadas em uma biblioteca. Na verdade, estou feliz que mais estruturas optaram por trabalhar dessa maneira, em vez de forçar você a incluir todos os tipos de arquivos de configuração externos, como era comum há pouco tempo.
Eelco
1
Eu tenho visto muitos arquivos do tipo LICENSE.TXT aparecendo no META_INF também, o que acho irritante.
Ti Strga
@ Elelco, código e dados não devem se misturar. Incluir arquivos de configuração externos não significa necessariamente uma bagunça na usabilidade. Depende de como está estruturado.
Pacerier
1
É algo bastante arbitrário afirmar o @Pacerier. Como uma declaração geral, é em grande parte preferência.
Eelco
13

A pasta META-INF é o lar do arquivo MANIFEST.MF . Este arquivo contém metadados sobre o conteúdo do JAR. Por exemplo, há uma entrada chamada Main-Class que especifica o nome da classe Java com o static main () para arquivos JAR executáveis.

Brian Matthews
fonte
10

Você também pode colocar recursos estáticos lá.

No exemplo:

META-INF/resources/button.jpg 

e obtê-los no web3.0-container via

http://localhost/myapp/button.jpg

> Leia mais

O /META-INF/MANIFEST.MF tem um significado especial:

  1. Se você executar um jar usando, java -jar myjar.jar org.myserver.MyMainClasspoderá mover a definição da classe principal para dentro do jar para reduzir a chamada java -jar myjar.jar.
  2. Você pode definir metainformações para pacotes, se você usar java.lang.Package.getPackage("org.myserver").getImplementationTitle().
  3. Você pode fazer referência aos certificados digitais que deseja usar no modo Applet / Webstart.
Sombrio
fonte
Portanto, qualquer material estático no aplicativo deve ser colocado nesse diretório, como imagens ou outros materiais.
Menai Ala Eddine - Aladdin
6

META-INF em Maven

No Maven, a pasta META-INF é entendida por causa do Layout de Diretório Padrão , que por convenção de nome empacota os recursos do seu projeto nos JARs: todos os diretórios ou arquivos colocados no diretório $ {basedir} / src / main / resources são empacotados no seu JAR com exatamente a mesma estrutura começando na base do JAR. A pasta $ {basedir} / src / main / resources / META-INF geralmente contém arquivos .properties enquanto no jar contém um MANIFEST.MF , pom.properties , o pom.xml , entre outros arquivos. Também estruturas como o Spring usam classpath:/META-INF/resources/para servir recursos da web. Para mais informações, vejaComo adiciono recursos ao meu projeto Maven .

EliuX
fonte
5

Apenas para adicionar às informações aqui, no caso de um arquivo WAR, o arquivo META-INF / MANIFEST.MF fornece ao desenvolvedor um recurso para iniciar uma verificação do tempo de implantação pelo contêiner, o que garante que o contêiner possa encontrar todas as classes de seu aplicativo depende de. Isso garante que, caso você tenha perdido um JAR, não precisará esperar até que seu aplicativo seja executado em tempo de execução para perceber que ele está ausente.

sasuke
fonte
5

Eu estive pensando sobre esse problema recentemente. Realmente não parece haver nenhuma restrição ao uso do META-INF. Há certas restrições, é claro, sobre a necessidade de colocar o manifesto lá, mas não parece haver nenhuma proibição de colocar outras coisas lá.

Por que esse é o caso?

O caso cxf pode ser legítimo. Aqui está outro lugar em que esse padrão não é recomendado para contornar um bug desagradável no JBoss-ws que impede a validação do servidor contra o esquema de um wsdl.

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

Mas, na verdade, não parece haver nenhum padrão, nenhum tu não deves. Geralmente, essas coisas são definidas com muito rigor, mas, por alguma razão, parece que não há padrões aqui. Ímpar. Parece que o META-INF se tornou um local fácil para qualquer configuração necessária que não possa ser facilmente manipulada de outra maneira.

Steve Cohen
fonte
5

Adicionando as informações aqui, o META-INF é uma pasta especial que o ClassLoader trata de forma diferente de outras pastas no jar. Os elementos aninhados dentro da pasta META-INF não são misturados com os elementos fora dela.

Pense nisso como outra raiz. DeEnumerator<URL> ClassLoader#getSystemResources(String path) perspectiva método e outros:

Quando o caminho fornecido começa com "META-INF", o método procura recursos aninhados dentro das pastas META-INF de todos os jars no caminho da classe.

Quando o caminho especificado não inicia com "META-INF", o método procura recursos em todas as outras pastas (fora do META-INF) de todos os jars e diretórios no caminho da classe.

Se você souber sobre outro nome de pasta que o getSystemResourcesmétodo trata especialmente, comente.

Readren
fonte
3

Se você estiver usando o JPA1, talvez seja necessário soltar um persistence.xmlarquivo que especifique o nome de uma unidade de persistência que você deseja usar. Uma unidade de persistência fornece uma maneira conveniente de especificar um conjunto de arquivos de metadados, classes e jars que contêm todas as classes a serem persistidas em um agrupamento.

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

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

Veja mais aqui: http://www.datanucleus.org/products/datanucleus/jpa/emf.html

f0ster
fonte
1

Todas as respostas estão corretas. Meta-inf tem muitos propósitos. Além disso, aqui está um exemplo sobre o uso do contêiner do tomcat.

Vá para o Tomcat Doc e verifique o atributo " Implementação padrão> copyXML ".

A descrição está abaixo.

Configure como true se desejar que um descritor XML de contexto incorporado ao aplicativo (localizado em /META-INF/context.xml) seja copiado para o xmlBase do Host proprietário quando o aplicativo for implantado. Nas iniciações subsequentes, o descritor XML de contexto copiado será usado de preferência a qualquer descritor XML de contexto incorporado dentro do aplicativo, mesmo que o descritor incorporado dentro do aplicativo seja mais recente. O valor do sinalizador é padronizado como false. Observe se o atributo deployXML do host proprietário for falso ou se o atributo copyXML do host proprietário for true, esse atributo não terá efeito.

Tugrul
fonte
0

Você tem o arquivo MANIFEST.MF dentro da pasta META-INF. Você pode definir dependências opcionais ou externas quais você deve ter acesso.

Exemplo:

Considere que você implantou seu aplicativo e seu contêiner (em tempo de execução) descobriu que seu aplicativo requer uma versão mais recente de uma biblioteca que não está dentro da pasta lib; nesse caso, se você definiu a versão mais recente opcional em MANIFEST.MF , seu aplicativo consultará à dependência de lá (e não falhará).

Source: Head First Jsp & Servlet

Prateek Joshi
fonte
1
Não está claro quanto disso é citado da fonte e não parece literal. Removida a formatação bizarra. Não use formatação de código para texto que não seja código. Use formatação de citação para o texto citado.
Marquês de Lorne