What is the difference between plugin-level configuration and execution-scoped configuration, and what does the <inherited> flag do?
answer
- plugin-level = all executions + CLI
- execution-scoped = that execution only
- direct CLI ignores execution config
- <inherited>false> = don't pass to children
- verify per-module with effective-pom -pl
basics
~10 sPlugin-level <configuration> applies to all the plugin's goals/executions and to direct CLI calls; execution-scoped config applies only to that execution. The <inherited>false</inherited> flag stops a plugin or execution from being inherited by child modules.
solid answer
~40 sThere are two places to put `<configuration>`: directly under `<plugin>` (plugin-level) and inside an `<execution>` (execution-scoped). Plugin-level config is the baseline for *every* execution and also applies when you invoke a goal directly from the command line (e.g. `mvn surefire:test`); execution-scoped config applies only to that execution's goals and overrides the plugin-level values for them. Direct CLI invocations do **not** pick up execution-scoped config — a classic gotcha. The `<inherited>` element (a boolean, default `true`) can be set on a `<plugin>` or on an `<execution>` to control whether it propagates to child modules; `<inherited>false</inherited>` keeps it in the current POM only — useful for an aggregator-only step you don't want every child to run.
code
xml · 12 lines<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<inherited>false</inherited>
<executions>
<execution>
<id>aggregator-only</id>
<phase>verify</phase>
<goals><goal>run</goal></goals>
</execution>
</executions>
</plugin>go deeper
Knows config can sit at plugin or execution level.
Understands the override relationship and the CLI-ignores-execution-config gotcha.
Uses <inherited>false</inherited> deliberately and reasons about per-module effective config.
Defines where shared vs local plugin behavior lives across an aggregator hierarchy.
## Two scopes of configuration ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> <!-- (A) plugin-level: baseline for all executions + direct CLI --> <configuration> <argLine>-Xmx256m</argLine> </configuration> <executions> <execution> <id>integration</id> <phase>integration-test</phase> <goals><goal>test</goal></goals> <!-- (B) execution-scoped: only this execution --> <configuration> <argLine>-Xmx1g</argLine> </configuration> </execution> </executions> </plugin> ``` - **(A) Plugin-level** config is the default for every execution AND is used when you run the goal directly from the command line (`mvn surefire:test`). - **(B) Execution-scoped** config applies only to that execution and overrides (A) for its goals. ### The CLI gotcha When you invoke a goal directly (`mvn <plugin>:<goal>`), Maven uses the plugin-level config only — it does **not** apply any execution-scoped config. So config that lives only inside an `<execution>` is invisible to direct CLI runs. If you need the same behavior from the CLI, lift it to plugin-level (or pass `-D` user properties). ## The <inherited> flag Many POM elements support `<inherited>` (boolean, default `true`). On a `<plugin>` or an `<execution>` it controls **whether the declaration is passed down to child modules**: ```xml <plugin> <artifactId>maven-site-plugin</artifactId> <inherited>false</inherited> <!-- only this (aggregator) POM runs it --> ... </plugin> ``` With `<inherited>false</inherited>`, the plugin/execution stays local to the current POM and child modules do not inherit it. This is handy for aggregator-level tasks (reporting, release orchestration) you don't want every leaf module repeating. ## Verifying Use `mvn help:effective-pom -pl <module>` to see, per module, which plugin declarations and config actually survived inheritance and scoping.
- Why might 'mvn surefire:test' from the CLI not honor config you set?Direct CLI goal invocations use only plugin-level <configuration>; they ignore execution-scoped config. Move the config to plugin level or pass -D properties.
- How do you stop child modules from inheriting an aggregator-only plugin?Set <inherited>false</inherited> on the <plugin> (or the specific <execution>); it then applies only to the current POM.
saying these in an interview costs you the question
- Assuming execution-scoped config applies to direct CLI invocations
- Thinking all plugin declarations are always inherited
- Confusing <inherited> with <pluginManagement>