`), which takes precedence over `-A`
2. **Verify processor is running**: Ensure annotation processor is configured correctly
3. **Check IDE configuration**: Some IDEs need special configuration for compiler options
4. **Clean and rebuild**: Run `mvn clean compile` to ensure fresh build
diff --git a/docs/DEBUG_LOGGING.md b/docs/DEBUG_LOGGING.md
index c4023aeb..6ceec929 100644
--- a/docs/DEBUG_LOGGING.md
+++ b/docs/DEBUG_LOGGING.md
@@ -11,7 +11,9 @@ The Simple Builders annotation processor supports conditional debug logging that
## Enabling Debug Logging
-Debug logging uses `Diagnostic.Kind.OTHER` but is only activated when explicitly enabled via the compiler argument `-Averbose=true`.
+Debug logging uses `Diagnostic.Kind.OTHER` but is only activated when explicitly enabled via the compiler argument `-Averbose=true` or the Maven system property `-Dsimplebuilder.verbose=true`.
+
+When Maven runs javac in-process, `mvn clean compile -Dsimplebuilder.verbose=true` works without an `-Averbose=${simplebuilder.verbose}` mapping in `pom.xml`, and the `-D` value overrides any `-A` mapping from the build file. Gradle also supports `-Dsimplebuilder.verbose=true` (or `systemProp.simplebuilder.verbose=true` in `gradle.properties`) with in-process compilation; use the `-A` mapping for forked compilation and IDE builds. Gradle does not track the property as a task input, so run `clean` or `--rerun-tasks` after changing it.
### Option 1: Via Maven Property (Recommended)
diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/CompilerArgumentsReader.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/CompilerArgumentsReader.java
index 5edf99fa..a34ef3cf 100644
--- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/CompilerArgumentsReader.java
+++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/CompilerArgumentsReader.java
@@ -52,17 +52,25 @@ public CompilerArgumentsReader(ProcessingEnvironment processingEnv) {
/**
* Reads the value of a compiler argument.
*
- * The method looks up the compiler argument using both the full compiler argument name (with
- * prefix) and the simple option name (without prefix) for backward compatibility.
+ *
The method checks the prefixed JVM system property first, then the prefixed compiler
+ * argument, and finally the bare option name for backward compatibility. The system property wins
+ * so a command-line {@code -D} can override options configured in the build file. The system
+ * property is available when the build tool runs javac in-process and is not available with
+ * {@code true }.
*
* @param argument the compiler argument enum to read
* @return the value of the compiler argument, or null if not set
*/
public String readValue(CompilerArgumentsEnum argument) {
- // Try with full compiler argument name first (e.g., "simplebuilder.verbose")
- String value = processingEnv.getOptions().get(argument.getCompilerArgument());
+ // Try the -D JVM system property first (e.g., -Dsimplebuilder.verbose)
+ String value = System.getProperty(argument.getCompilerArgument());
- // Fall back to simple option name for backward compatibility (e.g., "verbose")
+ // Then the -A compiler argument (e.g., -Asimplebuilder.verbose)
+ if (value == null) {
+ value = processingEnv.getOptions().get(argument.getCompilerArgument());
+ }
+
+ // Finally the bare option name for backward compatibility (e.g., -Averbose)
if (value == null) {
value = processingEnv.getOptions().get(argument.getOptionName());
}
@@ -129,11 +137,18 @@ public AccessModifier readAccessModifier(CompilerArgumentsEnum argument) {
*
This method reads all configuration options from compiler arguments like:
*
*
- * {@code -Asimplebuilder.generateFieldSupplier=true}
+ * {@code -Dsimplebuilder.generateFieldSupplier=true} (JVM system property, highest
+ * precedence)
+ * {@code -Asimplebuilder.generateFieldSupplier=true} (compiler argument)
+ * {@code -AgenerateFieldSupplier=true} (bare option name, backward compatibility)
* {@code -Asimplebuilder.builderAccess=public}
* etc.
*
*
+ * Options set via {@code @SimpleBuilder.Options} on the annotated type are not handled here;
+ * they are read by {@link BuilderConfigurationReader} and merged on top of this global
+ * configuration.
+ *
*
All values default to UNSET or DEFAULT if not specified in compiler arguments.
*
*
Adding a new option: every option in {@link CompilerArgumentsEnum} that represents a
diff --git a/processor/src/test/java/org/javahelpers/simple/builders/processor/CompilerArgumentsReaderTest.java b/processor/src/test/java/org/javahelpers/simple/builders/processor/CompilerArgumentsReaderTest.java
index c8b4c11f..d96c25fa 100644
--- a/processor/src/test/java/org/javahelpers/simple/builders/processor/CompilerArgumentsReaderTest.java
+++ b/processor/src/test/java/org/javahelpers/simple/builders/processor/CompilerArgumentsReaderTest.java
@@ -89,6 +89,47 @@ void readValue_OnlySimpleNameSet_UsesSimpleName() {
"Should fall back to simple option name");
}
+ @Test
+ void readValue_SystemPropertySet_FallsBackToSystemProperty() {
+ System.setProperty("simplebuilder.verbose", "true");
+ try {
+ ProcessingEnvironment env = ProcessingEnvironmentStub.createEmpty();
+ CompilerArgumentsReader reader = new CompilerArgumentsReader(env);
+
+ assertEquals("true", reader.readValue(CompilerArgumentsEnum.VERBOSE));
+ assertTrue(reader.readBooleanValue(CompilerArgumentsEnum.VERBOSE));
+ } finally {
+ System.clearProperty("simplebuilder.verbose");
+ }
+ }
+
+ @Test
+ void readValue_CompilerArgAndSystemPropertySet_PrefersSystemProperty() {
+ System.setProperty("simplebuilder.verbose", "true");
+ try {
+ ProcessingEnvironment env =
+ ProcessingEnvironmentStub.builder().put("simplebuilder.verbose", "false").build();
+ CompilerArgumentsReader reader = new CompilerArgumentsReader(env);
+
+ assertEquals("true", reader.readValue(CompilerArgumentsEnum.VERBOSE));
+ } finally {
+ System.clearProperty("simplebuilder.verbose");
+ }
+ }
+
+ @Test
+ void readValue_BareNameSystemProperty_Ignored() {
+ System.setProperty("verbose", "true");
+ try {
+ ProcessingEnvironment env = ProcessingEnvironmentStub.createEmpty();
+ CompilerArgumentsReader reader = new CompilerArgumentsReader(env);
+
+ assertNull(reader.readValue(CompilerArgumentsEnum.VERBOSE));
+ } finally {
+ System.clearProperty("verbose");
+ }
+ }
+
/** Test: readBooleanValue returns false when value is null. */
@Test
void readBooleanValue_NullValue_ReturnsFalse() {