How do you expose configuration to a Mojo, and how does a user set those values from the POM or command line?
answer
- @Parameter field name = XML element
- property = -D override
- defaultValue = ${expression}
- required / readonly
- ${project} via readonly param, services via @Component
basics
~10 sYou annotate fields with @Parameter. Users set them in the plugin's <configuration> block in the POM using the field name as the XML element, or via -D using the parameter's property name.
solid answer
~40 sEach configurable input is a field annotated `@Parameter`. The field name becomes the XML element inside the plugin's `<configuration>` block, so a field `outputDirectory` maps to `<outputDirectory>...</outputDirectory>`. Optional attributes: `defaultValue` (supports `${...}` expressions like `${project.build.directory}`), `property` (lets users override via `-Dthat.property=...`), `required = true` (build fails if unset), `readonly = true` (POM can't override — used for injected objects). Maven supports rich types: `String`, primitives, `File`, `List`/`Map`, arrays, even nested POJOs configured as nested XML. Injected Maven components like the current project come via `@Parameter(defaultValue = "${project}", readonly = true) MavenProject project`. For services like the repository system you instead use `@Component` / constructor injection. Precedence: explicit `-D` property > POM `<configuration>` > `defaultValue`.
code
xml · 12 lines<plugin>
<groupId>com.example</groupId>
<artifactId>greeting-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<outputDirectory>${project.build.directory}/hello</outputDirectory>
<names>
<name>Ada</name>
<name>Linus</name>
</names>
</configuration>
</plugin>go deeper
Knows @Parameter exposes config and the field name is the XML element.
Uses defaultValue expressions, property for -D, required/readonly, and collection mapping correctly.
Designs parameters as a stable API, picks proper injection for model vs. component, reasons about override precedence.
Sets standards for parameter naming/defaults across an org's plugins so they're predictable and backward-compatible.
## Parameters = the plugin's public API A Mojo's `@Parameter` fields are its configuration surface — treat them like a public API: stable names, sensible defaults, clear required/optional. ## Declaring a parameter ```java @Parameter(property = "greet.outputDir", defaultValue = "${project.build.directory}/greet", required = true) private File outputDirectory; ``` - **Field name → XML element.** The user configures `<outputDirectory>` because the field is `outputDirectory`. (You can override with `@Parameter(name = "...")` but matching the field is conventional.) - **`defaultValue`** is an *expression* evaluated against the project/session: `${project.version}`, `${project.build.directory}` (target dir), `${basedir}`, `${session}`. If the user sets nothing, this is used. - **`property`** binds a system/user property so users can do `-Dgreet.outputDir=/tmp/x`. - **`required = true`** makes the build fail fast if the value resolves to null. - **`readonly = true`** forbids POM overrides — use it for injected model objects you don't want users replacing. ## Configuring from the consumer POM ```xml <plugin> <groupId>com.example</groupId> <artifactId>greeting-maven-plugin</artifactId> <version>1.0.0</version> <configuration> <outputDirectory>${project.build.directory}/hello</outputDirectory> <names> <name>Ada</name> <name>Linus</name> </names> </configuration> </plugin> ``` Collections map element-by-element; a `List<String> names` field is filled from `<names><name>...</name></names>` (singular inner element). ## Precedence 1. Command-line `-D<property>` (if the parameter declares a `property`). 2. POM `<configuration>` value. 3. `defaultValue`. ## Injecting Maven objects vs. components - **Model objects** (read-only data) via `@Parameter(defaultValue = "${...}", readonly = true)`: `MavenProject` (`${project}`), `MavenSession` (`${session}`), `MojoExecution`. - **Components / services** (behavior) via `@Component` field or constructor injection (e.g. `RepositorySystem`, `BuildPluginManager`). ## Common expressions `${project}`, `${project.basedir}`, `${project.build.directory}`, `${project.build.outputDirectory}`, `${session}`, `${settings}`, `${plugin}`.
- What is the precedence between -D, POM <configuration>, and defaultValue?Command-line -D (when the parameter declares a 'property') wins, then the POM <configuration> value, then defaultValue if nothing else is set.
- How do you inject the current MavenProject into a Mojo?Add a field `@Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project;`. Services like RepositorySystem use @Component / constructor injection instead.
saying these in an interview costs you the question
- Thinking you must write parsing code to read POM config — Maven injects it
- Confusing 'property' (the -D key) with the field/element name
- Believing readonly parameters can still be set in the POM
- Injecting a behavioral component via @Parameter ${...} instead of @Component