What is an Archive File?
An archive file is simply a single file that contains many other files bundled together. Think of it like a ZIP file—because that's exactly what Java archives are!
Moving Box Analogy:
Imagine you're moving to a new house. Instead of carrying thousands of individual items one at a time, you pack them into boxes. Each box:
- Contains many items organized in a specific way
- Has a label describing its contents
- Is easy to move as a single unit
- Can be unpacked to access individual items
Java archives (JAR and WAR) work the same way—they bundle all your application's files into a single, portable package.
Why Not Just Use ZIP Files?
Java archives ARE ZIP files with extra features:
- Standard structure - Everyone agrees where files go
- Manifest file - Contains metadata about the archive
- JVM integration - Java can run code directly from archives
- Classpath support - The JVM knows how to find classes in archives
# You can actually open any JAR/WAR with a ZIP tool:
unzip myapp.jar -d extracted/
# Or use Java's jar command:
jar -tf myapp.jar # List contents
jar -xf myapp.jar # Extract contents
JAR Files: Java Archive
A JAR (Java Archive) file is the standard packaging format for Java applications and libraries. It bundles compiled Java classes, resources, and metadata into a single file.
JAR File Structure
myapp.jar
├── META-INF/
│ ├── MANIFEST.MF # Manifest file (metadata)
│ └── maven/ # (Optional) Maven info
├── com/
│ └── example/
│ ├── Main.class # Compiled Java classes
│ ├── Service.class
│ └── util/
│ └── Helper.class
├── application.properties # Configuration files
└── static/
└── logo.png # Static resources
The MANIFEST.MF File
The manifest is a special file that contains metadata about the JAR:
# META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 17.0.1 (Oracle Corporation)
Main-Class: com.example.Main
Class-Path: lib/gson-2.9.0.jar lib/commons-lang3-3.12.0.jar
Implementation-Title: My Application
Implementation-Version: 1.0.0
Types of JAR Files
| Type | Description | How to Run |
|---|---|---|
| Library JAR | Reusable code (no Main-Class) | Add to classpath |
| Executable JAR | Has Main-Class in manifest | java -jar app.jar |
| Fat/Uber JAR | Includes all dependencies | java -jar app.jar |
Creating JAR Files with Maven
<!-- pom.xml -->
<packaging>jar</packaging>
<build>
<plugins>
<!-- Standard JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.example.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Fat JAR with shade plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
WAR Files: Web Application Archive
A WAR (Web Application Archive) file is a specialized packaging format for Java web applications. It contains everything needed to deploy a web application to a servlet container.
WAR = JAR + Web Structure
A WAR file is essentially a JAR file with a specific directory structure that servlet containers understand. This structure defines where to find servlets, JSP files, static resources, and dependencies.
WAR File Structure
mywebapp.war
├── META-INF/
│ └── MANIFEST.MF
├── WEB-INF/ # PROTECTED - Not accessible via URL!
│ ├── web.xml # Deployment descriptor
│ ├── classes/ # Compiled Java classes
│ │ └── com/
│ │ └── example/
│ │ ├── HomeServlet.class
│ │ └── ProductServlet.class
│ └── lib/ # JAR dependencies
│ ├── gson-2.9.0.jar
│ └── mysql-connector-8.0.jar
├── index.html # PUBLIC - /mywebapp/index.html
├── css/
│ └── style.css # PUBLIC - /mywebapp/css/style.css
├── js/
│ └── app.js # PUBLIC - /mywebapp/js/app.js
└── images/
└── logo.png # PUBLIC - /mywebapp/images/logo.png
The WEB-INF Directory: Understanding Protection
The WEB-INF directory is special—its contents cannot be accessed directly by clients via HTTP requests:
# What users CAN access (outside WEB-INF):
http://localhost:8080/mywebapp/index.html ✓ Returns HTML
http://localhost:8080/mywebapp/css/style.css ✓ Returns CSS
# What users CANNOT access (inside WEB-INF):
http://localhost:8080/mywebapp/WEB-INF/web.xml ✗ 404 or 403
http://localhost:8080/mywebapp/WEB-INF/classes/ ✗ 404 or 403
# WHY? Security! WEB-INF contains:
# - Configuration with database credentials
# - Compiled code that could be decompiled
# - Libraries that could reveal vulnerabilities
Always put sensitive files (JSP templates, configuration) inside WEB-INF/. Use servlets to forward requests to protected resources.
Creating WAR Files with Maven
<!-- pom.xml -->
<packaging>war</packaging>
<dependencies>
<!-- Servlet API - provided by container -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope> <!-- Not included in WAR -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
JAR vs WAR: Complete Comparison
| Aspect | JAR | WAR |
|---|---|---|
| Full Name | Java Archive | Web Application Archive |
| Purpose | General Java apps/libraries | Web applications |
| Structure | META-INF/ + classes + resources | WEB-INF/ + public resources |
| Deployment | java -jar or classpath |
Deploy to servlet container |
| Dependencies | Optional (fat JAR) or external | Always in WEB-INF/lib |
| Protected Area | None | WEB-INF/ (hidden from web) |
| Hot Deployment | Requires restart | Supported by containers |
Spring Boot: JAR or WAR?
Spring Boot applications can be packaged as either JAR or WAR:
Spring Boot JAR (Recommended)
<packaging>jar</packaging>
# Run with:
java -jar myapp-1.0.0.jar
# Benefits:
# - Embedded Tomcat included
# - Simple deployment
# - Cloud-native friendly
Spring Boot WAR (For External Container)
<packaging>war</packaging>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope> <!-- Don't include Tomcat -->
</dependency>
// Main class for WAR deployment
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder app) {
return app.sources(MyApplication.class);
}
}
When to Use Each Format
| Use Case | Recommended | Reason |
|---|---|---|
| New Spring Boot app | JAR | Simpler, embedded container |
| Cloud deployment | JAR | Better for Docker |
| Legacy system | WAR | May require existing container |
| Corporate standard | WAR | WebLogic/WebSphere requirement |
| Microservices | JAR | Independent deployment |
| Reusable library | JAR | Not a web application |
EAR Files: Enterprise Archive
For completeness, EAR (Enterprise Archive) files bundle multiple modules (WARs, JARs) into a single deployable unit for full application servers:
enterprise-app.ear
├── META-INF/
│ ├── MANIFEST.MF
│ └── application.xml # Defines modules
├── web-module.war # Web tier
├── ejb-module.jar # EJB tier
└── lib/
└── shared-utils.jar # Shared libraries
Modern Perspective: EAR files were common in the Java EE era but are less common today. Modern architectures favor microservices (independent JARs), Spring Boot (embedded containers), or containers (Docker).
Common Issues and Troubleshooting
1. "No main manifest attribute"
# Error:
java -jar myapp.jar
no main manifest attribute, in myapp.jar
# Solution: Add Main-Class to manifest in pom.xml
<manifest>
<mainClass>com.example.Main</mainClass>
</manifest>
2. ClassNotFoundException in Fat JAR
# Error: Dependency classes not found at runtime
# Cause: Dependencies not included in JAR
# Solution: Use maven-shade-plugin for fat JAR
# Check what's in your JAR:
jar -tf myapp.jar | grep gson
# Should show com/google/gson/... if using fat JAR
3. javax vs jakarta Package Issues
# Error in Tomcat 10+:
java.lang.NoClassDefFoundError: javax/servlet/Servlet
# Cause: Using javax.servlet with Tomcat 10+ (requires jakarta)
# Solution: Update imports and dependencies
# OLD: import javax.servlet.*;
# NEW: import jakarta.servlet.*;
Summary
- JAR: General-purpose Java archive for applications and libraries
- WAR: Web application archive with specific structure for servlet containers
- WEB-INF/: Protected directory in WAR, inaccessible via HTTP
- Fat JAR: JAR with all dependencies bundled inside
- Embedded containers: Modern approach, container inside your JAR
- Spring Boot JAR: Preferred for new applications
- WAR for legacy: Use when external container is required
- MANIFEST.MF: Contains metadata, Main-Class for executables