META-INF的目的是什么?

在Java中,您经常会看到包含一些元文件的meta - inf文件夹。这个文件夹的目的是什么?我可以在那里放什么?

309556 次浏览

官方JAR文件规范(链接到Java 7版本,但文本自至少v1.3以来没有改变):

META-INF目录

以下文件/目录在META-INF目录下被Java 2平台识别和解释,以配置应用程序、扩展、类加载器和服务:

  • MANIFEST.MF

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

  • INDEX.LIST

此文件由新的"-i"jar工具的选项,它包含应用程序或扩展中定义的包的位置信息。它是JarIndex实现的一部分,类装入器使用它来加速类装入过程。

  • x.SF

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

  • x.DSA

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

  • services/

此目录存储所有服务提供者配置文件。

自Java 9实现中238以来新增了多版本jar。会看到一个子文件夹versions。这个特性允许将不同Java版本的类打包到一个jar中。

META-INF文件夹是清单。曼氏金融文件的主文件夹。该文件包含关于JAR内容的元数据。例如,有一个名为main - class的条目,它为可执行JAR文件指定了带有静态main()的Java类的名称。

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

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

至少,我认为这很简单……: -)

关键是META-INF应该被认为是一个内部Java 目录。别乱动它!您希望包含在JAR中的任何文件都应该放在其他子目录中或JAR本身的根目录中。

我注意到一些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中,到底有什么问题。但这似乎是一个新兴的事实标准;要么这样,要么出现反模式:-)

只是在这里添加信息,如果是WAR文件,则是META-INF/MANIFEST。MF文件为开发人员提供了由容器发起部署时检查的工具,以确保容器可以找到应用程序所依赖的所有类。这确保了万一您丢失了一个JAR,您不必等到应用程序在运行时崩溃时才意识到它丢失了。

如果你正在使用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 < / p >

我最近一直在思考这个问题。对于META-INF的使用似乎真的没有任何限制。当然,有一些限制,关于把舱单放在那里的必要性,但似乎没有任何禁止把其他东西放在那里。

为什么会这样呢?

cxf案例可能是合法的。这里是建议使用非标准的另一个地方,它可以绕过JBoss-ws中防止针对wsdl模式进行服务器端验证的严重错误。

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

但似乎真的没有什么标准,没有什么千言万语。通常这些事情都有非常严格的定义,但出于某种原因,这里似乎没有标准。奇数。META-INF似乎已经成为了一个无所不包的地方,任何所需的配置都无法通过其他方式轻松处理。

Maven中的META-INF

在Maven中,meta - inf文件夹是可以理解的,因为标准目录布局根据名称约定将项目资源打包到JAR中:任何放置在$ {basedir} / src / main /资源目录中的目录或文件都被打包到JAR中,从JAR的底部开始具有完全相同的结构。

文件夹$ {basedir} / src / main / resources / meta - inf通常包含. properties文件,而在jar中包含生成的清单。曼氏金融pom.propertiespom.xml等文件。同样,像春天这样的框架使用classpath:/META-INF/resources/来提供web资源。

更多信息见如何向Maven项目添加资源

所有答案都是正确的。Meta-inf有很多用途。此外,这里还有一个关于使用tomcat容器的示例。

< p > Tomcat医生和检查

. " 标准实现> copyXML "属性

描述如下。

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

你有舱单。MF文件在你的META-INF文件夹。你可以定义可选或外部依赖项,你必须访问。

例子:

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

Source:头第一Jsp &Servlet

添加到这里的信息,META-INF是一个特殊的文件夹,ClassLoader将其与jar中的其他文件夹区别对待。 嵌套在META-INF文件夹内的元素不会与它外部的元素混合。< / p >

把它想象成另一个根。从Enumerator<URL> ClassLoader#getSystemResources(String path)方法等的角度来看:

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

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

如果你知道getSystemResources方法特别处理的另一个文件夹名称,请评论它。

作为补充,META-INF文件夹现在也用于multi-release罐子。这是一个允许将针对不同Java版本的类打包到一个jar中的特性,例如包含一个针对Java 11的类,其中包含Java 11提供的新特性,在一个jar中也适用于Java 8,其中针对Java 8的不同类中包含较少的特性。例如,如果一个较新的Java版本提供了增强的、不同的或新的API方法,而这些方法在较早的版本中由于违反API而无法工作,那么这可能是有用的。然后会看到子文件夹versions