java.lang.ClassNotFoundException: Cannot find implementation for

14,330

Solution 1

Found probable cause:

https://github.com/mapstruct/mapstruct/issues/1159

looks like an issue between mapstruct and lombok

Edit:

Solution is to remove javaagent:lombok.jar from eclipse.ini, restart IDE and rebuild project, make a copy of files generated from annotation, add javaagent to eclipse.ini, restart IDE and rebuild project and restore copied files

Solution 2

Add annotation mapstruct and lombok processors to your compiler plugin and mapstruct should generate implementation for your mapper interface:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</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>
                        <version>${org.projectlombok.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>

Solution 3

When using Mapstruct with Spring, you can define that the mapper should generate a Spring bean using componentModel as described in 2. Set up. 2.4 Configuration options.

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring")
public interface UserMapper {
    /* your code... */
}

This allows you to inject the mapper in your beans:

@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;

    //rest of your code...
}

Take into account that Mapstruct generates the code on precompile stage, so you won't see any class implementing UserMapper interface until you compile the code and see the generated code folder.

Share:
14,330
J. Łyskawa
Author by

J. Łyskawa

Updated on June 07, 2022

Comments

  • J. Łyskawa
    J. Łyskawa almost 2 years

    I need help with the following error:

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController' defined in file [D:\projects\PIK\bin\main\edu\pw\eiti\pik\user\UserController.class]: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [edu.pw.eiti.pik.user.UserController]: Constructor threw exception; nested exception is java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot find implementation for edu.pw.eiti.pik.user.UserMapper
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:278) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1270) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
        at edu.pw.eiti.pik.PikApplication.main(PikApplication.java:10) [main/:na]
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [edu.pw.eiti.pik.user.UserController]: Constructor threw exception; nested exception is java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot find implementation for edu.pw.eiti.pik.user.UserMapper
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:182) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:271) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        ... 18 common frames omitted
    Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot find implementation for edu.pw.eiti.pik.user.UserMapper
        at org.mapstruct.factory.Mappers.getMapper(Mappers.java:79) ~[mapstruct-jdk8-1.2.0.Final.jar:na]
        at edu.pw.eiti.pik.user.UserMapper.getInstance(UserMapper.java:12) ~[main/:na]
        at edu.pw.eiti.pik.user.UserController.<init>(UserController.java:18) ~[main/:na]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:170) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
        ... 20 common frames omitted
    Caused by: java.lang.ClassNotFoundException: Cannot find implementation for edu.pw.eiti.pik.user.UserMapper
        at org.mapstruct.factory.Mappers.getMapper(Mappers.java:93) ~[mapstruct-jdk8-1.2.0.Final.jar:na]
        at org.mapstruct.factory.Mappers.getMapper(Mappers.java:76) ~[mapstruct-jdk8-1.2.0.Final.jar:na]
        ... 27 common frames omitted
    

    UserMapper interface has

    @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
    

    annotation. I use eclipse Neon with buildship plugin, org.mapstruct and spring are imported with Gradle. It works without this error on my colleague's IntelliJ

    Code for UserMapper:

    package edu.pw.eiti.pik.user;
    
    import org.mapstruct.Mapper;
    import org.mapstruct.ReportingPolicy;
    import org.mapstruct.factory.Mappers;
    import org.springframework.security.core.GrantedAuthority;
    
    @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
    public interface UserMapper {
    
        static UserMapper getInstance() {
            return Mappers.getMapper(UserMapper.class);
        }
    
        User fromDto(UserDto dto);
    
        UserDto toDto(User entity);
    
        Authority fromDto(AuthorityDto dto);
    
        AuthorityDto toDto(GrantedAuthority entity);
    }
    

    From what I read it could do something with compiler failing to connect auto-generated code (Gradle does not set anything in AnnotationProcessing>FactoryPath)

    • J. Łyskawa
      J. Łyskawa about 6 years
      no, Mapper is the only annotation
    • J. Łyskawa
      J. Łyskawa about 6 years
      it is actually an interface, my bad.
    • J. Łyskawa
      J. Łyskawa about 6 years
      I tried adding it to static UserMapper getInstance() { return Mappers.getMapper(UserMapper.class); } but to no effect
    • J. Łyskawa
      J. Łyskawa about 6 years
      No, I do not use @Autowired
    • J. Łyskawa
      J. Łyskawa about 6 years
      However it works without modification on my colleague's IntelliJ
    • J. Łyskawa
      J. Łyskawa about 6 years
      Only default constructor
    • J. Łyskawa
      J. Łyskawa about 6 years
      There is no class implementing UserMapper
    • Filip
      Filip about 6 years
      Do you use the apt plugin? If yes which version?
  • Luiggi Mendoza
    Luiggi Mendoza about 6 years
    @J.Łyskawa how are you running your app?
  • J. Łyskawa
    J. Łyskawa about 6 years
    SpringApplication.run(PikApplication.class, args);
  • Luiggi Mendoza
    Luiggi Mendoza about 6 years
    Are you including the package where your mapper is located as part of the spring auto scanning?
  • heading
    heading over 3 years
    You save my day. Thanks a lot.