When you start working with Maven, one of the first things you configure in your pom.xml is the packaging type. It seems like a small detail — just a single tag — but it shapes everything about how your project gets built, what artifact gets produced, and which lifecycle goals run at each phase. Getting it wrong can lead to confusing build failures or deployment issues that take a while to trace back to the root cause.
This article walks through the most important Maven packaging types, what they actually do under the hood, and when you should reach for each one.
What Is a Packaging Type, Exactly?
Every Maven project has a Project Object Model, the pom.xml file, which defines the project’s identity and build instructions. Inside that file, the <packaging> tag tells Maven what kind of artifact to produce. If you leave it out entirely, Maven defaults to jar — which is fine for most standalone Java applications and libraries.
The packaging type does more than just determine the file extension of the output. It also controls which goals get bound to which lifecycle phases. A project with war packaging runs different plugin goals during the package phase than a project with jar packaging, and a project with pom packaging runs almost nothing at all during those intermediate phases. Understanding this connection between packaging and lifecycle is what separates developers who troubleshoot build issues quickly from those who spend hours reading plugin documentation.
JAR: The Default and Most Common Type
JAR stands for Java Archive. It is the default packaging type in Maven, and it is what most Java libraries and applications produce. When you run mvn package on a JAR project, Maven compiles the source files, runs tests, and then bundles the compiled class files along with any included resources into a single compressed archive.
JAR files are versatile. They can be imported as dependencies in other projects, deployed as standalone applications with a main class defined in the manifest, or published to a repository for others to consume. The majority of open-source Java libraries you find on Maven Central are distributed as JARs.
One thing worth knowing: Maven also supports an executable JAR format where all dependencies are bundled inside a single “fat JAR” or “uber JAR.” This is handled through plugins like maven-shade-plugin or spring-boot-maven-plugin, not through the packaging type itself, but it is still a JAR at its core. For teams that frequently evaluate which libraries to bundle, maven packages search tools can save a lot of back-and-forth when comparing candidates before committing to a dependency.
WAR: For Web Applications
WAR stands for Web Application Archive. If you are building a Java web application that will be deployed to a servlet container like Apache Tomcat or Jetty, war is the packaging type you need.
The structure of a WAR file is specific. It includes compiled Java classes, JSP files, HTML, CSS, JavaScript, and a WEB-INF directory containing a deployment descriptor along with any JARs the application depends on at runtime. This self-contained structure is what allows a WAR file to be dropped into a servlet container and run without additional configuration.
The lifecycle for WAR packaging largely mirrors JAR packaging, with one key difference: the package phase runs the war goal instead of the jar goal. This goal knows how to assemble the WAR directory structure correctly. One practical note: the web.xml file used to be mandatory for WAR projects, though modern servlet containers and annotations have reduced its necessity in many cases.
POM: The Simplest Type, With a Specific Purpose
POM packaging is unusual because it does not produce a deployable artifact in the traditional sense. The artifact it produces is the POM file itself. This makes it ideal for two specific patterns: parent projects and multi-module aggregators.
A parent POM defines shared configuration — dependency versions, plugin versions, build settings — that child modules can inherit. This prevents the kind of version drift that happens when the same library is declared at different versions across ten different submodules. An aggregator POM, on the other hand, lists submodules and allows you to build the entire project with a single command from the root directory. Often, a single POM serves both roles simultaneously.
Because POM packaging does not compile code or run tests, it only binds goals to the install and deploy phases of the lifecycle. This keeps things clean and avoids unnecessary build work at the parent level.
EAR: Enterprise Archive for Full Java EE Applications
EAR stands for Enterprise Archive. It is the packaging type used for full Java EE (now Jakarta EE) applications that need to be deployed to an application server like WildFly, GlassFish, or IBM WebSphere.
An EAR file can contain multiple modules: web modules packaged as WARs, EJB modules packaged as JARs, and shared library JARs. The deployment descriptor application.xml inside the META-INF directory describes the structure to the application server. In this sense, EAR is a superset of both JAR and WAR — it is the container that holds everything together for enterprise deployment.
EAR packaging requires maven-ear-plugin and has its own lifecycle bindings. A dedicated goal generates the application.xml based on what you have declared in the EAR project’s POM dependencies. EAR is less common today than it was in the Java EE heyday, as microservices and containerized deployments have reduced the need for monolithic enterprise archives. But in legacy enterprise environments or when you genuinely need EJBs and distributed transactions, it remains the right tool.
EJB: Enterprise Java Beans
EJB packaging is used specifically for modules that contain Enterprise Java Beans — server-side components managed by an EJB container, handling concerns like declarative transactions and security. The lifecycle mirrors JAR packaging but with a different goal during the package phase, and it uses maven-ejb-plugin. Maven supports EJB 2 and EJB 3, defaulting to version 2 if none is specified.
EJB modules are typically included as dependencies in an EAR project, where they sit alongside WAR modules in the final enterprise archive.
maven-plugin: When You Are Building Maven Itself
If you are writing a Maven plugin — a tool that other Maven builds will use — the packaging type is maven-plugin. This type extends the JAR lifecycle with additional goals that generate the plugin descriptor file Maven needs to understand what goals the plugin provides and how to invoke them.
Most developers will never write a Maven plugin from scratch, but knowing this type exists helps when you encounter it in an existing codebase or open-source project.
RAR: Resource Adapters
RAR stands for Resource Archive in the Java EE context. A resource adapter is a system-level driver that connects a Java application to an enterprise information system — think JCA connectors for mainframes, legacy databases, or messaging systems. A RAR file contains a JAR with source code and a deployment descriptor. Like EJB and WAR, it follows a lifecycle similar to JAR but with a distinct package goal handled by maven-rar-plugin.
Choosing the Right Type
The decision is usually straightforward once you know what you are building. Libraries and standalone Java apps go with jar. Web applications for Tomcat or Jetty go with war. Shared dependency management or multi-module project structures use pom. Full enterprise application deployments to an app server use ear. EJB modules use ejb, and Maven plugins use maven-plugin.
The packaging type you choose is not just a label — it determines the entire build path your project takes. Getting it right from the start, and pairing it with well-chosen dependencies, saves a considerable amount of time later. If you are still exploring which artifacts fit your project before locking in those decisions, mavenpackages.com is a good place to search and compare what is available across the ecosystem.






