What's the purpose of META-INF?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The META-INF directory is a reserved folder at the root of Java archive files (JAR, WAR, EAR) that holds metadata and configuration files describing how the archive should behave at build time, runtime, and deployment. The JVM and application servers read from this directory automatically, so its contents control everything from which class to execute, to how services are discovered, to whether the archive has been tampered with.
If you have ever wondered why your executable JAR launches the right main class, or how Spring discovers your beans without explicit registration, the answer is almost always a file inside META-INF.
The MANIFEST.MF File
MANIFEST.MF is the most important file in META-INF. Every JAR file created by standard tooling includes one. It is a plain-text key-value file that the JVM reads before doing anything else with the archive.
A minimal manifest for an executable JAR looks like this:
Key attributes and what they control:
| Attribute | Purpose |
Main-Class | Entry point when running java -jar |
Class-Path | Additional JARs to include on the classpath |
Implementation-Version | Version string for the library or application |
Specification-Version | API contract version for compatibility checks |
Sealed | When set on a package, forces all classes in that package to come from this JAR |
You can also define per-package attributes by adding named sections:
This seals the com.example.api package, preventing other JARs from contributing classes to it at runtime, which protects against classpath conflicts and split-package issues.
JAR Signing and Security Files
When a JAR is signed, three additional files appear in META-INF:
The .SF file contains digests of each section of MANIFEST.MF. The .RSA (or .DSA or .EC) file contains the actual cryptographic signature and the signer's certificate chain. Together they let the JVM verify that no file in the JAR has been modified since signing.
You can verify a signed JAR from the command line:
If any class file has been altered, the verification fails. This mechanism is the foundation for Java WebStart security, applet trust decisions, and enterprise deployment policies.
Service Provider Interface (SPI)
The META-INF/services/ directory is central to Java's ServiceLoader mechanism, which enables modular, pluggable architectures without compile-time coupling.
Each file in services/ is named after a fully qualified interface or abstract class, and its contents list the concrete implementations:
File contents:
At runtime, the application discovers implementations dynamically:
This pattern is used extensively in the JDK itself (JDBC drivers, XML parsers, cryptographic providers) and in frameworks like SLF4J for logging backend discovery.
Framework-Specific Files in META-INF
Beyond standard JVM files, many frameworks place their own configuration in META-INF:
| File | Framework | Purpose |
persistence.xml | JPA (Hibernate, EclipseLink) | Defines persistence units, data sources, and entity mappings |
beans.xml | CDI (Java EE / Jakarta EE) | Enables CDI bean discovery in the archive |
spring.factories | Spring Boot (pre-3.0) | Lists auto-configuration classes for component scanning |
spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | Spring Boot 3.0+ | Replacement for spring.factories |
web-fragment.xml | Servlet 3.0+ | Declares servlets, filters, and listeners for modular web apps |
INDEX.LIST | JDK | Speeds up class loading by indexing package-to-JAR mappings |
A typical JPA persistence.xml inside META-INF:
META-INF in WAR and EAR Archives
In web archives (WAR), META-INF appears at the archive root, while web resources go under WEB-INF. In enterprise archives (EAR), META-INF holds application.xml, which declares the modules (WARs, EJB JARs) packaged inside.
Archive structure comparison:
The key point is that META-INF always lives at the archive root regardless of archive type, and different containers look for different files inside it.
Common Pitfalls
- Placing
persistence.xmldirectly in the project root instead of insideMETA-INF. JPA will not find it and will fail silently or throw an opaque error about missing persistence units. - Confusing
META-INFin a JAR withWEB-INFin a WAR. These are different directories with different visibility rules. Files inMETA-INFare accessible viaClassLoader.getResource(), whileWEB-INFcontents are accessible through theServletContext. - Forgetting that
META-INF/services/files must use the fully qualified interface name as the filename, not the implementation name. Getting this reversed meansServiceLoaderfinds nothing. - Editing
MANIFEST.MFby hand and omitting the trailing newline. The manifest specification requires a newline at the end of the file, and some JVM implementations silently ignore the last entry if it is missing. - Assuming all classes from
META-INF/services/are loaded eagerly.ServiceLoaderis lazy by default; implementations are instantiated on iteration, which can mask startup errors until the service is actually used.
Summary
META-INFis a reserved directory in Java archives that the JVM, application servers, and frameworks read automatically.MANIFEST.MFcontrols execution, versioning, classpath, and package sealing.- Signing files (
.SF,.RSA/.DSA) provide tamper-detection and identity verification. META-INF/services/enables the ServiceLoader pattern for runtime plugin discovery.- Frameworks like JPA, CDI, and Spring Boot place their own configuration files in
META-INFfor automatic discovery. - The directory exists in JAR, WAR, and EAR archives, always at the archive root.

