Jaki jest cel META-INF?

Odpowiedzi:

65

Ogólnie rzecz biorąc, sam nie powinieneś wkładać niczego do META-INF. Zamiast tego powinieneś polegać na tym, czego używasz do pakowania swojego JAR. Jest to jeden z obszarów, w którym moim zdaniem Ant naprawdę przoduje: określenie atrybutów manifestu pliku JAR. Bardzo łatwo jest powiedzieć coś takiego:

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

Przynajmniej myślę, że to łatwe ... :-)

Chodzi o to, że META-INF należy uznać za wewnętrzny katalog meta Java . Nie zadzieraj z tym! Wszelkie pliki, które chcesz dołączyć do pliku JAR, należy umieścić w innym podkatalogu lub w katalogu głównym samego pliku JAR.

Daniel Spiewak
źródło
17
Co z usługami? Deskryptory biblioteki tagów? Umieszczenie czegoś w katalogu głównym JAR to zły pomysł. W przypadku braku jasnej konwencji zasoby w katalogu głównym zbyt często się kolidują.
erickson
13
Jeśli używasz JPA, musisz umieścić plik persistence.xml w tym folderze, co nie dzieje się automatycznie.
JRSofty
4
To byłaby dobra odpowiedź, z wyjątkiem tego, że w prostej aplikacji Spring MVC META-INF jest jedynym katalogiem, w którym pliki konfiguracyjne mogą być przywoływane zarówno przez testy jednostkowe, jak i kontrolery. Jeśli działałby inny katalog, byłoby świetnie - nie działa (przynajmniej nie wprost). Dla mnie budowanie pliku Jar tylko w celu przetestowania pliku wojennego jest jak budowanie samochodu, abyś mógł iść do kuchni. Przynajmniej dla mnie. Ale spędziłem trochę czasu, robiąc Ruby, a one mogły mnie zrujnować, jeśli chodzi o pliki konfiguracyjne (choć wymienię trochę piekła XML za wiedzę o typach moich parametrów). :)
John Lockwood
Czy możesz podać nam przykład typów plików, które powinien zawierać ten folder?
Menai Ala Eddine - Aladdin
3
To nie odpowiada, czym jest META-INF. Gdybym miał na to odpowiedź, może mógłbym ocenić, czy umieszczenie czegoś w tym folderze nie powinno być „nigdy” zrobione.
Kröw
164

Z oficjalnej specyfikacji pliku JAR (link prowadzi do wersji Java 7, ale tekst nie zmienił się od co najmniej wersji 1.3):

Katalog META-INF

Następujące pliki / katalogi w katalogu META-INF są rozpoznawane i interpretowane przez platformę Java 2 w celu konfiguracji aplikacji, rozszerzeń, programów ładujących klasy i usług:

  • MANIFEST.MF

Plik manifestu służący do definiowania danych związanych z rozszerzeniem i pakietem.

  • INDEX.LIST

Ten plik jest generowany przez nową -iopcję narzędzia „jar”, ​​która zawiera informacje o lokalizacji dla pakietów zdefiniowanych w aplikacji lub rozszerzeniu. Jest on częścią implementacji JarIndex i wykorzystywany przez moduły ładujące klasy w celu przyspieszenia procesu ładowania klasy.

  • x.SF

Plik podpisu dla pliku JAR. „x” oznacza podstawową nazwę pliku.

  • x.DSA

Plik bloku podpisu skojarzony z plikiem podpisu o tej samej nazwie pliku podstawowego. Ten plik przechowuje podpis cyfrowy odpowiedniego pliku podpisu.

  • services/

W tym katalogu są przechowywane wszystkie pliki konfiguracyjne usługodawcy.

aku
źródło
3
TLD muszą również podlegać META-INF.
erickson
@erickson, Opracowanie?
Pacerier
Deskryptory bibliotek znaczników @Pacerier dla bibliotek znaczników JSP muszą znajdować się w katalogu META-INF. Zapomniałem, co oznaczało TLD w 2008 roku.
erickson
27

Zauważyłem, że niektóre biblioteki Java zaczęły używać META-INF jako katalogu, w którym powinny znajdować się pliki konfiguracyjne, które powinny być spakowane i zawarte w CLASSPATH wraz z plikami JAR. Na przykład Spring umożliwia importowanie plików XML znajdujących się w ścieżce klasy za pomocą:

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

W tym przykładzie cytuję bezpośrednio z podręcznika użytkownika Apache CXF . Przy projekcie, nad którym pracowałem, w którym musieliśmy pozwolić na wiele poziomów konfiguracji przez Spring, zastosowaliśmy się do tej konwencji i umieściliśmy nasze pliki konfiguracyjne w META-INF.

Kiedy zastanawiam się nad tą decyzją, nie wiem, co dokładnie byłoby nie tak po prostu dołączając pliki konfiguracyjne do konkretnego pakietu Java, a nie do META-INF. Ale wydaje się, że jest to wyłaniający się de facto standard; albo to, albo pojawiający się anty-wzór :-)

użytkownik38748
źródło
4
Konfiguracja nie należy do biblioteki. Myślę, że przybiłeś go „pojawiającym się anty-wzorem”. Naprawdę łatwo jest zlokalizować pliki konfiguracyjne względem biblioteki; nie muszą fizycznie wchodzić do tego samego pliku JAR, aby zostać znalezionym.
erickson
24
Nie zgadzam się ze stwierdzeniem, że konfiguracja nie należy do biblioteki. Myślę, że konfiguracja, szczególnie jeśli chodzi o ustawienia domyślne, jest dobrze zapakowana w bibliotece. Cieszę się, że więcej frameworków zdecydowało się na taką pracę, w przeciwieństwie do zmuszania was do dołączania wszelkiego rodzaju zewnętrznych plików konfiguracyjnych, jak to było niedawno.
Eelco,
1
Wiele plików typu LICENSE.TXT pojawia się również w META_INF, co mnie denerwuje.
Ti Strga,
@Eelco, Kod i dane nie powinny się mieszać. Dołączenie zewnętrznych plików konfiguracyjnych nie musi oznaczać bałaganu użyteczności. To zależy od jego struktury.
Pacerier
1
To dość arbitralne stwierdzenie @Pacerier. Ogólnie rzecz biorąc, jest to w dużej mierze preferencja.
Eelco,
13

Folder META-INF to strona główna pliku MANIFEST.MF . Ten plik zawiera metadane dotyczące zawartości pliku JAR. Na przykład istnieje wpis o nazwie Main-Class, który określa nazwę klasy Java za pomocą statycznego main () dla plików wykonywalnych JAR.

Brian Matthews
źródło
10

Możesz tam również umieścić zasoby statyczne.

W przykładzie:

META-INF/resources/button.jpg 

i zdobądź je w kontenerze web3.0 przez

http://localhost/myapp/button.jpg

> Czytaj więcej

/META-INF/MANIFEST.MF ma specjalne znaczenie:

  1. Jeśli uruchomisz słoik za pomocą java -jar myjar.jar org.myserver.MyMainClass, możesz przenieść definicję głównej klasy do słoika, abyś mógł zmniejszyć wywołanie java -jar myjar.jar.
  2. Jeśli chcesz, możesz zdefiniować Metainformacje do paczek java.lang.Package.getPackage("org.myserver").getImplementationTitle().
  3. Możesz odwoływać się do certyfikatów cyfrowych, których chcesz używać w trybie Applet / Webstart.
Ponury
źródło
Dlatego wszelkie elementy statyczne w aplikacji powinny być umieszczone w tym katalogu, takie jak obrazy lub inne elementy.
Menai Ala Eddine - Aladdin
6

META-INF w Maven

W Maven folder META-INF jest rozumiany ze względu na Standardowy układ katalogów , który zgodnie z konwencją nazw pakuje zasoby projektu do plików JAR: wszelkie katalogi lub pliki umieszczone w katalogu $ {basedir} / src / main / resources są spakowane do Twojego pliku JAR z dokładnie taką samą strukturą, zaczynając od podstawy JAR. Folder $ {basedir} / src / main / resources / META-INF zwykle zawiera pliki .properties , podczas gdy w słoiku zawiera między innymi wygenerowany plik MANIFEST.MF , pom.properties , pom.xml . Również ramy, jak wiosną używać classpath:/META-INF/resources/do obsługi zasobów internetowych. Aby uzyskać więcej informacji zobaczJak dodać zasoby do mojego projektu Maven .

EliuX
źródło
5

Aby dodać tutaj informacje, w przypadku pliku WAR plik META-INF / MANIFEST.MF zapewnia programistom możliwość zainicjowania kontroli czasu wdrożenia przez kontener, co zapewnia, że ​​kontener może znaleźć wszystkie klasy aplikacji. zależy od. Zapewnia to, że w przypadku pominięcia pliku JAR nie trzeba czekać, aż aplikacja przestanie działać w środowisku wykonawczym, aby zdać sobie sprawę z jego braku.

sasuke
źródło
5

Ostatnio zastanawiałem się nad tym problemem. Wydaje się, że naprawdę nie ma żadnych ograniczeń w korzystaniu z META-INF. Oczywiście istnieją pewne ograniczenia dotyczące konieczności umieszczania manifestu, ale wydaje się, że nie ma żadnych zakazów umieszczania tam innych rzeczy.

Dlaczego tak jest?

Sprawa cxf może być uzasadniona. Oto inne miejsce, w którym ten niestandardowy jest zalecany, aby obejść paskudny błąd w JBoss-ws, który zapobiega walidacji po stronie serwera względem schematu wsdl.

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

Ale tak naprawdę wydaje się, że nie ma żadnych standardów, żadnych „ty”. Zwykle te rzeczy są bardzo ściśle określone, ale z jakiegoś powodu wydaje się, że nie ma tu żadnych standardów. Dziwny. Wygląda na to, że META-INF stało się głównym miejscem dla każdej potrzebnej konfiguracji, której nie da się łatwo obsłużyć w inny sposób.

Steve Cohen
źródło
5

Dodając do informacji tutaj, META-INF jest specjalnym folderem, który ClassLoadertraktuje inaczej niż inne foldery w słoiku. Elementy zagnieżdżone w folderze META-INF nie są mieszane z elementami poza nim.

Pomyśl o tym jak o innym katalogu głównym. Z perspektywy Enumerator<URL> ClassLoader#getSystemResources(String path)metody i wsp .:

Gdy podana ścieżka zaczyna się od „META-INF”, metoda wyszukuje zasoby zagnieżdżone w folderach META-INF wszystkich słoików na ścieżce klasy.

Gdy podana ścieżka nie zaczyna się od „META-INF”, metoda szuka zasobów we wszystkich innych folderach (poza META-INF) wszystkich słoików i katalogów w ścieżce klasy.

Jeśli wiesz o nazwie innego folderu, którą ta getSystemResourcesmetoda traktuje specjalnie, skomentuj ją.

Readren
źródło
3

Jeśli używasz JPA1, być może będziesz musiał upuścić tam persistence.xmlplik, który określa nazwę jednostki trwałości, której możesz chcieć użyć. Jednostka trwałości zapewnia wygodny sposób określania zestawu plików metadanych oraz klas i słoików zawierających wszystkie klasy, które mają zostać utrwalone w grupie.

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

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

Zobacz więcej tutaj: http://www.datanucleus.org/products/datanucleus/jpa/emf.html

f0ster
źródło
1

Wszystkie odpowiedzi są poprawne. Meta-inf ma wiele celów. Ponadto znajduje się przykład użycia kontenera tomcat.

Przejdź do Tomcat Doc i zaznacz atrybut „ Standardowa implementacja> copyXML ”.

Opis znajduje się poniżej.

Ustaw na true, jeśli chcesz, aby deskryptor XML osadzony w aplikacji (znajdujący się w /META-INF/context.xml) był kopiowany do xmlBase właściciela, gdy aplikacja jest wdrażana. Podczas kolejnych uruchomień skopiowany kontekstowy deskryptor XML będzie używany zamiast dowolnego kontekstowego deskryptora XML osadzonego w aplikacji, nawet jeśli deskryptor osadzony w aplikacji jest nowszy. Domyślna wartość flagi to false. Uwaga: jeśli atrybut deployXML hosta będącego właścicielem ma wartość false lub jeśli atrybut copyXML hosta będącego właścicielem ma wartość true, ten atrybut nie będzie miał wpływu.

Tugrul
źródło
0

Masz plik MANIFEST.MF w folderze META-INF. Możesz zdefiniować opcjonalne lub zewnętrzne zależności , do których musisz mieć dostęp.

Przykład:

Rozważ, że wdrożyłeś aplikację, a Twój kontener (w czasie wykonywania) dowiedział się, że aplikacja wymaga nowszej wersji biblioteki, która nie znajduje się w folderze lib. W takim przypadku, jeśli zdefiniowano opcjonalną nowszą wersję, MANIFEST.MFaplikacja będzie się odnosić na zależność stamtąd (i nie spowoduje awarii).

Source: Head First Jsp & Servlet

Prateek Joshi
źródło
1
Nie jest jasne, ile z tego jest cytowane ze źródła, i nie wygląda to dosłownie. Usunięto dziwne formatowanie. Nie używaj formatowania kodu dla tekstu, który nie jest kodem. Używaj formatowania cytatów dla cytowanego tekstu.
Markiz Lorne