META-INF的目的是什么?

时间:2008-09-16 07:55:21

标签: java meta-inf

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

12 个答案:

答案 0 :(得分:156)

来自the official JAR File Specification(链接转到Java 7版本,但文本至少从v1.3开始没有更改):

  

META-INF目录

     

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

     
      
  • MANIFEST.MF
  •   
     

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

     
      
  • INDEX.LIST
  •   
     

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

     
      
  • x.SF
  •   
     

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

     
      
  • x.DSA
  •   
     

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

     
      
  • services/
  •   
     

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

答案 1 :(得分:61)

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

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

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

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

答案 2 :(得分:24)

我注意到一些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 User Guide。在我工作的项目中,我们必须通过Spring允许多级配置,我们遵循这个约定并将我们的配置文件放在META-INF中。

当我反思这个决定时,我不知道将配置文件包含在特定Java包中而不是META-INF中究竟会出现什么问题。但它似乎是一个新兴的事实上的标准;或者是新兴的反模式: - )

答案 3 :(得分:10)

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

答案 4 :(得分:8)

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

例如:

META-INF/resources/button.jpg 

通过

将它们放入web3.0容器中
http://localhost/myapp/button.jpg

> Read more

/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(),则可以为包定义元信息。
  3. 您可以参考您希望在Applet / Webstart模式下使用的数字证书。

答案 5 :(得分:4)

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

答案 6 :(得分:4)

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

为什么会这样?

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

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

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

答案 7 :(得分:4)

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

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

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

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

如果您了解getSystemResources方法专门处理的其他文件夹名称,请对其进行评论。

答案 8 :(得分: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

答案 9 :(得分:3)

Maven中的META-INF

在Maven中,理解 META-INF 文件夹是因为Standard Directory Layout按名称约定将您的项目资源打包在JAR中:放置在 $ {中的任何目录或文件basedir} / src / main / resources 目录被打包到JAR中,其结构与JAR基础相同。文件夹 $ {basedir} / src / main / resources / META-INF 通常包含 .properties 文件,而jar中包含生成的 MANIFEST.MF pom.properties pom.xml 以及其他文件。此外,Spring等框架使用classpath:/META-INF/resources/来提供网络资源。有关详细信息,请参阅How do i add resources to my Maven Project

答案 10 :(得分:1)

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

转到 Tomcat Doc并检查 &#34; 标准实施&gt; copyXML &#34;属性。

说明如下。

  

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

答案 11 :(得分:0)

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

示例:

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

MANIFEST.MF Head First Jsp&amp;的Servlet