-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Expected behavior
Summary
The processor test suite (mapstruct/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time) contains tests that fail intermittently due to non-deterministic behavior in the code generation process. These issues were discovered using the NonDex tool. The root causes are related to iterating over collections with no guaranteed order, such as method lists from the compiler and HashSets.
Root Cause Analysis
Unstable Field Order: The MapperRetrievalProcessor iterates through each ExecutableElement from elementUtils.getAllEnclosedExecutableElements() to add method into List. However, getAllEnclosedExecutableElements is implemented using a HashSet which the order is not guaranteed to be stable. The processor then discovers and creates the required DateTimeFormatter fields in this unstable order, leading to a non-deterministic layout in the final generated file.
Potential Fix
- I will open a pull request for modification of the comparing logic in JavaFileAssert.java by sorting the fields in both files to make the comparison more robust.
- A more fundamental and valuable alternative would be to make the code generation itself predictable. It can be fixed by sorting the list of methods right after they are retrieved from the compiler, before any processing happens.
Actual behavior
Unstable Field Order in Generated Mappers
The order of helper fields (specifically DateTimeFormatter fields) in the generated mapper implementation classes is not consistent across builds.
-
Run 1 Output:
private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 = ... private final DateTimeFormatter dateTimeFormatter_HH_mm_168697690 = ...
-
Internal Field Order (from debug print):
----- Fields Order ----- SupportingField@2e6109be SupportingField@12251427 SupportingField@aa6b84f3 SupportingField@3e07ade -
Run 2 Output:
private final DateTimeFormatter dateTimeFormatter_HH_mm_168697690 = ... private final DateTimeFormatter dateTimeFormatter_dd_MM_yyyy_HH_mm_12071769242 = ...
-
Internal Field Order (from debug print):
----- Fields Order ----- SupportingField@12251427 SupportingField@2e6109be SupportingField@3e07ade SupportingField@aa6b84f3
Steps to reproduce the problem
This non-deterministic behavior can be reliably reproduced by running the NonDex Maven plugin on the processor module.
- Navigate to the root of the MapStruct project.
- Run the following command:
mvn -pl processor edu.illinois:nondex-maven-plugin:2.2.1:nondex
- Observe that the build will fail intermittently on tests like
Java8CustomPatternDateTimeFormatterGeneratedTesteach
MapStruct Version
MapStruct 1.7.0-SNAPSHOT