-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Context
Following the migration from Apache Commons BeanUtils to Spring BeanUtils (PR #2241, issue #2202), we should evaluate MapStruct as a long-term replacement for bean mapping in PHI-critical areas of the codebase.
Current State
- β Phase 1 Complete: Migrated from Apache Commons BeanUtils to Spring BeanUtils (PR security: migrate from Apache Commons BeanUtils to Spring BeanUtils (Phase 1)Β #2241)
β οΈ Current approach: Spring BeanUtils uses runtime reflection for property copying- π Usage: 41+ files across the codebase use BeanUtils for property copying
Key areas using bean mapping:
- REST API converters (20+ files)
- Demographic data handling (PHI-critical)
- Billing data transformations
- Lab result processing
- Appointment/scheduling data
- Clinical notes and encounter data
Why MapStruct?
MapStruct is an annotation-based code generator that provides compile-time bean mapping with several advantages over runtime reflection:
Security Benefits
- β Zero reflection = no classloader manipulation attacks possible (CVE-2014-0114, CVE-2019-10086 class)
- β Compile-time validation = catches mapping errors before runtime
- β Type-safe = prevents accidental data leaks between incompatible types
- β No security patches needed = generated code has no runtime dependencies
Performance Benefits
- β Faster execution = plain method calls instead of reflection
- β Better JIT optimization = compiler can inline and optimize generated code
- β Lower memory overhead = no reflection metadata caching
Development Benefits
- β IDE autocomplete = mappers are normal Java interfaces
- β Compile-time errors = catches mismatched types immediately
- β Explicit mappings = clear documentation of data transformations
- β Custom conversion logic = easy to add PHI sanitization, validation, etc.
Evaluation Goals
This issue tracks the evaluation of MapStruct to determine:
-
Feasibility Assessment
- Analyze compatibility with Spring Framework 5.3.39
- Test integration with existing Struts2 actions
- Evaluate impact on build times (annotation processing)
- Assess learning curve for development team
-
Priority Area Identification
- Identify highest-value migration targets:
- REST API converters (already abstracted, easy wins)
- Demographic data (PHI-critical, highest security priority)
- Billing transformations (performance-sensitive)
- Lab result processing (high volume)
- Estimate migration effort for each area
- Identify highest-value migration targets:
-
Proof of Concept
- Create sample mapper for REST converter (e.g., TicklerMapper)
- Benchmark performance vs Spring BeanUtils
- Test compile-time validation with intentional errors
- Evaluate generated code quality
-
Integration Strategy
- Document integration with Spring dependency injection
- Define coding standards for mapper interfaces
- Create templates for common patterns (entity β DTO, partial updates, etc.)
- Plan gradual adoption approach (coexist with Spring BeanUtils)
-
Risk Assessment
- Identify potential breaking changes
- Evaluate impact on existing tests
- Document rollback strategy if issues arise
- Consider team training requirements
Example Implementation
Before (Spring BeanUtils - runtime reflection):
@RestController
public class TicklerConverter {
public TicklerLinkTo1 getAsTransferObject(TicklerLink entity) {
TicklerLinkTo1 dto = new TicklerLinkTo1();
BeanUtils.copyProperties(entity, dto); // Runtime reflection
return dto;
}
}After (MapStruct - compile-time generation):
@Mapper(componentModel = "spring")
public interface TicklerMapper {
TicklerLinkTo1 toDto(TicklerLink entity);
TicklerLink toEntity(TicklerLinkTo1 dto);
@Mapping(target = "id", ignore = true)
void updateEntity(@MappingTarget TicklerLink target, TicklerLinkTo1 source);
}
@RestController
public class TicklerConverter {
@Autowired
private TicklerMapper ticklerMapper;
public TicklerLinkTo1 getAsTransferObject(TicklerLink entity) {
return ticklerMapper.toDto(entity); // Type-safe, no reflection
}
}Success Criteria
This evaluation should result in:
- Decision document: Adopt MapStruct fully, partially, or not at all
- If adopted: Migration plan with phased rollout strategy
- If adopted: Developer documentation and code templates
- Performance benchmarks comparing MapStruct vs Spring BeanUtils
- Security analysis confirming elimination of reflection-based risks
Priority
Medium - This is a long-term improvement for security and performance. Spring BeanUtils (Phase 1) already eliminated the CVE exposure, so this is about incremental improvement rather than urgent remediation.
Dependencies
Proposed dependency:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.6.3</version>
<scope>provided</scope>
</dependency>Related
- Issue security: investigate commons-beanutils CVE exposure and mitigation strategyΒ #2202 - commons-beanutils CVE investigation
- PR security: migrate from Apache Commons BeanUtils to Spring BeanUtils (Phase 1)Β #2241 - Phase 1 migration to Spring BeanUtils
- Issue Investigate refactoring out commons-digester3 dependencyΒ #2196 - Refactor out commons-digester3
Resources
Note: This issue is for evaluation only. Implementation would be tracked in separate issues for each migration area if we decide to proceed.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status