关于java:META-INF的目的是什么?

关于java:META-INF的目的是什么?

What's the purpose of META-INF?

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


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

The META-INF directory

The following files/directories in the META-INF directory are recognized and interpreted by the Java 2 Platform to configure applications, extensions, class loaders and services:

  • MANIFEST.MF

The manifest file that is used to define extension and package related data.

  • INDEX.LIST

This file is generated by the new"-i" option of the jar tool, which contains location information for packages defined in an application or extension. It is part of the JarIndex implementation and used by class loaders to speed up their class loading process.

  • x.SF

The signature file for the JAR file. 'x' stands for the base file name.

  • x.DSA

The signature block file associated with the signature file with the same base file name. This file stores the digital signature of the corresponding signature file.

  • services/

This directory stores all the service provider configuration files.


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

1
2
3
4
5
<jar ...>
    <manifest>
       
    </manifest>
</jar>

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

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


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

1
2
<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中到底有什么问题。但这似乎是一个新兴的事实上的标准。要么,要么新兴的反模式:-)


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


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

例如:

1
META-INF/resources/button.jpg

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

1
http://localhost/myapp/button.webp

>阅读更多

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

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

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

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

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

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

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


    Maven中的META-INF

    在Maven中,由于标准目录布局而使META-INF文件夹被理解,按照标准约定,该布局将您的项目资源打包在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/来提供Web资源。有关更多信息,请参见如何向Maven项目添加资源。


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

    为什么会这样呢?

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

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

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


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


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

    1
    2
    3
    4
    5
    6
    7
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;

    // ...

    EntityManagerFactory emf =
          Persistence.createEntityManagerFactory(persistenceUnitName);

    在这里查看更多:
    http://www.datanucleus.org/products/datanucleus/jpa/emf.html


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


    Tomcat文档并检查
    "标准实施> copyXML"属性。

    说明如下。

    Set to true if you want a context XML descriptor embedded inside the application (located at /META-INF/context.xml) to be copied to the owning Host's xmlBase when the application is deployed. On subsequent starts, the copied context XML descriptor will be used in preference to any context XML descriptor embedded inside the application even if the descriptor embedded inside the application is more recent. The flag's value defaults to false. Note if the deployXML attribute of the owning Host is false or if the copyXML attribute of the owning Host is true, this attribute will have no effect.


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

    例:

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

    Source: Head First Jsp和Servlet


    推荐阅读