META-INF的目的是什么?


Answers:


65

一般来说,您不应该自己在META-INF中添加任何内容。相反,您应该依靠任何用于打包JAR的东西。这是我认为Ant真正擅长的领域之一:指定JAR文件清单属性。像这样说很容易:

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

至少,我认为这很容易... :-)

关键是应将META-INF视为内部Java 目录。不要惹它!您要包含在JAR中的任何文件都应放在其他子目录中或JAR本身的根目录中。


17
服务如何?标签库描述符?将某些内容放在JAR的根中是一个坏主意。在没有明确约定的情况下,根源中的资源很可能发生冲突。
erickson

13
如果您使用的是JPA,则必须将persistence.xml放入该文件夹中,这不会自动发生。
JRSofty 2011年

4
这将是一个很好的答案,除了在简单的Spring MVC应用程序中,META-INF是唯一可以在单元测试和控制器中都引用配置文件的目录。如果另一个目录有效,那将是很好的-至少(不是直接做到)不是。对我来说,建立一个Jar文件来测试战争文件就像建立一辆汽车,以便您可以步行到厨房。至少对我来说。但是我花了一些时间做Ruby,就配置文件而言,它们可能毁了我(尽管我会为了了解我的参数类型而作一点XML地狱)。:)
约翰·洛克伍德

您能否举一些有关此文件夹应包含的文件类型的示例?
Menai Ala Eddine

3
这不能回答META-INF是什么。如果我对此有一个答案,那么也许我可以自己判断是否应该“绝对”不要在该文件夹中放置某些东西。
10Kröw

164

来自官方的JAR文件规范(链接指向Java 7版本,但至少从v1.3起,文本没有更改):

META-INF目录

Java 2 Platform识别并解释了META-INF目录中的以下文件/目录,以配置应用程序,扩展,类加载器和服务:

  • MANIFEST.MF

用于定义扩展名和打包相关数据的清单文件。

  • INDEX.LIST

该文件由-ijar工具的新“ ”选项生成,其中包含应用程序或扩展中定义的包的位置信息。它是JarIndex实现的一部分,并且由类加载器用来加速其类加载过程。

  • x.SF

JAR文件的签名文件。“ x”代表基本文件名。

  • x.DSA

与具有相同基本文件名的签名文件关联的签名块文件。该文件存储相应签名文件的数字签名。

  • services/

该目录存储所有服务提供商的配置文件。


3
TLD也必须属于META-INF。
erickson

@erickson,详细吗?
Pacerier,

JSP标记库的@Pacerier标记库描述符必须位于META-INF目录中。我已经忘了TLD在2008
。– erickson

27

我注意到一些Java库已经开始使用META-INF作为目录,其中包含应该打包的配置文件,以及JAR一起包含在CLASSPATH中。例如,Spring允许您使用以下命令导入类路径上的XML文件:

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

在此示例中,我直接引用了《Apache CXF用户指南》。在我从事的一个项目中,我们必须通过Spring进行多级配置,我们遵循了这一约定并将配置文件放入META-INF中。

当我考虑这个决定时,我不知道仅将配置文件包含在特定的Java包中,而不是将其包含在META-INF中到底有什么问题。但这似乎是一个新兴的事实上的标准。要么是这样,要么是新兴的反模式:-)


4
Configuraton不属于库。我认为您用“新兴的反模式”将其钉住了。找到相对于库的配置文件确实非常容易。他们不需要实际进入相同的JAR即可找到。
erickson

24
我不同意配置不属于库的说法。我认为配置(尤其是默认设置)可以很好地打包在库中。实际上,我很高兴有更多的框架选择像这样工作,而不是强迫您包括各种外部配置文件,就像不久前常见的那样。
Eelco

1
我一直在META_INF中看到很多LICENSE.TXT类型的文件,这很烦人。
Ti Strga

@Eelco,代码和数据应该混合。包括外部配置文件并不一定意味着可用性混乱。这取决于它的结构。
和平者

1
声明@Pacerier是一件很随意的事情。一般而言,这是首选。
Eelco 2014年

13

META-INF文件夹是MANIFEST.MF文件的宿主。该文件包含有关JAR内容的元数据。例如,有一个名为Main-Class的条目,该条目使用可执行的JAR文件的静态main()指定Java类的名称。


10

您也可以在其中放置静态资源。

例如:

META-INF/resources/button.jpg 

并通过以下方式将其放入web3.0容器中

http://localhost/myapp/button.jpg

>阅读更多

/META-INF/MANIFEST.MF具有特殊含义:

  1. 如果使用运行jar java -jar myjar.jar org.myserver.MyMainClass,则可以将主类定义移入jar,以便将调用缩小为java -jar myjar.jar
  2. 您可以使用定义包的元信息java.lang.Package.getPackage("org.myserver").getImplementationTitle()
  3. 您可以引用要在Applet / Webstart模式下使用的数字证书。

因此,应用程序中的任何静态内容都应与图像或其他内容一样放置在此目录中。
Menai Ala Eddine

6

Maven中的META-INF

在Maven中,理解META-INF文件夹的原因是“ 标准目录布局”,它按照名称约定将您的项目资源打包在JAR中:放置在$ {basedir} / src / main / resources目录中的任何目录或文件都打包到JAR中从JAR的基础开始具有完全相同的结构。文件夹$ {basedir} / src / main / resources / META-INF通常包含.properties文件,而jar中的文件包含生成的MANIFEST.MFpom.propertiespom.xml等文件。像Spring这样的框架也可以classpath:/META-INF/resources/用来提供Web资源。有关更多信息,请参见如何向Maven项目添加资源


5

仅在此处添加信息,如果是WAR文件,则META-INF / MANIFEST.MF文件为开发人员提供了一种通过容器启动部署时间检查的功能,以确保容器可以找到您的应用程序的所有类。取决于。这样可以确保在错过JAR的情况下,您不必等到应用程序在运行时崩溃就知道它丢失了。


5

我最近一直在考虑这个问题。使用META-INF似乎没有任何限制。当然,对于将清单放在其中的必要性有一些限制,但是似乎没有任何禁止在其中放入其他内容的禁止。

为什么会这样呢?

cxf案件可能是合法的。在另一个地方,建议使用这种非标准的方法来解决JBoss-ws中的一个讨厌的错误,该错误会阻止针对wsdl模式的服务器端验证。

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

但是,实际上似乎没有任何标准,没有任何提示。通常,这些东西的定义非常严格,但是由于某种原因,似乎这里没有标准。奇。似乎META-INF已成为无法通过其他方式轻松处理的所有所需配置的统筹兼顾的地方。


5

除了此处的信息外,META-INF是一个特殊的文件ClassLoader夹,与jar中的其他文件夹区别对待。嵌套在META-INF文件夹内的元素不会与它外部的元素混合。

认为它像另一个根。从Enumerator<URL> ClassLoader#getSystemResources(String path)方法等角度来看:

当给定路径以“ META-INF”开头时,该方法将搜索嵌套在类路径中所有jar的META-INF文件夹内的资源。

当给定路径不是以“ META-INF”开头时,该方法将在类路径中所有jar和目录的所有其他文件夹(META-INF之外)中搜索资源。

如果您知道该getSystemResources方法特别处理的另一个文件夹名称,请对此进行评论。


3

如果使用的是JPA1,则可能必须persistence.xml在其中放置一个文件,该文件指定您可能要使用的持久性单元的名称。持久性单元提供了一种方便的方法,用于指定一组元数据文件,类以及包含要分组保存的所有类的jar。

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

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

在此处查看更多信息:http : //www.datanucleus.org/products/datanucleus/jpa/emf.html


1

所有答案都是正确的。Meta-inf有许多目的。此外,这是有关使用tomcat容器的示例。

转到 Tomcat Doc并检查“ Standard Implementation> copyXML ”属性。

说明如下。

如果您希望在部署应用程序时将嵌入在应用程序中的上下文XML描述符(位于/META-INF/context.xml)复制到所有者的xmlBase中,请设置为true。在随后的启动中,将优先使用复制的上下文XML描述符,即使嵌入在应用程序内部的描述符是最新的,也将优先使用嵌入在应用程序内部的任何上下文XML描述符。该标志的值默认为false。请注意,如果拥有主机的deployXML属性为false,或者拥有主机的copyXML属性为true,则此属性无效。


0

您在META-INF文件夹中有MANIFEST.MF文件。您可以定义必须具有访问权限的可选或外部依赖项

例:

考虑到您已经部署了应用程序,并且您的容器(在运行时)发现您的应用程序需要库的较新版本,该库不在lib文件夹中,在这种情况下,如果您在其中定义了可选的较新版本,MANIFEST.MF则您的应用程序将引用从那里依赖(并且不会崩溃)。

Source: 首先是Jsp和Servlet


1
目前尚不清楚从源头中引用多少,而且看起来不是逐字的。删除了奇怪的格式。不要对非代码文本使用代码格式。不要对引用的文本使用引号格式。
洛恩侯爵,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.