Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions DEBUG_LOGGING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Debug Logging for Simple Builders

The Simple Builders annotation processor supports conditional debug logging that provides detailed information about the builder generation process.

## Logging Levels

- **INFO**: Always visible - Shows success messages for each builder generated
- **WARNING**: Always visible - Shows when a builder cannot be generated (e.g., wrong annotation target, generation errors). Other builders will continue to be generated.
- **ERROR**: Always visible - Shows fatal configuration errors (e.g., unsupported JDK version). Stops compilation completely.
- **DEBUG**: Conditional - Shows detailed tracing of field discovery, method analysis, and code generation steps

## Enabling Debug Logging

Debug logging uses `Diagnostic.Kind.OTHER` but is only activated when explicitly enabled via the compiler argument `-Averbose=true`.

### Option 1: Via Maven Property (Recommended)

Add a property in your `pom.xml`:

```xml
<properties>
<simplebuilder.verbose>false</simplebuilder.verbose>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<compilerArgs>
<arg>-Averbose=${simplebuilder.verbose}</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
```

Then enable debug logging from command line:
```bash
mvn clean compile -Dsimplebuilder.verbose=true
```

### Option 2: Static Configuration

Set it permanently in your `pom.xml`:

```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<compilerArgs>
<arg>-Averbose=true</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
```

## Example Debug Output

When debug logging is enabled, you'll see detailed output with visual separators:

```
[INFO] [DEBUG] ===============================
[INFO] simple-builders: PROCESSING ROUND START
[INFO] [DEBUG] ===============================
[INFO] [DEBUG] simple-builders: Processing round started. Found 3 annotated elements.
[INFO] [DEBUG] ------------------------------------
[INFO] [DEBUG] simple-builders: Processing element: PersonDto
[INFO] [DEBUG] ------------------------------------
[INFO] [DEBUG] Extracting builder definition from: org.example.PersonDto
[INFO] [DEBUG] Builder will be generated as: org.example.PersonDtoBuilder
[INFO] [DEBUG] Analyzing method: setName with 1 parameter(s)
[INFO] [DEBUG] -> Adding field: name (type: java.lang.String)
[INFO] [DEBUG] Analyzing method: setAge with 1 parameter(s)
[INFO] [DEBUG] -> Adding field: age (type: int)
[INFO] [DEBUG] Processed 2 possible setters: added 2 fields, skipped 0
[INFO] [DEBUG] Starting code generation for builder: PersonDtoBuilder
[INFO] [DEBUG] Generating 0 constructor fields and 2 setter fields
[INFO] [DEBUG] Generated 2 methods for field: name
[INFO] [DEBUG] Generated 2 methods for field: age
[INFO] [DEBUG] Writing builder class to file: org.example.PersonDtoBuilder
[INFO] [DEBUG] Successfully generated builder: PersonDtoBuilder
[INFO] simple-builders: Successfully generated builder for: PersonDto
```

**Note**: Debug messages are prefixed with `[DEBUG]` and use `Diagnostic.Kind.OTHER` which appears as `[INFO]` in Maven output.

## Normal Output (Without Debug)

Without debug logging enabled, you only see the INFO-level messages:

```
[INFO] simple-builders: Successfully generated builder for: PersonDto
[INFO] simple-builders: Successfully generated builder for: OrderDto
[INFO] simple-builders: Successfully generated builder for: CustomerDto
```

## Troubleshooting

If debug logging is not appearing:

1. Verify the compiler plugin configuration includes the debug or verbose argument
2. Check that you're using Maven 3.6+
3. Ensure the annotation processor is actually running (check for generated files in `target/generated-sources/annotations`)
4. Try with `-X` flag to see all Maven debug output and verify the compiler arguments are being passed
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
- [Usage](#usage)
- [Basic Usage](#basic-usage)
- [Collections and Nested Objects](#collections-and-nested-objects)
- [Debug Logging](#debug-logging)
- [Building from Source](#building-from-source)
- [Contributing](#contributing)
- [License](#license)
- [Links](#links)

## What is Simple Builders?

Expand Down Expand Up @@ -169,6 +171,12 @@ Project project = ProjectBuilder.create()
.build();
```

### Debug Logging

Simple Builders supports detailed debug logging to trace the builder generation process. Enable it with the `-Averbose=true` compiler argument for detailed insights into field discovery, method analysis, and code generation.

For complete documentation on enabling and using debug logging, see [DEBUG_LOGGING.md](DEBUG_LOGGING.md).

## Building from Source

1. Clone the repository:
Expand Down Expand Up @@ -210,7 +218,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
* [Downloads](https://github.com/java-helpers/simple-builders/releases)
* [Issue tracker](https://github.com/java-helpers/simple-builders/issues)
* [CI build](https://github.com/java-helpers/simple-builders/actions/)

## Licensing

SimpleBuilders is licensed under the MIT License; you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.opensource.org/licenses/mit-license.php.
6 changes: 6 additions & 0 deletions example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.release>${java.version}</maven.compiler.release>

<!-- Set to true to enable debug logging in annotation processor -->
<simplebuilder.verbose>false</simplebuilder.verbose>
</properties>

<dependencies>
Expand Down Expand Up @@ -77,6 +80,9 @@
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Averbose=${simplebuilder.verbose}</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
package org.javahelpers.simple.builders.example;

import java.util.Set;
import java.util.function.Supplier;

import org.javahelpers.simple.builders.core.annotations.IgnoreInBuilder;
import org.javahelpers.simple.builders.core.annotations.SimpleBuilder;

@SimpleBuilder
Expand All @@ -40,6 +43,11 @@ public void setName(String name) {
this.name = name;
}

@IgnoreInBuilder
public void setName(Supplier<String> nameSupplier) {
this.name = nameSupplier.get();
}

public Set<SponsorDto> getSponsoren() {
return sponsoren;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@

@SimpleBuilder
public class PersonDto {
private String name;
private final String name;
private int groesse;
private List<String> nickNames;
private java.time.LocalDate birthdate;
private MannschaftDto mannschaft;

public String getName() {
return name;
public PersonDto(String name) {
this.name = name;
}

public void setName(String name) {
this.name = name;
public String getName() {
return name;
}

public int getGroesse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@
@Generated("org.javahelpers.simple.builders.processor")
@BuilderImplementation(forClass = PersonDto.class)
public class PersonDtoBuilder {
private final PersonDto instance = new PersonDto();
private final PersonDto instance = new PersonDto("test");

public static PersonDtoBuilder create() {
return new PersonDtoBuilder();
}

public PersonDtoBuilder name(String name) {
instance.setName(name);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
Expand All @@ -49,6 +50,7 @@
*/
@AutoService(Processor.class)
@SupportedAnnotationTypes("org.javahelpers.simple.builders.core.annotations.SimpleBuilder")
@SupportedOptions("verbose")
public class BuilderProcessor extends AbstractProcessor {
private ProcessingContext context;
private JavaCodeGenerator codeGenerator;
Expand All @@ -57,20 +59,17 @@ public class BuilderProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
ProcessingLogger logger = new ProcessingLogger(processingEnv.getMessager());
ProcessingLogger logger = new ProcessingLogger(processingEnv);
this.context =
new ProcessingContext(
processingEnv.getElementUtils(), processingEnv.getTypeUtils(), logger);
this.codeGenerator = new JavaCodeGenerator(processingEnv.getFiler());

// Enforce minimum Java version (17+) for the processor
this.codeGenerator = new JavaCodeGenerator(processingEnv.getFiler(), logger);
SourceVersion current = processingEnv.getSourceVersion();
this.supportedJdk = isAtLeastJava17(current);
if (!this.supportedJdk) {
context.error(
"simple-builders requires Java 17 or higher for annotation processing. Detected: "
+ current
+ ". Please upgrade to JDK 17+ or disable the processor.");
"simple-builders requires Java 17 or higher for annotation processing. Detected: '%s'. Please upgrade to JDK 17+ or disable the processor.",
current);
}
}

Expand All @@ -89,13 +88,30 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
if (simpleBuilderAnnotation == null) {
context.error(
"Annotation org.javahelpers.simple.builders.core.annotations.SimpleBuilder is not on classpath. So nothing to do here.");
return false;
}
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(simpleBuilderAnnotation)) {

Set<? extends Element> annotatedElements =
roundEnv.getElementsAnnotatedWith(simpleBuilderAnnotation);
context.debug("===============================");
context.info("simple-builders: PROCESSING ROUND START");
context.debug("===============================");
context.debug(
"simple-builders: Processing round started. Found %d annotated elements.",
annotatedElements.size());

for (Element annotatedElement : annotatedElements) {
try {
context.debug("------------------------------------");
context.debug("simple-builders: Processing element: %s", annotatedElement.getSimpleName());
context.debug("------------------------------------");
process(annotatedElement);
context.info(
"simple-builders: Successfully generated builder for: %s",
annotatedElement.getSimpleName());
} catch (BuilderException ex) {
context.error(annotatedElement, "Failed to process annotated element: " + ex.getMessage());
// All builder generation failures are warnings to allow other builders to be generated
context.warning(
annotatedElement, "simple-builders: Failed to generate builder - %s", ex.getMessage());
}
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ public void addFieldInConstructor(FieldDto field) {
fieldsInConstructor.add(field);
}

/** Adds multiple field definitions to be provided via the DTO constructor. */
public void addAllFieldsInConstructor(List<FieldDto> fields) {
fieldsInConstructor.addAll(fields);
}

/** Adds multiple field definitions to the builder. */
public void addAllFields(List<FieldDto> fields) {
this.fields.addAll(fields);
}

/**
* Getting all definied fields in builder definition.
*
Expand Down
Loading
Loading