在Java中,您经常会看到包含一些元文件的meta - inf文件夹。这个文件夹的目的是什么?我可以在那里放什么?
从官方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/ 此目录存储所有服务提供者配置文件。
以下文件/目录在META-INF目录下被Java 2平台识别和解释,以配置应用程序、扩展、类加载器和服务:
MANIFEST.MF
用于定义扩展和包相关数据的清单文件。
INDEX.LIST
此文件由新的"-i"jar工具的选项,它包含应用程序或扩展中定义的包的位置信息。它是JarIndex实现的一部分,类装入器使用它来加速类装入过程。
-i
x.SF
JAR文件的签名文件。'x'代表基本文件名。
x.DSA
与具有相同基文件名的签名文件关联的签名块文件。该文件存储对应签名文件的数字签名。
services/
此目录存储所有服务提供者配置文件。
自Java 9实现中238以来新增了多版本jar。会看到一个子文件夹versions。这个特性允许将不同Java版本的类打包到一个jar中。
versions
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。
persistence.xml
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似乎已经成为了一个无所不包的地方,任何所需的配置都无法通过其他方式轻松处理。
你也可以在那里放置静态资源。
在示例:
META-INF/resources/button.jpg
并通过web3.0容器获取它们
http://localhost/myapp/button.jpg
>阅读更多< / >
/ meta - inf / MANIFEST。MF有特殊的含义:
java -jar myjar.jar org.myserver.MyMainClass
java -jar myjar.jar
java.lang.Package.getPackage("org.myserver").getImplementationTitle()
在Maven中,meta - inf文件夹是可以理解的,因为标准目录布局根据名称约定将项目资源打包到JAR中:任何放置在$ {basedir} / src / main /资源目录中的目录或文件都被打包到JAR中,从JAR的底部开始具有完全相同的结构。
文件夹$ {basedir} / src / main / resources / meta - inf通常包含. properties文件,而在jar中包含生成的清单。曼氏金融、pom.properties、pom.xml等文件。同样,像春天这样的框架使用classpath:/META-INF/resources/来提供web资源。
classpath:/META-INF/resources/
更多信息见如何向Maven项目添加资源。
所有答案都是正确的。Meta-inf有很多用途。此外,这里还有一个关于使用tomcat容器的示例。
描述如下。
如果希望在部署应用程序时将嵌入在应用程序(位于/META-INF/context. XML)中的上下文XML描述符复制到所属主机的xmlBase,则将该值设置为true。在随后的启动中,复制的上下文XML描述符将优先于应用程序中嵌入的任何上下文XML描述符,即使应用程序中嵌入的描述符是最近的。该标志的默认值为false。注意,如果所属主机的deployXML属性为假,或者所属主机的copyXML属性为真,则该属性将不起作用。
你有舱单。MF文件在你的META-INF文件夹。你可以定义可选或外部依赖项,你必须访问。
例子:
假设你已经部署了你的应用程序,你的容器(在运行时)发现你的应用程序需要一个不在lib文件夹内的库的新版本,在这种情况下,如果你在MANIFEST.MF中定义了可选的新版本,那么你的应用程序将从那里引用依赖(并且不会崩溃)。
Source:头第一Jsp &Servlet
Source:
ClassLoader
把它想象成另一个根。从Enumerator<URL> ClassLoader#getSystemResources(String path)方法等的角度来看:
Enumerator<URL> ClassLoader#getSystemResources(String path)
当给定的路径以“META-INF”开头时,该方法搜索类路径中所有jar的META-INF文件夹内嵌套的资源。
当给定的路径不是以“META-INF”开头时,该方法在类路径中所有jar和目录的所有其他文件夹(在META-INF之外)中搜索资源。
如果你知道getSystemResources方法特别处理的另一个文件夹名称,请评论它。
getSystemResources
作为补充,META-INF文件夹现在也用于multi-release罐子。这是一个允许将针对不同Java版本的类打包到一个jar中的特性,例如包含一个针对Java 11的类,其中包含Java 11提供的新特性,在一个jar中也适用于Java 8,其中针对Java 8的不同类中包含较少的特性。例如,如果一个较新的Java版本提供了增强的、不同的或新的API方法,而这些方法在较早的版本中由于违反API而无法工作,那么这可能是有用的。然后会看到子文件夹versions。