Was ist der Zweck von META-INF?

Antworten:

65

Im Allgemeinen sollten Sie selbst nichts in META-INF einfügen. Stattdessen sollten Sie sich auf alles verlassen, was Sie zum Packen Ihrer JAR verwenden. Dies ist einer der Bereiche, in denen Ant meiner Meinung nach wirklich herausragend ist: Angeben von JAR-Dateimanifestattributen. Es ist sehr einfach, etwas zu sagen wie:

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

Zumindest finde ich das einfach ... :-)

Der Punkt ist, dass META-INF als internes Java- Meta- Verzeichnis betrachtet werden sollte. Leg dich nicht damit an! Alle Dateien, die Sie in Ihre JAR aufnehmen möchten, sollten in einem anderen Unterverzeichnis oder im Stammverzeichnis der JAR selbst abgelegt werden.

Daniel Spiewak
quelle
17
Was ist mit Dienstleistungen? Tag-Bibliotheksdeskriptoren? Es ist eine schlechte Idee, etwas in die Wurzel eines JAR zu stecken. In Ermangelung einer klaren Konvention ist es zu wahrscheinlich, dass Ressourcen in der Wurzel kollidieren.
Erickson
13
Wenn Sie JPA verwenden, müssen Sie eine persistence.xml in diesen Ordner einfügen. Dies geschieht nicht automatisch.
JRSofty
4
Dies wäre eine gute Antwort, außer dass META-INF in einer einfachen Spring MVC-App das einzige Verzeichnis ist, in dem Konfigurationsdateien sowohl von den Komponententests als auch von den Controllern referenziert werden können. Wenn ein anderes Verzeichnis funktionieren würde, wäre das großartig - es funktioniert nicht (zumindest nicht einfach). Für mich ist das Erstellen einer Jar-Datei, nur um eine Kriegsdatei zu testen, wie das Erstellen eines Autos, damit Sie in die Küche gehen können. Zumindest für mich. Aber ich habe einige Zeit mit Ruby verbracht, und sie haben mich möglicherweise in Bezug auf Konfigurationsdateien ruiniert (obwohl ich ein wenig XML-Hölle eintauschen werde, um zu wissen, welche Arten meiner Parameter es gibt). :)
John Lockwood
Können Sie uns ein Beispiel geben, welche Dateitypen diesen Ordner enthalten sollen?
Menai Ala Eddine - Aladdin
3
Dies beantwortet nicht, was META-INF ist. Wenn ich eine Antwort darauf hätte, könnte ich vielleicht selbst beurteilen, ob etwas "nie" in diesen Ordner gelegt werden sollte oder nicht.
Kröw
164

Aus der offiziellen JAR-Dateispezifikation (Link führt zur Java 7-Version, aber der Text hat sich seit mindestens Version 1.3 nicht geändert):

Das META-INF-Verzeichnis

Die folgenden Dateien / Verzeichnisse im META-INF-Verzeichnis werden von der Java 2-Plattform erkannt und interpretiert, um Anwendungen, Erweiterungen, Klassenlader und Dienste zu konfigurieren:

  • MANIFEST.MF

Die Manifestdatei, mit der Erweiterungs- und paketbezogene Daten definiert werden.

  • INDEX.LIST

Diese Datei wird durch die neue -iOption " " des JAR-Tools generiert , die Standortinformationen für Pakete enthält, die in einer Anwendung oder Erweiterung definiert sind. Es ist Teil der JarIndex-Implementierung und wird von Klassenladeprogrammen verwendet, um den Ladevorgang von Klassen zu beschleunigen.

  • x.SF

Die Signaturdatei für die JAR-Datei. 'x' steht für den Basisdateinamen.

  • x.DSA

Die Signaturblockdatei, die der Signaturdatei mit demselben Basisdateinamen zugeordnet ist. Diese Datei speichert die digitale Signatur der entsprechenden Signaturdatei.

  • services/

In diesem Verzeichnis werden alle Konfigurationsdateien des Dienstanbieters gespeichert.

aku
quelle
3
TLDs müssen ebenfalls unter META-INF fallen.
Erickson
@erickson, aufwendig?
Pacerier
@ Pacerier-Tag-Bibliotheksdeskriptoren für JSP-Tag-Bibliotheken müssen sich im META-INF-Verzeichnis befinden. Ich hatte 2008 vergessen, wofür TLD stand.
erickson
27

Ich habe festgestellt, dass einige Java-Bibliotheken META-INF als Verzeichnis verwenden, in das Konfigurationsdateien aufgenommen werden sollen, die zusammen mit JARs gepackt und in CLASSPATH enthalten sein sollen. Mit Spring können Sie beispielsweise XML-Dateien importieren, die sich im Klassenpfad befinden, indem Sie:

<import resource="classpath:/META-INF/cxf/cxf.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extensions-*.xml" />

In diesem Beispiel zitiere ich direkt aus dem Apache CXF-Benutzerhandbuch . Bei einem Projekt, an dem ich gearbeitet habe und bei dem wir über Spring mehrere Konfigurationsebenen zulassen mussten, haben wir diese Konvention befolgt und unsere Konfigurationsdateien in META-INF abgelegt.

Wenn ich über diese Entscheidung nachdenke, weiß ich nicht, was genau falsch wäre, wenn ich die Konfigurationsdateien einfach in ein bestimmtes Java-Paket und nicht in META-INF einbinden würde. Aber es scheint ein aufkommender De-facto-Standard zu sein; entweder das oder ein aufkommendes Anti-Muster :-)

user38748
quelle
4
Die Konfiguration gehört nicht in eine Bibliothek. Ich denke, Sie haben es mit "Emerging Anti-Pattern" genagelt. Es ist wirklich ziemlich einfach, Konfigurationsdateien relativ zu einer Bibliothek zu finden. Sie müssen nicht physisch in dasselbe Glas gehen, um gefunden zu werden.
Erickson
24
Ich stimme der Aussage nicht zu, dass die Konfiguration nicht in eine Bibliothek gehört. Ich denke, dass die Konfiguration, insbesondere wenn es um Standardeinstellungen geht, in einer Bibliothek gut verpackt ist. Ich bin eigentlich froh, dass sich mehr Frameworks dafür entschieden haben, so zu arbeiten, anstatt Sie zu zwingen, alle Arten von externen Konfigurationsdateien einzuschließen, wie es vor nicht allzu langer Zeit üblich war.
Eelco
1
Ich habe viele Dateien vom Typ LICENSE.TXT in META_INF gesehen, was ich ärgerlich finde.
Ti Strga
@Eelco, Code und Daten sollten sich nicht mischen. Das Einfügen externer Konfigurationsdateien bedeutet nicht unbedingt ein Usability-Chaos. Es kommt darauf an, wie es aufgebaut ist.
Pacerier
1
Das ist eine ziemlich willkürliche Sache, um @Pacerier zu sagen. Generell ist es weitgehend bevorzugt.
Eelco
13

Der Ordner META-INF ist die Heimat der Datei MANIFEST.MF . Diese Datei enthält Metadaten zum Inhalt der JAR. Beispielsweise gibt es einen Eintrag namens Main-Class, der den Namen der Java-Klasse mit der statischen main () für ausführbare JAR-Dateien angibt.

Brian Matthews
quelle
10

Sie können dort auch statische Ressourcen platzieren.

Zum Beispiel:

META-INF/resources/button.jpg 

und bekomme sie in web3.0-container über

http://localhost/myapp/button.jpg

> Lesen Sie mehr

Die /META-INF/MANIFEST.MF hat eine besondere Bedeutung:

  1. Wenn Sie ein JAR mit ausführen, können java -jar myjar.jar org.myserver.MyMainClassSie die Hauptklassendefinition in das JAR verschieben, um den Aufruf zu verkleinern java -jar myjar.jar.
  2. Sie können Metainformationen für Pakete definieren, wenn Sie diese verwenden java.lang.Package.getPackage("org.myserver").getImplementationTitle().
  3. Sie können auf digitale Zertifikate verweisen, die Sie im Applet / Webstart-Modus verwenden möchten.
Grimmig
quelle
Daher sollten statische Elemente in der Anwendung wie Bilder oder andere Elemente in diesem Verzeichnis abgelegt werden.
Menai Ala Eddine - Aladdin
6

META-INF in Maven

In Maven wird der META-INF- Ordner aufgrund des Standardverzeichnislayouts verstanden , das Ihre Projektressourcen nach Namenskonvention in JARs verpackt: Alle Verzeichnisse oder Dateien im Verzeichnis $ {basedir} / src / main / resources werden in Ihre JAR gepackt mit genau der gleichen Struktur beginnend an der Basis des JAR. Der Ordner $ {basedir} / src / main / resources / META-INF enthält normalerweise .properties- Dateien, während der JAR unter anderem eine generierte MANIFEST.MF , pom.properties , die pom.xml enthält . Auch Frameworks wie Frühling verwenden , classpath:/META-INF/resources/um Web - Ressourcen zu dienen. Weitere Informationen finden Sie unterWie füge ich Ressourcen zu meinem Maven Projekt .

EliuX
quelle
5

Um die Informationen hier im Falle einer WAR-Datei zu ergänzen, bietet die Datei META-INF / MANIFEST.MF dem Entwickler die Möglichkeit, eine Überprüfung der Bereitstellungszeit durch den Container zu initiieren, um sicherzustellen, dass der Container alle Klassen Ihrer Anwendung finden kann kommt drauf an. Auf diese Weise wird sichergestellt, dass Sie nicht warten müssen, bis Ihre Anwendung zur Laufzeit ausfällt, falls Sie eine JAR verpasst haben, um festzustellen, dass sie fehlt.

Sasuke
quelle
5

Ich habe kürzlich über dieses Problem nachgedacht. Es scheint wirklich keine Einschränkung für die Verwendung von META-INF zu geben. Es gibt natürlich gewisse Einschränkungen hinsichtlich der Notwendigkeit, das Manifest dort zu platzieren, aber es scheint keine Verbote zu geben, andere Dinge dort zu platzieren.

Warum ist das so?

Der cxf-Fall kann legitim sein. Hier ist ein weiterer Ort, an dem dieser Nicht-Standard empfohlen wird, um einen bösen Fehler in JBoss-ws zu umgehen, der die serverseitige Validierung anhand des Schemas einer wsdl verhindert.

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

Aber es scheint wirklich keine Standards zu geben, keine Du-sollst-nicht. Normalerweise sind diese Dinge sehr streng definiert, aber aus irgendeinem Grund scheint es hier keine Standards zu geben. Seltsam. Es scheint, dass META-INF zu einem Sammelpunkt für jede erforderliche Konfiguration geworden ist, die auf andere Weise nicht einfach zu handhaben ist.

Steve Cohen
quelle
5

Zusätzlich zu den Informationen hier ist das META-INF ein spezieller Ordner, der ClassLoaderanders behandelt wird als andere Ordner im Glas. Im META-INF-Ordner verschachtelte Elemente werden nicht mit den Elementen außerhalb des META-INF-Ordners gemischt.

Stellen Sie es sich wie eine andere Wurzel vor. Aus Enumerator<URL> ClassLoader#getSystemResources(String path)Sicht von Method et al.:

Wenn der angegebene Pfad mit "META-INF" beginnt, sucht die Methode nach Ressourcen, die in den META-INF-Ordnern aller Jars im Klassenpfad verschachtelt sind.

Wenn der angegebene Pfad nicht mit "META-INF" beginnt, sucht die Methode in allen anderen Ordnern (außerhalb von META-INF) aller Jars und Verzeichnisse im Klassenpfad nach Ressourcen.

Wenn Sie einen anderen Ordnernamen kennen, den die getSystemResourcesMethode speziell behandelt, kommentieren Sie ihn bitte.

Readren
quelle
3

Wenn Sie JPA1 verwenden, müssen Sie möglicherweise eine persistence.xmlDatei dort ablegen, die den Namen einer Persistenz-Einheit angibt, die Sie möglicherweise verwenden möchten. Eine Persistenz-Einheit bietet eine bequeme Möglichkeit, eine Reihe von Metadatendateien, Klassen und Jars anzugeben, die alle Klassen enthalten, die in einer Gruppierung beibehalten werden sollen.

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

Weitere Informationen finden Sie hier: http://www.datanucleus.org/products/datanucleus/jpa/emf.html

f0ster
quelle
1

Alle Antworten sind richtig. Meta-inf hat viele Zwecke. Darüber hinaus finden Sie hier ein Beispiel für die Verwendung von Tomcat-Containern.

Gehen Sie zu Tomcat Doc und aktivieren Sie das Attribut " Standardimplementierung> copyXML ".

Beschreibung ist unten.

Auf true setzen, wenn ein in die Anwendung eingebetteter Kontext-XML-Deskriptor (unter /META-INF/context.xml) bei der Bereitstellung der Anwendung in die xmlBase des Hosts kopiert werden soll. Bei nachfolgenden Starts wird der kopierte Kontext-XML-Deskriptor gegenüber jedem in die Anwendung eingebetteten Kontext-XML-Deskriptor bevorzugt verwendet, selbst wenn der in die Anwendung eingebettete Deskriptor aktueller ist. Der Wert des Flags ist standardmäßig false. Hinweis: Wenn das deployXML-Attribut des besitzenden Hosts falsch ist oder wenn das copyXML-Attribut des besitzenden Hosts true ist, hat dieses Attribut keine Auswirkung.

Tugrul
quelle
0

Sie haben die Datei MANIFEST.MF in Ihrem META-INF-Ordner. Sie können optionale oder externe Abhängigkeiten definieren , auf die Sie Zugriff haben müssen.

Beispiel:

Angenommen, Sie haben Ihre App bereitgestellt und Ihr Container (zur Laufzeit) hat festgestellt, dass für Ihre App eine neuere Version einer Bibliothek erforderlich ist, die sich nicht im lib-Ordner befindet. Wenn Sie in diesem Fall die optionale neuere Version in definiert haben, MANIFEST.MFverweist Ihre App darauf zur Abhängigkeit von dort (und wird nicht abstürzen).

Source: Head First Jsp & Servlet

Prateek Joshi
quelle
1
Es ist unklar, wie viel davon aus der Quelle zitiert wird, und es sieht nicht wörtlich aus. Bizarre Formatierung entfernt. Verwenden Sie keine Code-Formatierung für Text, der kein Code ist. Verwenden Sie die Anführungszeichenformatierung für zitierten Text.
Marquis von Lorne