By WebNest Studio Engineering Team
Advanced Java Tutorial
Packaging and Deployment: JAR and WAR
Once a Java application is written and tested, it needs to be packaged into a distributable form that can run on another machine — a teammate's laptop, a test server, or production infrastructure. Java defines standard archive formats for this, and the two you'll encounter constantly are JAR (Java ARchive) and WAR (Web ARchive).
Both are, structurally, just ZIP files with a specific internal layout and a required metadata file. The difference is what they're meant to contain and where they're meant to run.
Why it matters
Compiled classes are not what you hand to a server; an archive is. Knowing what is inside a JAR or a WAR, and what makes one runnable, explains the errors met on every first deployment: "no main manifest attribute" and ClassNotFoundException. Spring Boot's single runnable JAR builds directly on these ideas.
JAR — Java ARchive
A JAR bundles compiled .class files, resources (property files, images, config), and a manifest file (META-INF/MANIFEST.MF) into a single distributable file. JARs are used both for reusable libraries (something other projects depend on, with no way to "run" it directly) and for standalone runnable applications.
- A library JAR is meant to be placed on another program's classpath or declared as a Maven/Gradle dependency.
- A runnable JAR includes a
Main-Classentry in its manifest, so it can be executed directly withjava -jar app.jarwithout specifying the entry class on the command line. - A "fat" or "uber" JAR bundles the application's own classes together with all of its dependencies' classes, so it can run standalone with no external classpath setup.
WAR — Web ARchive
A WAR packages a Java web application — servlets, JSPs, static assets, and web-specific configuration (WEB-INF/web.xml or its modern annotation-based equivalent) — in a structure that a servlet container understands. Unlike a plain JAR, a WAR is not run with java -jar; it is deployed into a servlet container such as Apache Tomcat, Jetty, or WildFly, which unpacks it, wires up the servlets, and manages the application's web lifecycle (handling HTTP requests, session management, and so on).
Choosing Between Them
The choice generally isn't really a choice you make freely — it follows from the architecture. A command-line tool, a batch job, a microservice with an embedded HTTP server (such as one built with embedded Tomcat inside Spring Boot), or a shared library is packaged as a JAR. A traditional web application meant to be deployed into an externally managed servlet container is packaged as a WAR. Modern cloud-native Java increasingly favors runnable "fat" JARs with an embedded server over WARs deployed to a separate container, because it simplifies deployment to a single self-contained artifact.
Examples
Building and running a runnable JAR with a manifest Main-Class entry
// Compile
// javac -d out src/com/webnest/App.java
package com.webnest;
public class App {
public static void main(String[] args) {
System.out.println("Running from a JAR file");
}
}
// Create a manifest file, manifest.txt, containing:
// Main-Class: com.webnest.App
//
// Package into a runnable JAR:
// jar cfm app.jar manifest.txt -C out .
//
// Run it directly, no classpath flags needed:
// java -jar app.jar
Running from a JAR file
A minimal WAR directory layout for a servlet container
my-webapp.war
├── index.html
├── css/
│ └── styles.css
└── WEB-INF/
├── web.xml (servlet mappings, or omitted if using annotations)
├── classes/
│ └── com/webnest/HelloServlet.class
└── lib/
└── some-dependency.jar
// Deployed by copying my-webapp.war into Tomcat's webapps/ directory.
// Tomcat unpacks it and serves it at: http://localhost:8080/my-webapp/
INFO: Deploying web application archive [my-webapp.war]
INFO: Deployment of web application archive [my-webapp.war] has finished
Common Mistakes
- Trying to run a WAR file directly with "java -jar" — a WAR must be deployed into a servlet container, it has no standalone entry point.
- Forgetting the Main-Class entry in a JAR's manifest and then being unable to run it with "java -jar", requiring the class name to be specified manually on the classpath instead.
- Assuming a plain JAR automatically includes its dependencies — without building a "fat" JAR (via a plugin like Maven Shade or the Gradle Shadow plugin), dependency classes are not bundled in.
- Placing web-specific files (web.xml, JSPs) outside the required WEB-INF structure, so the servlet container cannot find them.
Exercise
This exercise uses the JDK command-line tools in a terminal, so it does not run in the playground. A project has one source file, src/Main.java, whose class Main has a main method. Write the commands that compile it into the folder out, package the compiled classes into app.jar with Main as the entry point, and run the JAR.
Expected result: the last command runs the program, with no "no main manifest attribute" error.
# TODO: compile src/Main.java into the folder out
# TODO: create app.jar with Main as the entry point, from the contents of out
# TODO: run the JAR
Show hints
javac -d outwrites the class files into the given folder.- In
jar cfe app.jar Main -C out ., theeoption records the entry point in the manifest.
Show solution
javac -d out src/Main.java
jar cfe app.jar Main -C out .
java -jar app.jar
Quick quiz
1. What must a JAR contain to be run with java -jar?
- A. A web.xml file
- B. A Main-Class entry in its manifest
- C. A pom.xml file
- D. At least two classes
Show answer
B. Without it, the JVM reports "no main manifest attribute".
2. Where do the compiled classes go inside a WAR file?
- A. In the root folder
- B. In META-INF
- C. In WEB-INF/classes
- D. In lib
Show answer
C. Library JARs go in WEB-INF/lib.
3. How is a Spring Boot application usually packaged?
- A. As an executable JAR that contains an embedded server and all its dependencies
- B. As a WAR that needs a separate server
- C. As separate class files
- D. As a ZIP of source code
Show answer
A. It is started with java -jar, with no application server to install.
Interview questions
What is the difference between a JAR and a WAR?
Show answer
Both are ZIP archives. A JAR packages compiled classes and resources as a library or a standalone application, and is runnable when its manifest names a main class. A WAR packages a web application in the layout a servlet container expects: static files at the root, classes in WEB-INF/classes, libraries in WEB-INF/lib. A WAR is deployed into a server such as Tomcat, which provides the runtime.
What is a fat JAR?
Show answer
A fat JAR, or uber JAR, contains the application's own classes together with all of its dependencies, and in the case of Spring Boot an embedded web server as well. The whole application is one file started with java -jar, which suits containers and cloud deployment. A normal thin JAR holds only the project's classes and expects its dependencies to be supplied on the classpath.
Key Points to Remember
- JAR bundles compiled classes and resources for libraries or standalone runnable applications.
- A runnable JAR needs a Main-Class entry in its manifest to work with "java -jar".
- WAR packages a full web application (servlets, JSPs, WEB-INF) for deployment into a servlet container like Tomcat.
- Modern services increasingly favor self-contained "fat" JARs with an embedded server over externally deployed WARs.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering