Spring Boot Artifact Packaging
About
Spring Boot artifact packaging refers to the process of bundling our Spring Boot application into a deployable format. This packaging ensures that our application can be easily deployed and run on various environments without requiring additional setup or configuration. Spring Boot provides multiple options for packaging artifacts (such as JARs and WARs) to simplify deployment. The packaging mode chosen depends on the type of application (standalone or traditional web app) and the intended deployment environment.
Most common types of Packaging Options
JAR (Java Application Archive): By default, Spring Boot packages applications as executable JARs. An executable JAR includes the application's code, dependencies, and an embedded servlet container (such as Tomcat or Jetty), enabling us to run the application with a simple
java -jar
command.WAR (Web Application Archive): Spring Boot can also package applications as traditional WAR files. These WAR files are deployable to external servlet containers (such as Tomcat, Jetty, or WildFly). WAR packaging is useful when deploying Spring Boot applications in environments where a servlet container is already provided by the infrastructure
EAR (Enterprise Application Archive): This packaging format is used for deploying large-scale enterprise applications that consist of multiple modules, such as EJBs, web applications, and connectors. EAR files include multiple modules, each packaged as a JAR or WAR file. They are suitable for complex applications with multiple components that need to be deployed together.
Executable JAR: This is a special type of JAR file that can be executed directly from the command line without requiring the
java -jar
command. It includes a native launcher that allows the application to be run on different operating systems without requiring a Java installation. Executable JAR files are convenient for distributing our application to users who may not have Java installed.
JAR Packaging
1. What is a JAR File?
A JAR is a compressed archive that can contain Java classes, libraries, images, and resources necessary for a Java application to run.
It uses the same format as a ZIP file but has additional metadata for Java applications.
JAR files are platform-independent and allow Java applications to be distributed and deployed easily.
Compression in JAR Files
JAR files use ZIP compression to reduce the size of the archive. This compression helps in faster transmission and better storage utilization.
The compression is automatically handled when we create a JAR using tools like
jar
or build systems like Maven or Gradle.
2. Types of JAR Files
Library JAR: A non-executable JAR that contains code (typically reusable libraries) without a
Main-Class
entry.Executable JAR: Contains a
Main-Class
entry in itsMANIFEST.MF
file, which allows the JAR to be executed withjava -jar
.Runnable JAR: A type of executable JAR but with dependencies packed inside (a "fat JAR").
Aspect
Fat JAR (Uber JAR)
Thin JAR
Modular JAR (Jigsaw)
Executable JAR
Description
Bundles the application code and all its dependencies into a single JAR.
Contains only the application code and minimal metadata. Dependencies must be provided externally.
Designed for use with Java modules introduced in Java 9. Contains module metadata (module-info.class).
Contains the main class and can be run directly with java -jar
, but may not include dependencies.
Purpose
Simplifies deployment by packaging everything together.
Reduces size by excluding dependencies.
Enables modularity in Java applications and better dependency management.
Provides a runnable JAR for Java apps but dependencies are handled externally.
Dependencies
Embedded within the JAR (e.g., in BOOT-INF/lib/
).
Not included in the JAR; they must be managed externally (e.g., in lib/
folder or via classpath).
Dependencies can be external or modular, managed via modules.
Dependencies are not included and must be managed via classpath.
Class Loading
Uses a custom class loader (e.g., Spring Boot Loader) to load dependencies.
Relies on the external classpath for dependencies.
Java's module system handles class loading and visibility.
Standard Java class loader, dependencies managed via classpath.
Size
Larger, since it includes the application and all dependencies.
Smaller, as it only contains the application code and metadata.
Typically smaller but may vary based on module dependencies.
Typically smaller, only contains the application code and a MANIFEST.MF
.
Usage
Common in Spring Boot, standalone apps, and microservices where ease of deployment is important.
Used in environments where dependencies are provided externally, like application servers.
Modular applications built with Java 9+ where fine-grained control over dependencies is needed.
Common for simple applications, but requires dependencies to be handled manually.
Build Tools
Typically created using Maven/Gradle plugins (e.g., Spring Boot Maven/Gradle Plugin, Maven Shade Plugin).
Standard JAR creation in Maven/Gradle without plugins that package dependencies.
Built using Jigsaw and compatible build tools (Maven/Gradle).
Generated using build tools (e.g., Maven jar
plugin) with a main class specified in MANIFEST.MF
.
Deployment
Self-contained; can be deployed directly without worrying about external dependencies.
Requires external dependencies, making deployment more complex (dependencies must be provided by the environment).
Deployed with external modules, allowing for fine control of dependency management.
Requires external libraries or dependencies to be available on the classpath.
Advantages
- Simplifies deployment - Bundles everything needed - Ideal for microservices and cloud deployments
- Smaller JAR file - Separation of concerns (code vs. libraries) - Useful for large apps managed by servers like Tomcat, JBoss
- Clear separation of modules - Better dependency management - Enhanced encapsulation
- Smaller size - Easier to understand and build for simple applications
Disadvantages
- Larger JAR file - Redundant packaging if dependencies are already available in the environment
- Needs external libraries - Deployment can be complex in certain environments
- More complex to configure - Requires understanding of Java’s module system
- Does not include dependencies, must manage classpath manually
Example
Spring Boot application packaged using Maven/Gradle plugins to include the app and its dependencies.
Java EE or Jakarta EE apps deployed to an application server, where libraries are provided by the server.
Modular Java application using the module-info.java
descriptor introduced in Java 9.
Simple standalone Java application with a Main-Class
specified in the MANIFEST.MF
.
3. Typical JAR File
A Typical JAR file contains:
Java Class Files: Compiled
.class
files from the Java source code.Resources: Non-code resources such as images, configuration files, property files, etc.
Manifest File (
META-INF/MANIFEST.MF
): A special file that contains metadata about the JAR, such as the main class to be executed, versioning information, and other properties.
JAR file structure
-> Manifest File (MANIFEST.MF
)
MANIFEST.MF
)The MANIFEST.MF file located in the META-INF
directory is critical for providing meta-information about the JAR file. It follows a key-value format and can contain:
Version Information: Version of the manifest and the JAR file.
Main-Class: Specifies the entry point (the class containing the
main()
method) of the application when the JAR is executable.
Class-Path: Specifies external libraries or JAR files required for the application to run.
Example MANIFEST.MF
:
-> com/myapp/
(or equivalent package structure)
This is where all our compiled class files are stored. The directory structure reflects the package hierarchy of our Java classes.
Example:
-> resources/
(or other resource directories)
Non-class files such as properties files, images, or XML configuration files are often included here.
These files might be configuration files or other resources that our application needs to access at runtime.
Example:
Running a JAR
If the manifest specifies a
Main-Class
, we can run the JAR with:
Otherwise, we must manually specify the classpath and main class to run:
4. Spring Boot JAR File
In addition to a typical JAR file, a Spring Boot JAR has:
Embedded Dependencies: All third-party libraries are included in
BOOT-INF/lib
, making it a fat JAR. This eliminates the need for an external dependency manager during runtime.Custom Class Loader: Spring Boot uses a custom class loader (from the
org.springframework.boot.loader
package) to load classes fromBOOT-INF/classes
andBOOT-INF/lib
correctly.Embedded Server: If we're building a Spring Boot web application, the JAR file will contain an embedded web server (like Tomcat or Jetty) inside the
BOOT-INF/lib
directory, allowing the application to run standalone without external servers.
Spring Boot JAR file structure
-> BOOT-INF/
Directory
BOOT-INF/
DirectoryThis is where Spring Boot segregates the application’s compiled classes and its dependencies.
--- BOOT-INF/classes/
:
Contains our application’s compiled
.class
files and other resources (e.g., properties or YAML files).For example:
--- BOOT-INF/lib/
:
Contains all the third-party dependencies packaged within our Spring Boot application. These are the libraries our application needs to run, based on what we declared in
pom.xml
orbuild.gradle
.Each library is stored as a separate JAR file.
For example:
-> META-INF/
Directory
META-INF/
DirectoryThis directory contains metadata about our application, typical in Java archive files.
--- META-INF/MANIFEST.MF
:
The manifest file contains metadata such as the entry point of our Spring Boot application and the version of Spring Boot.
Example content:
Main-Class: Specifies the class that will bootstrap our Spring Boot application, typically
JarLauncher
.Start-Class: Our application’s entry point with the
main()
method (MainApplication
in this case)
--- META-INF/maven/org.example/sample-project/
:
This subdirectory contains files generated by Maven during the build process:
pom.xml
: The project’s Mavenpom.xml
file. It defines the project’s dependencies and configuration.pom.properties
: This file contains information such as the group ID, artifact ID, version, and other Maven-related metadata.
Example structure:
-> org/springframework/boot/loader/
Directory
This directory is part of the Spring Boot Loader. It contains the classes that manage launching our Spring Boot application.
Loader Classes:
The classes here, such as
JarLauncher
,WarLauncher
, andPropertiesLauncher
, handle the custom class loading and the execution of our Spring Boot JAR file.These classes are responsible for reading classes from
BOOT-INF/classes
andBOOT-INF/lib
and ensuring that they are available to the application.Key classes:
JarLauncher
: Handles launching the Spring Boot JAR.WarLauncher
: Used if the application is packaged as a WAR (not typical for a JAR).PropertiesLauncher
: Enables launching based on configuration properties.
Example:
5. How Spring Boot Fat JAR Works?
When we run a Spring Boot JAR using java -jar sample-project-1.0-SNAPSHOT.jar
, the following process happens:
Spring Boot Loader: The
JarLauncher
(specified in theMANIFEST.MF
) starts execution.Class Loading: The launcher sets up a custom class loader that loads classes from
BOOT-INF/classes
(our application’s classes) andBOOT-INF/lib
(our dependencies).Application Startup: The
Start-Class
(our main application class, specified in the manifest) is then located and executed, starting the Spring Boot application.Embedded Server: If it’s a web application, the embedded web server (e.g., Tomcat) is started, and the application becomes accessible via the configured port (default:
8080
).
6. Creating a JAR File
a. Using the JDK jar
Tool
jar
ToolThe JDK provides a jar
command to create, view, or extract JAR files.
-> Creating a JAR: If we have compiled class files in the com/example
directory:
c
: Create a new JAR file.v
: Verbose output to show the files being added.f
: Output the result to a file (e.g.,myapp.jar
).-C
: Change to the specified directory (./com
) before adding files.
-> Adding a Manifest File: We can include a custom MANIFEST.MF
file using:
b. Using Build Tools
Maven: Maven simplifies the process of building JAR files using the
maven-jar-plugin
:
7. Security in JAR Files
a. Signing JAR Files
We can sign a JAR file to ensure its authenticity and integrity. Signing is typically used when distributing JARs over the web.
Sign JAR: Use the
jarsigner
tool to sign a JAR file.
b. Verifying Signed JARs
We can verify the signature of a JAR file using:
8. Multi-Release JARs
Introduced in Java 9, multi-release JARs allow different class versions to be packaged for different Java runtime environments. This enables backward compatibility while taking advantage of newer Java features.
Structure of a multi-release JAR:
The JVM automatically selects the appropriate class version based on the runtime environment.
WAR Packaging
1. What is a WAR File?
A WAR file is a standard format used for deploying web applications on a Java EE (Enterprise Edition) server. It contains all the components required for a web application to run, such as Java classes, libraries, configuration files, static resources, and JSP (JavaServer Pages) files. A WAR file can be deployed to any compliant servlet container or application server that implements the Java Servlet API.
The WAR file has a specific structure and layout that conforms to the Java Servlet Specification. However, Spring Boot adds some enhancements to make it easier to work with WAR packaging in modern development workflows.
2. Structure of a Spring Boot WAR File
When we package a Spring Boot application as a WAR file (e.g., sample-project-1.0-SNAPSHOT.war
), the file will have the following structure after extraction:
-> META-INF/
Directory
META-INF/
DirectoryThis is a standard directory in any JAR or WAR file that contains metadata about the archive.
META-INF/MANIFEST.MF
:This is the manifest file for the WAR file, similar to a JAR. It typically contains metadata such as:
Manifest-Version: The version of the manifest format.
Class-Path: The classpath needed to run the application (optional in WARs).
Main-Class: Often absent in WAR files, as they do not run standalone like JARs.
In a Spring Boot WAR, the Main-Class attribute might not be present, since the WAR will be managed by the external server.
Example
MANIFEST.MF
:
-> WEB-INF/
Directory
The WEB-INF
directory is the heart of the WAR file and is not directly accessible via the web browser. It contains all the important parts of the web application: classes, libraries, and configuration files.
WEB-INF/web.xml
(Optional):This file is the deployment descriptor for the Java EE web application. It specifies configurations like servlets, filters, listeners, and security settings.
For Spring Boot applications, we typically don’t need to configure
web.xml
manually, as Spring Boot uses Java-based configuration. However, if we need to, we can override this and add custom servlet or filter configurations.Example:
WEB-INF/classes/
:This directory contains all the compiled classes from our
src/main/java
directory.All of our application’s resources (like
application.properties
,application.yml
, or static resources) will also reside here.Example:
WEB-INF/lib/
:This directory contains all the JAR dependencies required by the application. This includes all libraries we specified in the
pom.xml
orbuild.gradle
file.Spring Boot makes sure that all our external dependencies (like
spring-core
,spring-web
, etc.) are included here.Example:
WEB-INF/lib-provided/
(Optional):If we are relying on certain dependencies that are provided by the application server (e.g.,
javax.servlet-api
,spring-web
), we can place them in this directory to signal that they should not be included in the final WAR.These libraries are typically provided by the servlet container (e.g., Tomcat), and we don’t need to include them in the WAR file.
Example:
-> org/springframework/boot/loader/
Directory (Optional)
org/springframework/boot/loader/
Directory (Optional)In a Spring Boot JAR, this directory contains Spring Boot’s launcher classes. However, for a WAR deployment, this may or may not be present. When deploying a Spring Boot application as a WAR, the servlet container’s classloader handles the loading process.
If present: This folder contains
JarLauncher
,WarLauncher
, and other Spring Boot loader classes used for custom class loading when running as a standalone WAR.If absent: The WAR relies on the external servlet container for launching, so this package isn't needed.
-> Static Resources (Optional)
Static resources (like HTML, CSS, JS, and image files) are usually placed outside of the WEB-INF
directory in the root directory of the WAR. For example:
index.html
: The main landing page for the application.static/
: This directory holds static resources such as images, CSS files, or JavaScript files that are publicly accessible.
Example structure:
EAR Packaging
1. What is an EAR File?
An EAR (Enterprise Archive) is a file format used for packaging and deploying Java EE enterprise applications. It encapsulates multiple related modules that together form a cohesive application, including Web Applications (WARs), EJB (Enterprise JavaBeans) modules (JARs), and utility libraries. EAR packaging is typically used for applications with complex business logic involving multiple tiers (web tier, business tier, etc.).
EAR files follow a standardized structure as defined by the Java EE specifications, and are deployed to application servers that support the full Java EE platform.
2. Typical Structure of an EAR File
When we package a Java EE application as an EAR file (e.g., sample-project-1.0-SNAPSHOT.ear
), the resulting file structure, after extraction, looks like the following:
-> META-INF/
Directory
META-INF/
DirectoryThis directory holds metadata about the EAR file and its contents.
META-INF/MANIFEST.MF
:Similar to other Java archive formats (JAR, WAR), the
MANIFEST.MF
file in theMETA-INF
directory contains information about the EAR file itself.Example:
META-INF/application.xml
(Optional):This is the deployment descriptor for the EAR file. It describes how the different modules (WARs, EJB JARs, etc.) in the EAR should be deployed.
For Spring Boot applications or modern Java EE configurations, this file may be optional or even omitted, as many servers can use annotations or default conventions.
A typical
application.xml
would specify all the modules (JARs and WARs) that are part of the EAR, and any context root or configuration settings.Example:
3. WAR Modules
Web Applications are packaged as WAR files and included in the EAR. Each WAR module contains the structure already discussed in the previous section (like
WEB-INF
,META-INF
,classes
, etc.).These WAR modules represent the web tier of the enterprise application, and they handle HTTP requests and responses. For example, in a traditional multi-tier enterprise application, the web module (WAR) would serve as the user interface (UI) tier that interacts with the business tier (EJB).
Example:
The WAR
module would behave just like any Spring Boot web application or Java EE web application.
4. JAR Modules (EJB and Utility JARs)
EJB Modules are packaged as JAR files within the EAR. These contain the business logic in the form of Enterprise JavaBeans (EJBs).
Utility JARs: These are libraries shared across the application, which can be referenced by both WAR and EJB modules. Utility classes or shared components, like logging frameworks, database utilities, or shared services, can be placed in this directory.
Example:
JAR vs WAR vs EAR
Aspect
JAR
WAR
EAR
Purpose
Standalone applications (with embedded server).
Deployable web applications to a servlet container (e.g., Tomcat).
Multi-module enterprise applications (web, EJB, etc.) managed by an application server.
Application Server
Embedded (self-contained) server, like Tomcat, Jetty, or Undertow.
Requires external servlet container (Tomcat, Jetty) for deployment.
Requires a full-fledged Java EE-compliant application server (e.g., WildFly, GlassFish, WebLogic).
Deployment Method
Directly run via java -jar <app>.jar
.
Deploy WAR to a servlet container (Tomcat, Jetty, etc.).
Deploy EAR to a Java EE-compliant application server.
Structure
Contains BOOT-INF/classes
(compiled classes), BOOT-INF/lib
(dependencies), and Spring Boot loader classes.
Contains a typical WAR structure: WEB-INF/
, META-INF/
, classes
, lib
.
Contains multiple modules, including WARs, EJB JARs, and shared libraries (lib/
).
Configuration Files
Application-specific configurations (application.properties
, application.yml
) bundled in BOOT-INF/classes
.
Standard web.xml
configuration in WEB-INF/
.
application.xml
in META-INF/
for EAR metadata and module definitions.
Embedded Server
Yes (Tomcat, Jetty, Undertow can be embedded within the JAR).
No, relies on the servlet container in which it is deployed.
No, relies on the application server for both web and EJB modules.
Ease of Deployment
Simple to deploy as a single JAR; just run it as a standard Java application.
Requires deployment to an external servlet container (Tomcat, Jetty).
More complex as multiple modules are deployed as one EAR package.
Scalability
Good for microservices or small applications due to its simplicity and self-contained nature.
Suitable for larger applications but still requires a container.
Best suited for enterprise-level applications with complex modules (web, EJB, etc.).
Module Handling
No modularity; the JAR encapsulates everything.
WAR is a single web module with JSP, servlets, Spring controllers, etc.
EAR can bundle multiple WARs, EJB JARs, and shared libraries for modularity.
Spring Boot Support
Fully supported by Spring Boot (standard packaging method for Spring Boot apps).
Supported but requires a slight change to pom.xml
for WAR packaging.
Not directly supported by Spring Boot (typically used in full Java EE environments).
Use Cases
Ideal for standalone microservices or self-contained applications.
Web applications that need to run in traditional servlet containers.
Large, complex enterprise applications requiring EJB, multiple WARs, and shared resources.
Class Loading
Handles its own class loading with Spring Boot Loader.
Depends on the servlet container’s classloader.
Handled by the Java EE application server, allowing multiple modules to share classes.
Shared Libraries
All dependencies are bundled inside the JAR itself (via BOOT-INF/lib
).
External libraries can be shared via the servlet container’s lib
directory.
A dedicated lib/
directory inside the EAR for shared libraries accessible by all modules (WAR, JAR).
Application Server Features
Limited application server features (e.g., no full Java EE compliance).
Only servlet-based features (no EJB or resource adapters).
Full Java EE support including EJB, JPA, messaging, resource adapters, etc.
Security
Spring Security can be bundled for application-level security.
Relies on container-based security, e.g., web.xml for security constraints.
Uses the full range of Java EE security (JASPIC, JAAS, container-managed security).
Customization
Customization of the embedded server is possible (configuring ports, HTTPS, etc.).
Relies on the external servlet container’s configuration.
Application server manages module interaction, security, and resource adapters.
Hot Deployment
Not typically supported; usually requires restarting the app for changes.
Some servlet containers support hot deployment (reloading changes without restarting).
Most Java EE servers support hot deployment for EARs (hot swapping modules).
Development Effort
Lower effort, simpler setup for microservices and small applications.
Medium effort, suitable for traditional web apps.
Higher effort, more suited for enterprise-level, multi-module apps.
Tools
Built using tools like Spring Boot, Maven, Gradle with Spring Boot plugins for packaging.
Built using Spring Boot with modified pom.xml for WAR packaging.
Typically built using Maven EAR Plugin or Ant, and deployed on application servers like WildFly or WebLogic.
Typical Examples
Microservices, REST APIs, standalone applications (e.g., Spring Boot apps).
Standard web applications using JSP/Servlets or Spring MVC.
Enterprise applications involving multiple modules, e.g., web (WAR) and business logic (EJB JAR).
Last updated
Was this helpful?