it-swarm-vi.tech

Mục đích của META-INF là gì?

Trong Java, bạn thường thấy một thư mục META-INF chứa một số tệp meta. Mục đích của thư mục này là gì và tôi có thể đặt gì ở đó?

267
Kristian

Nói chung, bạn không nên tự mình đặt bất cứ thứ gì vào META-INF. Thay vào đó, bạn nên dựa vào bất cứ thứ gì bạn sử dụng để đóng gói JAR của bạn. Đây là một trong những lĩnh vực mà tôi nghĩ Ant thực sự vượt trội: chỉ định các thuộc tính tệp kê khai tệp JAR. Rất dễ để nói điều gì đó như:

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

Ít nhất, tôi nghĩ điều đó thật dễ dàng ... :-)

Vấn đề là META-INF nên được coi là một thư mục Java meta nội bộ. Đừng lộn xộn với nó! Bất kỳ tệp nào bạn muốn đưa vào JAR của bạn nên được đặt trong một số thư mục con khác hoặc tại thư mục gốc của chính JAR.

61
Daniel Spiewak

Từ Đặc tả tệp JAR chính thức (liên kết đến phiên bản Java 7, nhưng văn bản đã không thay đổi kể từ ít nhất v1.3):

Thư mục META-INF

Các tệp/thư mục sau trong thư mục META-INF được Nền tảng Java 2 nhận ra và diễn giải để định cấu hình các ứng dụng, tiện ích mở rộng, trình tải lớp và dịch vụ:

  • MANIFEST.MF

Tệp kê khai được sử dụng để xác định dữ liệu liên quan đến phần mở rộng và gói.

  • INDEX.LIST

Tệp này được tạo bởi tùy chọn "-i" mới của công cụ jar, chứa thông tin vị trí cho các gói được xác định trong ứng dụng hoặc tiện ích mở rộng. Nó là một phần của việc triển khai Jar Index và được các trình tải lớp sử dụng để tăng tốc quá trình tải lớp của họ.

  • x.SF

Tệp chữ ký cho tệp JAR. 'x' là viết tắt của tên tệp cơ sở.

  • x.DSA

Tệp khối chữ ký được liên kết với tệp chữ ký có cùng tên tệp cơ sở. Tập tin này lưu trữ chữ ký số của tập tin chữ ký tương ứng.

  • services/

Thư mục này lưu trữ tất cả các tập tin cấu hình nhà cung cấp dịch vụ.

157
aku

Tôi đã nhận thấy rằng một số thư viện Java đã bắt đầu sử dụng META-INF như một thư mục để bao gồm các tệp cấu hình nên được đóng gói và đưa vào CLASSPATH cùng với JAR. Ví dụ: Spring cho phép bạn nhập các tệp XML trên đường dẫn lớp bằng cách sử dụng:

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

Trong ví dụ này, tôi trích dẫn thẳng ra Hướng dẫn sử dụng Apache CXF . Trong một dự án mà tôi đã làm việc trong đó chúng tôi phải cho phép nhiều cấp cấu hình thông qua Spring, chúng tôi đã tuân theo quy ước này và đưa các tệp cấu hình của chúng tôi vào META-INF.

Khi tôi suy nghĩ về quyết định này, tôi không biết chính xác điều gì sẽ sai khi chỉ bao gồm các tệp cấu hình trong một gói Java cụ thể, thay vì trong META-INF. Nhưng nó dường như là một tiêu chuẩn thực tế mới nổi; hoặc đó, hoặc một mô hình chống mới nổi :-)

25
user38748

Thư mục META-INF là ngôi nhà cho tệp MANIFEST.MF . Tệp này chứa dữ liệu meta về nội dung của JAR. Ví dụ, có một mục được gọi là Main-Class chỉ định tên của lớp Java với hàm main () cho các tệp JAR thực thi.

10
Brian Matthews

Bạn cũng có thể đặt tài nguyên tĩnh trong đó.

Trong ví dụ:

META-INF/resources/button.jpg 

và lấy chúng trong web3.0-container thông qua

http://localhost/myapp/button.jpg

> Đọc thêm

/META-INF/MANIFEST.MF có một ý nghĩa đặc biệt:

  1. Nếu bạn chạy một jar bằng cách sử dụng Java -jar myjar.jar org.myserver.MyMainClass, bạn có thể di chuyển định nghĩa lớp chính vào trong jar để bạn có thể thu nhỏ cuộc gọi vào Java -jar myjar.jar.
  2. Bạn có thể xác định Siêu dữ liệu cho các gói nếu bạn sử dụng Java.lang.Package.getPackage("org.myserver").getImplementationTitle().
  3. Bạn có thể tham khảo các chứng chỉ kỹ thuật số bạn muốn sử dụng trong chế độ Applet/Webstart.
8
Peter Rader

Chỉ cần thêm vào thông tin ở đây, trong trường hợp tệp WAR, tệp META-INF/MANIFEST.MF cung cấp cho nhà phát triển một cơ sở để bắt đầu kiểm tra thời gian triển khai bởi container để đảm bảo rằng container có thể tìm thấy tất cả các lớp ứng dụng của bạn phụ thuộc. Điều này đảm bảo rằng trong trường hợp bạn bỏ lỡ một JAR, bạn không phải đợi cho đến khi ứng dụng của bạn hoạt động trong thời gian chạy để nhận ra rằng nó bị thiếu.

4
sasuke

Thêm vào thông tin ở đây, META-INF là một thư mục đặc biệt mà ClassLoader xử lý khác với các thư mục khác trong tệp. Các phần tử được lồng trong thư mục META-INF không được trộn lẫn với các phần tử bên ngoài nó.

Hãy nghĩ về nó như một gốc khác. Từ phương pháp Enumerator<URL> ClassLoader#getSystemResources(String path) et al phối cảnh:

Khi đường dẫn đã cho bắt đầu bằng "META-INF", phương thức tìm kiếm các tài nguyên được lồng trong các thư mục META-INF của tất cả các tệp trong đường dẫn lớp.

Khi đường dẫn đã cho không bắt đầu bằng "META-INF", phương thức sẽ tìm kiếm tài nguyên trong tất cả các thư mục khác (bên ngoài META-INF) của tất cả các tệp và thư mục trong đường dẫn lớp.

Nếu bạn biết về một tên thư mục khác mà phương thức getSystemResources xử lý đặc biệt, vui lòng nhận xét về nó.

4
Readren

Tôi đã suy nghĩ về vấn đề này gần đây. Thực sự không có bất kỳ hạn chế nào đối với việc sử dụng META-INF. Tất nhiên, có một số hạn chế nhất định về sự cần thiết phải đặt bảng kê khai ở đó, nhưng dường như không có bất kỳ sự cấm đoán nào về việc đưa những thứ khác vào đó.

Tại sao điều này là trường hợp?

Trường hợp cxf có thể là hợp pháp. Đây là một nơi khác, nơi phi tiêu chuẩn này được khuyến nghị để khắc phục một lỗi khó chịu trong JBoss-ws ngăn chặn xác thực phía máy chủ đối với lược đồ của wsdl.

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

Nhưng thực sự không có bất kỳ tiêu chuẩn, bất kỳ tiêu chuẩn nào. Thông thường những điều này được xác định rất nghiêm ngặt, nhưng vì một số lý do, dường như không có tiêu chuẩn nào ở đây. Kì lạ Có vẻ như META-INF đã trở thành một nơi hấp dẫn cho mọi cấu hình cần thiết mà không thể dễ dàng xử lý theo một cách khác.

4
Steve Cohen

Nếu bạn đang sử dụng JPA1, bạn có thể phải thả tệp persistence.xml vào đó chỉ định tên của đơn vị lưu trữ lâu bền mà bạn có thể muốn sử dụng. Một đơn vị kiên trì cung cấp một cách thuận tiện để chỉ định một tập hợp các tệp siêu dữ liệu và các lớp và các tệp có chứa tất cả các lớp được duy trì trong một nhóm.

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

// ...

EntityManagerFactory emf =
      Persistence.createEntityManagerFactory(persistenceUnitName);

Xem thêm tại đây: http://www.datanucleus.org/products/datanucleus/jpa/emf.html

3
f0ster

META-INF trong Maven

Trong Maven, thư mục META-INF được hiểu vì Bố cục thư mục chuẩn mà theo quy ước tên gói tài nguyên dự án của bạn trong JAR : mọi thư mục hoặc tệp được đặt trong thư mục $ {Dựair}/src/main/resource được đóng gói vào JAR của bạn với cùng cấu trúc bắt đầu từ cơ sở của JAR. Thư mục $ {Dựair}/src/main/resource/META-INF thường chứa các tệp . Thuộc tính trong khi trong tệp chứa a được tạo MANIFEST.MF , pom.properies , pom.xml , trong số các tệp khác. Ngoài ra các khung như Spring sử dụng classpath:/META-INF/resources/ để phục vụ tài nguyên web. Để biết thêm thông tin, hãy xem Làm cách nào để thêm tài nguyên vào Dự án Maven của tôi

3
EliuX

Tất cả các câu trả lời đều đúng. Meta-inf có nhiều mục đích. Ngoài ra, đây là một ví dụ về việc sử dụng container Tomcat.

Chuyển đến Tomcat Doc và kiểm tra thuộc tính " Thực hiện chuẩn> copyXML ".

Mô tả dưới đây.

Đặt thành true nếu bạn muốn một bộ mô tả XML ngữ cảnh được nhúng bên trong ứng dụng (có tại /META-INF/context.xml) để được sao chép sang xmlBase của chủ sở hữu khi ứng dụng được triển khai. Trong các lần khởi động tiếp theo, bộ mô tả XML bối cảnh được sao chép sẽ được sử dụng theo sở thích đối với bất kỳ bộ mô tả XML ngữ cảnh nào được nhúng bên trong ứng dụng ngay cả khi bộ mô tả được nhúng bên trong ứng dụng gần đây hơn. Giá trị của cờ mặc định là sai. Lưu ý nếu thuộc tính triển khai MLX của Máy chủ sở hữu là sai hoặc nếu thuộc tính copyXML của Máy chủ sở hữu là đúng, thuộc tính này sẽ không có hiệu lực.

1
Tugrul

Bạn có tệp MANIFEST.MF trong thư mục META-INF. Bạn có thể xác định các phụ thuộc tùy chọn hoặc bên ngoài mà bạn phải có quyền truy cập.

Ví dụ :

Hãy xem xét bạn đã triển khai ứng dụng và thùng chứa của bạn (trong thời gian chạy) phát hiện ra rằng ứng dụng của bạn yêu cầu phiên bản mới hơn của thư viện không nằm trong thư mục lib, trong trường hợp đó nếu bạn đã xác định phiên bản mới hơn tùy chọn trong MANIFEST.MF thì ứng dụng của bạn sẽ đề cập đến sự phụ thuộc từ đó (và sẽ không sụp đổ).

Source: Jsp & Servlet đầu tiên

0
Prateek Joshi