skip to content

What does the <packaging> element do, and what are the common packaging types?

level: middleimportance: must knowfreq 70%

answer

  1. packaging picks lifecycle bindings
  2. jar = default
  3. war = maven-war-plugin
  4. pom = no binary, parent/aggregator
  5. maven-plugin = plugin descriptor

basics

~10 s

<packaging> tells Maven what kind of artifact to build and which lifecycle bindings to use. Common values: jar (default), war (web app), pom (aggregator/parent), and maven-plugin.

solid answer

~40 s

The <packaging> element selects the artifact type and, crucially, the default plugin goals bound to each lifecycle phase. With jar (the default), the package phase runs maven-jar-plugin to produce a .jar. With war, maven-war-plugin produces a deployable .war for servlet containers. pom packaging means the module produces no binary itself — it's used for parent POMs and multi-module aggregators; only the pom.xml is installed/deployed. maven-plugin packaging builds a Maven plugin and runs maven-plugin-plugin to generate the plugin descriptor. There are others via extensions (ear, bundle/OSGi, takari, etc.). Choosing packaging is the single biggest switch that changes which default goals execute, so it determines the whole build flow for that module.

code

xml · 3 lines
xml
<packaging>war</packaging>
<!-- binds maven-war-plugin:war to the package phase -->
<!-- output: target/<finalName>.war -->

go deeper

for a junior

Know that jar is the default and war is for web apps.

for a middle

Explain that packaging determines lifecycle goal bindings, and list jar/war/pom/maven-plugin and their purposes.

for a senior

Reason about when to use pom packaging for parents vs aggregators and the cost of mis-choosing packaging.

for a principal

Design multi-module topologies (parent vs aggregator vs BOM), and standardize packaging usage and build-extension policy across teams.

## What <packaging> controls Maven runs builds through a fixed sequence of **lifecycle phases** (validate, compile, test, package, install, deploy, etc.). Which plugin **goals** run in each phase is decided largely by the project's **packaging** type. So `<packaging>` is not just a label for the output file — it picks a whole set of default plugin bindings. If you omit `<packaging>`, it defaults to **jar**. ## Common packaging types - **jar** — default. Binds `maven-jar-plugin:jar` to the `package` phase; output is a `.jar`. Used for libraries and most apps. - **war** — binds `maven-war-plugin:war`; produces a `.war` (Web Application Archive) for servlet containers like Tomcat. Bundles classes, `WEB-INF`, and dependencies. - **pom** — produces no binary artifact; only the `pom.xml` is installed/deployed. Used for: - **parent POMs** that centralize config/dependencyManagement, - **aggregator** modules that list `<modules>` to build several children together. - **maven-plugin** — builds a Maven plugin; binds `maven-plugin-plugin` to generate the plugin descriptor (`plugin.xml`) so the plugin's goals are discoverable. ## Less common (need a build extension) - **ear** — Java EE enterprise archive (maven-ear-plugin). - **bundle** — OSGi bundle (maven-bundle-plugin), requires `<extensions>true</extensions>`. ## Example: parent + war module ```xml <!-- parent/pom.xml --> <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>shop-parent</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <module>shop-web</module> </modules> </project> ``` ```xml <!-- shop-web/pom.xml --> <project> <parent> <groupId>com.example</groupId> <artifactId>shop-parent</artifactId> <version>1.0.0</version> </parent> <artifactId>shop-web</artifactId> <packaging>war</packaging> </project> ``` ## Key takeaway Changing packaging changes which goals run by default. Picking `pom` for a leaf code module would skip compilation/jar entirely; picking `jar` for a parent aggregator would try to build a useless empty jar.

  • When would you use packaging 'pom'?
    For a parent POM that shares configuration via inheritance, or an aggregator module that lists <modules> to build several children; it produces only the pom, no binary.
  • Does packaging affect more than the file extension?
    Yes — it changes the default plugin goals bound to each lifecycle phase, so it controls the entire build flow for that module.
  • What does maven-plugin packaging add?
    It runs maven-plugin-plugin to generate the plugin descriptor (plugin.xml/META-INF metadata) so Maven can discover the plugin's mojos/goals.

saying these in an interview costs you the question

  • Thinking packaging only sets the output file extension
  • Using jar packaging for a parent aggregator module
  • Believing pom packaging still compiles and jars code

context