Using java MapStruct with VSCode

Viewed 2944

I'm working with java Mapstruct. Running with gradle bootRun is work properly, but I have some problems with VSCode for debugging and running the unit tests: java.lang.ClassNotFoundException: Cannot find implementation.

information: IDE VSCode, SpringBoot 2.2.2, Java SDK 11, Gradle 6.1.1

build.gradle:

compileJava {
    options.compilerArgs = [
            '-Amapstruct.defaultComponentModel=spring'
    ]
}

dependencies {
    implementation 'org.mapstruct:mapstruct-jdk8:1.3.1.Final'
    implementation 'org.mapstruct:mapstruct-processor:1.3.1.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.3.1.Final'
    testAnnotationProcessor 'org.mapstruct:mapstruct-processor:1.3.1.Final'
}

launch.json for debugging in VSCode:

 {
            "type": "java",
            "name": "Debug (Launch)-DemoApplication<demo>",
            "request": "launch",
            "mainClass": "com.api.demo.DemoApplication",
            "projectName": "demo",
            "args": [
                "-Amapstruct.defaultComponentModel=spring",
                "-DprocessorIntegrationTest.debug=true",
                "-classpath",
                "${workspaceFolder}/build/classes/"
            ],
            "sourcePaths": [
                "${workspaceFolder}/build/generated/"
            ]
        }

Mapper file:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserPayloadMapper extends GenericPayloadMapper<User, UserRegistryRequest, UserRegistryResponse> {
    UserPayloadMapper INSTANCE = Mappers.getMapper(UserPayloadMapper.class);

    @Mapping(source = "userId", target = "id")
    public User fromRequest(UserRegistryRequest request);

    public UserRegistryResponse toResponse(User user);
}

Can anyone help me to configure the VSCode to run debug and unit tests? I thought before running debug and unit tests, it does not load the generated source code, but I don't know how to fix it.

Edit: For unit test file, if I add @SpringBootTest(classes = { UserPayloadMapper.class }) this will run properly, but inside the unit test code have nothing related to this mapper and I have several mappers like that, I cant put all of them into each unit tests.

2 Answers

I found the solution: add @ComponentScan(basePackages = "com.api.demo/build/classes/java/main/com/api/demo/service/mapper") and it works (to the mapstruct generated folder).

Dependency for build.gradle

dependencies {
    compile group: 'org.mapstruct', name: 'mapstruct-jdk8', version: '1.2.0.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'
}

Interface for Mapping from Dto to Model

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface Mapper {
    DatabaseDto toModel(ModelDto source);
    // Converting DatabaseDto to ModelDto based on the matched Columns
    // Mappings with Different Column names from Source to Destination
    @Mappings({
        @Mapping(target="id", source="dto.employeeId"),
        @Mapping(target="name", source="dto.employeeName")
    })
    ModelDto fromModel(DatabaseDto dto);
}
Related