Reputation: 1682
I'm trying to create very simple JUnit test into Spring Cloud project:
@SpringBootTest(classes = {ProductMapper.class })
public class TestingWebApplicationTests {
@Test
public void contextLoads() {
}
}
import org.mapstruct.Mapper;
@Mapper(config = BaseMapperConfig.class)
public interface ProductMapper {
ProductDTO toDTO(Product product);
ProductFullDTO toFullDTO(Product product);
Product map(ProductFullDTO productDTO);
ProductFilter toFilter(ProductFilterDTO dto);
}
I get this error when I try to run the test into the latest Intelij.
java: No implementation was created for ProductMapper due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
Do you know how I can fix this issue?
Upvotes: 13
Views: 27239
Reputation: 106
In my case I had a reference to an entity object defined in a domain object like this:
@Data
public class Message implements Serializable, MutableDomainObject {
private MessageEntity parentMessage; // this should have been Message, not MessageEntity
}
The annotation processor was reporting the following error:
No implementation was created for RestMessageMapper due to having a problem in the erroneous element com.example.entity.MessageEntity
=> Also check your object references.
Upvotes: 0
Reputation: 1
I had the same problem, and my search brought me here. I know it's too late, but I'll put my fix here, in case someone like me ends up here. These are the dependencies:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok.mapstruct.binding.version}</version>
<scope>compileOnly</scope>
</dependency>
Make sure you copy them just like that, and use properties for the version variables. The lombok dependency has an <optional>true</optional>
tag by default if you get it from the spring initializer, so remove that tag and use the scope tag as above.
And here are the plugins:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>21</source>
<target>21</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok.mapstruct.binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
Hope this helps someone!
Upvotes: 0
Reputation: 17687
I had the same problem, but in my case the root cause was related to my multi-module architecture.
The top-level mapper has used one child mapper of module A which used itself a child mapper of module B.
Gradle module A has dependency implementation of module B
implementation("module-b")
This means the application module has no access to classes of transitive dependency B through module A which makes MapStruct fail with this error:
No implementation was created for MapperOfApplication due to having a problem in the erroneous element EntityOfModuleB. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
The odd thing is, mapper for EntityOfModuleB is not even used, as EntityOfModuleADto has no reference to EntityOfModuleBDto and in my opinion this error should not occur in my case. (MapStruct bug?)
However, as a solution I had to additionally include dependency implementation("module-b")
into my application module
Upvotes: 1
Reputation: 639
It's not exactly related to MapStruct itself, but maybe it will save some devs a few minutes / hours when searching for the problem.
I had a similar problem in a project, where I was supposed to add new API version and mark old one as deprecated.
When I tried compiling with maven, I got errors
[ERROR] /src/main/java/com/example/MapStructMapperClass.java: No implementation was created for MapStructMapperClass.java due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
The project uses Lombok, so I checked annotation processor configs. Looked fine and worked properly on a simple, ad hoc created project. Tried bumping MapStruct and Lpmbok versions. Still the same problem.
Then, I noticed a few lines in the log:
[WARNING] COMPILATION WARNING :
[INFO] ------------------------------
[WARNING] /src/main/java/com/example/MyRestController.java: com.example.MyOldService in MyRestController has been deprecated
[INFO] 1 warning
[INFO] ----------------------
[ERROR] COMPILATION ERROR :
[INFO] ----------------------
[ERROR] warnings found and -Werror specified
And the config in maven pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<failOnWarning>true</failOnWarning>
<configuration>
</plugin>
As Javac JDK 8 states:
-Werror
Terminate compilation if warnings occur.
So, my problem was that I used @Deprecated annotation and someone turned treating compilation warnings as errors on. Due to the project using MapStruct and having pleeeeenty of mappers with the same compilation error, I focused on solving the problem with the annotations processors, completely ignoring those "insignificant" warnings.
Upvotes: 1
Reputation: 385
Try to reorder your annotation processor factory path, move lombok to the top.
Upvotes: 25
Reputation: 44476
Use the generated implementation of the mapper within the Spring test configuration:
@SpringBootTest(classes = {ProductMapperImpl.class })
Also remember that the mapper itself should be bound to the Spring context.
Upvotes: 1