在Java中,您经常会看到包含一些元文件的META-INF文件夹。这个文件夹的目的是什么,我可以放在那里?
答案 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
/META-INF/MANIFEST.MF有一个特殊含义:
java -jar myjar.jar org.myserver.MyMainClass
运行jar,则可以将主类定义移动到jar中,以便将调用缩小为java -jar myjar.jar
。java.lang.Package.getPackage("org.myserver").getImplementationTitle()
,则可以为包定义元信息。答案 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 文件夹是因为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