How does the <packaging> element change the default goal-to-phase bindings? Contrast jar, war, pom, and maven-plugin.
answer
- packaging = lifecycle mapping
- jar -> jar:jar
- war -> war:war
- pom -> only install/deploy
- maven-plugin -> plugin:descriptor
basics
~10 sThe <packaging> value selects which plugin goals are bound by default. jar binds jar:jar at package; war binds war:war; pom binds almost nothing (only install/deploy); maven-plugin adds plugin descriptor goals.
solid answer
~40 s`<packaging>` is more than a file extension — it maps to a named lifecycle-mapping that defines the default goal-to-phase bindings for the `default` lifecycle. For `jar`: package binds `jar:jar`, plus compiler/surefire/resources earlier. For `war`: package binds `war:war` (which assembles the web archive). For `pom`: there is essentially no compile/test/package work — only `install:install` and `deploy:deploy` are bound, which suits aggregator/parent POMs. For `maven-plugin`: it behaves like jar but additionally binds `plugin:descriptor` (generate-resources) and `plugin:addPluginArtifactMetadata` so the plugin metadata is built. Because the binding set is driven by packaging, changing packaging silently changes what `mvn package` produces, which is a common source of 'why is there no artifact?' confusion (usually a `pom` packaging where someone expected a jar).
code
xml · 6 lines<!-- Parent / aggregator POM: pom packaging means no compile/jar binding -->
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>web</module>
</modules>go deeper
Know jar is the default and produces a jar; war produces a war.
Map each packaging to its distinctive package-phase goal and know pom skips compile/test.
Diagnose 'no artifact produced' issues from wrong packaging and choose pom for aggregators deliberately.
Govern packaging conventions across a large reactor and understand custom lifecycle mappings via extensions/components.xml.
## Packaging selects a lifecycle mapping The `<packaging>` element (default `jar`) names a **lifecycle mapping** — a built-in table of which goals bind to which phases of the `default` lifecycle. Each packaging ships its own table. ## jar (the default) ``` process-resources -> resources:resources compile -> compiler:compile process-test-resources -> resources:testResources test-compile -> compiler:testCompile test -> surefire:test package -> jar:jar install -> install:install deploy -> deploy:deploy ``` ## war Identical to jar except `package` binds **`war:war`** instead of `jar:jar`. The war goal assembles `src/main/webapp`, classes, and dependency JARs into a `.war`. ## pom A POM-packaged module produces no compiled artifact. Only: ``` package -> site:attach-descriptor (in newer Maven) install -> install:install deploy -> deploy:deploy ``` There is **no compile, test, or jar binding**. This is correct for parent POMs and aggregator (multi-module) POMs that only declare `<modules>`. A frequent mistake: leaving `<packaging>pom</packaging>` on a module that has real `src/main/java` and wondering why no jar appears. ## maven-plugin Like jar, but adds plugin-specific goals: ``` generate-resources -> plugin:descriptor (writes META-INF/maven/plugin.xml) package -> jar:jar + plugin:addPluginArtifactMetadata ``` This ensures the Mojo descriptor that Maven needs to invoke the plugin is generated. ## Why it matters ```xml <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>web-app</artifactId> <version>1.0.0</version> <packaging>war</packaging> <!-- swap to jar and package binds jar:jar instead --> </project> ``` Changing one word reroutes the entire `package` step. Always confirm packaging matches the intended artifact, and use `pom` only for parents/aggregators.
- Why does a `pom`-packaged module skip compile and test?Its lifecycle mapping binds no compiler or surefire goals; pom modules are meant to aggregate or be inherited, not to produce a code artifact.
- What extra goal does `maven-plugin` packaging bind compared to `jar`?plugin:descriptor (and plugin:addPluginArtifactMetadata) to generate the plugin.xml Mojo descriptor.
saying these in an interview costs you the question
- Believing packaging only sets the output file extension
- Expecting a jar from a `pom`-packaged module
- Thinking war packaging still binds jar:jar at package