Skip to content

Comments

implement "strictness modes" for bean validation#30

Merged
goekay merged 1 commit intomainfrom
impl-various-strictness-modes
Feb 19, 2026
Merged

implement "strictness modes" for bean validation#30
goekay merged 1 commit intomainfrom
impl-various-strictness-modes

Conversation

@goekay
Copy link
Member

@goekay goekay commented Feb 19, 2026

motivation: throwing exception and interrupting operation may not always be desirable.

@qodo-free-for-open-source-projects

Review Summary by Qodo

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Introduce StrictnessMode enum with LogWarning and ThrowError options
• Replace boolean flags with strictness mode parameters in validation modules
• Implement conditional validation behavior based on strictness mode setting
• Add SLF4J dependency and logging for constraint violation warnings

Grey Divider

File Changes

1. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/StrictnessMode.java ✨ Enhancement +6/-0

Create StrictnessMode enum for validation behavior

• New enum file defining two strictness modes for bean validation
• LogWarning mode logs violations without throwing exceptions
• ThrowError mode throws ConstraintViolationException on violations

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/StrictnessMode.java


2. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerModifierWithValidation.java ✨ Enhancement +2/-1

Add strictness mode parameter to deserializer modifier

• Add strictnessMode field to store validation behavior configuration
• Pass strictness mode to BeanDeserializerWithValidation constructor

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerModifierWithValidation.java


3. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java ✨ Enhancement +15/-4

Implement strictness mode handling in deserializer

• Add @Slf4j annotation for logging support
• Add strictnessMode field and constructor parameter
• Refactor validation logic to use switch statement for strictness mode handling
• Log warnings instead of throwing exceptions when in LogWarning mode

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java


View more (4)
4. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java ✨ Enhancement +2/-1

Add strictness mode parameter to serializer modifier

• Add strictnessMode field to store validation behavior configuration
• Pass strictness mode to BeanSerializerWithValidation constructor

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java


5. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java ✨ Enhancement +16/-4

Implement strictness mode handling in serializer

• Add @Slf4j annotation for logging support
• Add strictnessMode field and constructor parameter
• Extract validation logic into separate validate() method
• Implement switch statement for strictness mode-based error handling
• Support logging warnings or throwing exceptions based on mode

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java


6. ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java ✨ Enhancement +26/-8

Refactor module to use strictness mode parameters

• Add @Builder annotation for fluent module construction
• Replace boolean forReading and forWriting parameters with readingMode and writingMode
• Add null validation to ensure at least one mode is configured
• Update factory methods to use builder pattern with StrictnessMode.ThrowError as default

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java


7. pom.xml Dependencies +6/-0

Add SLF4J API dependency

• Add SLF4J API dependency version 2.0.17 with compile scope
• Enables logging functionality for validation warning messages

pom.xml


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (4) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Breaking ctor signatures 🐞 Bug ⛯ Reliability
Description
Public validation modifier classes now require a StrictnessMode parameter, which is a source/binary
incompatible change for any consumers constructing them directly. This can break downstream builds
without a clear migration path.
Code

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java[R16-23]

+    private final StrictnessMode strictnessMode;

    @Override
    public ValueSerializer<?> modifySerializer(SerializationConfig config,
                                               BeanDescription.Supplier beanDesc,
                                               ValueSerializer<?> serializer) {
        if (serializer instanceof BeanSerializerBase) {
-            return new BeanSerializerWithValidation((BeanSerializerBase) serializer, validator);
+            return new BeanSerializerWithValidation((BeanSerializerBase) serializer, validator, strictnessMode);
Evidence
These classes are public and use Lombok @RequiredArgsConstructor, so adding a new final field
changes the generated public constructor signature. The module now constructs them with the new
(Validator, StrictnessMode) signature, confirming the API changed from the prior (Validator)-only
constructor.

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java[12-24]
ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerModifierWithValidation.java[15-27]
ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java[24-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Public classes `BeanSerializerModifierWithValidation` / `BeanDeserializerModifierWithValidation` (and related wrappers) changed constructor signatures due to adding `strictnessMode` as a new final field under Lombok `@RequiredArgsConstructor`. This is a breaking change for downstream consumers who instantiate these classes directly.

### Issue Context
The library already provides `BeanValidationModule` factories for typical use, so you can either (a) keep public constructors stable via overloads/defaults, or (b) reduce surface area by making internal classes non-public and exposing stable factory APIs.

### Fix Focus Areas
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java[12-27]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerModifierWithValidation.java[15-30]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java[14-39]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java[17-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Builder throws runtime NPE 🐞 Bug ✓ Correctness
Description
BeanValidationModule’s public builder can build an invalid configuration (both modes unset) that
fails at runtime with a NullPointerException. This is avoidable and should fail with a clearer
contract and exception type.
Code

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java[R14-18]

+    @Builder
+    private BeanValidationModule(Validator validator, StrictnessMode readingMode, StrictnessMode writingMode) {
+        if (readingMode == null && writingMode == null) {
+            throw new NullPointerException("readingMode and writingMode are null");
+        }
Evidence
The module constructor explicitly throws a NullPointerException when both modes are null, and Lombok
@Builder on the constructor generates a public builder() method, making it possible for consumers to
hit this at runtime by not setting either mode.

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java[14-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`BeanValidationModule.builder()` allows creating a module with both `readingMode` and `writingMode` unset, which currently fails at runtime via `NullPointerException`. This is confusing for callers and makes configuration errors harder to diagnose.

### Issue Context
The existing static factories (`forReading`, `forWriting`, `forReadingAndWriting`) are safe, but the generated builder is public and can be used directly.

### Fix Focus Areas
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanValidationModule.java[14-31]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Warn mode logs stacktrace 🐞 Bug ➹ Performance
Description
In LogWarning mode, validation failures are logged with a full exception stacktrace, and an
exception is constructed solely for logging. This can create significant log noise and overhead in
high-volume invalid-input scenarios.
Code

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java[R34-38]

+        var exception = new ConstraintViolationException(violations);
+        switch (strictnessMode) {
+            case LogWarning -> log.warn("There are constraint violations", exception);
+            case ThrowError -> throw exception;
+        }
Evidence
Both serializer and deserializer create a ConstraintViolationException and pass it to log.warn,
which emits a full stacktrace and incurs throwable stacktrace construction cost even though the
operation continues in LogWarning mode.

ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java[28-38]
ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java[56-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
In `LogWarning` strictness mode, validation failures currently log a full stacktrace and allocate a `ConstraintViolationException` purely for logging. This adds CPU overhead and can spam logs if invalid payloads are common.

### Issue Context
`LogWarning` is explicitly intended to *not* interrupt operation; logging stack traces for an expected control path is typically too noisy.

### Fix Focus Areas
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java[28-38]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java[56-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

4. slf4j added in parent 🐞 Bug ⛯ Reliability
Description
slf4j-api is added as a compile dependency in the parent POM, which makes all modules (including
ocpp-custom) inherit it even though only ocpp-jaxb currently uses @Slf4j. This unnecessarily
broadens the transitive dependency surface for artifacts that don’t need logging.
Code

pom.xml[R133-138]

+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>2.0.17</version>
+            <scope>compile</scope>
+        </dependency>
Evidence
The parent POM defines slf4j-api with compile scope, and ocpp-custom inherits from that parent while
declaring no logging usage/dependencies of its own. This means consumers of ocpp-custom will also
get slf4j-api transitively.

pom.xml[122-138]
ocpp-custom/pom.xml[5-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`slf4j-api` is introduced at the parent POM level, causing *all* modules to inherit it even if they do not use SLF4J.

### Issue Context
Only the validation (de)serializer classes in `ocpp-jaxb` currently use Lombok `@Slf4j`.

### Fix Focus Areas
- pom.xml[122-139]
- ocpp-jaxb/pom.xml[1-120]
- ocpp-custom/pom.xml[1-22]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +16 to +23
private final StrictnessMode strictnessMode;

@Override
public ValueSerializer<?> modifySerializer(SerializationConfig config,
BeanDescription.Supplier beanDesc,
ValueSerializer<?> serializer) {
if (serializer instanceof BeanSerializerBase) {
return new BeanSerializerWithValidation((BeanSerializerBase) serializer, validator);
return new BeanSerializerWithValidation((BeanSerializerBase) serializer, validator, strictnessMode);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Breaking ctor signatures 🐞 Bug ⛯ Reliability

Public validation modifier classes now require a StrictnessMode parameter, which is a source/binary
incompatible change for any consumers constructing them directly. This can break downstream builds
without a clear migration path.
Agent Prompt
### Issue description
Public classes `BeanSerializerModifierWithValidation` / `BeanDeserializerModifierWithValidation` (and related wrappers) changed constructor signatures due to adding `strictnessMode` as a new final field under Lombok `@RequiredArgsConstructor`. This is a breaking change for downstream consumers who instantiate these classes directly.

### Issue Context
The library already provides `BeanValidationModule` factories for typical use, so you can either (a) keep public constructors stable via overloads/defaults, or (b) reduce surface area by making internal classes non-public and exposing stable factory APIs.

### Fix Focus Areas
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerModifierWithValidation.java[12-27]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerModifierWithValidation.java[15-30]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanSerializerWithValidation.java[14-39]
- ocpp-jaxb/src/main/java/de/rwth/idsg/ocpp/jaxb/validation/BeanDeserializerWithValidation.java[17-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@goekay goekay merged commit 46888f9 into main Feb 19, 2026
1 check passed
@goekay goekay deleted the impl-various-strictness-modes branch February 19, 2026 10:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant