it-swarm.cn

META-INF的目的是什么?

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

265
Kristian

一般来说,你不应该自己把任何东西放到META-INF中。相反,你应该依靠你用来打包JAR的任何东西。这是我认为Ant非常擅长的领域之一:指定JAR文件清单属性。说起来很容易:

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

至少,我觉得这很容易...... :-)

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

60
Daniel Spiewak

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

META-INF目录

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

  • MANIFEST.MF

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

  • INDEX.LIST

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

  • x.SF

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

  • x.DSA

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

  • services/

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

156
aku

我注意到一些Java库已经开始使用META-INF作为一个目录,其中包含应该打包并包含在CLASSPATH中的配置文件以及JAR。例如,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中究竟会出现什么问题。但它似乎是一个新兴的事实上的标准;无论是那个,还是一个新兴的反模式:-)

24
user38748

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

10
Brian Matthews

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

例如:

META-INF/resources/button.jpg 

并通过它在web3.0容器中获取它们

http://localhost/myapp/button.jpg

>了解更多

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

  1. 如果使用Java -jar myjar.jar org.myserver.MyMainClass运行jar,可以将主类定义移动到jar中,这样就可以将调用缩小为Java -jar myjar.jar
  2. 如果使用Java.lang.Package.getPackage("org.myserver").getImplementationTitle(),可以将Metainformation定义为包。
  3. 您可以参考您希望在Applet/Webstart模式下使用的数字证书。
8
Peter Rader

只是为了添加这里的信息,在WAR文件的情况下,META-INF/MANIFEST.MF文件为开发人员提供了一个工具来启动容器的部署时检查,确保容器可以找到应用程序的所有类。依赖于取决于。这可以确保在您错过JAR的情况下,您不必等到应用程序在运行时爆炸才能意识到它已丢失。

4
sasuke

添加到此处的信息,META-INF是一个特殊的文件夹,ClassLoader与jar中的其他文件夹不同。嵌套在META-INF文件夹中的元素不会与其外部的元素混合。

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

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

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

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

4
Readren

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

为什么会这样?

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

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

但实际上似乎没有任何标准,任何你都不会。通常这些东西都是非常严格定义的,但由于某种原因,似乎这里没有标准。奇。似乎META-INF已经成为任何所需配置的一个繁琐的地方,这些配置无法通过其他方式轻松处理。

4
Steve Cohen

如果您正在使用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

3
f0ster

Maven中的META-INF

在Maven中, META-INF 文件夹可以理解,因为 标准目录布局 通过名称约定将您的项目资源打包到JAR中:放置在$ {basedir}中的任何目录或文件/ src/main/resources目录被打包到JAR中,具有从JAR基础开始的完全相同的结构。文件夹$ {basedir}/src/main/resources/META-INF通常包含。property文件,而jar中包含生成的 MANIFEST.MF pom.properties pom.xml ,以及其他文件。还有像 Spring这样的框架 使用classpath:/META-INF/resources/来提供web资源。有关更多信息,请参阅 如何向Maven项目添加资源

3
EliuX

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

转到 Tomcat Doc 并选中“ 标准实现> copyXML ”属性。

描述如下。

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

1
Tugrul

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

示例:

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

Source:首先是Jsp和Servlet

0
Prateek Joshi