Spring boot : Error creating bean with name 'methodValidationPostProcessor'

Aditya Ekbote picture Aditya Ekbote · Nov 23, 2018 · Viewed 15.1k times · Source

I have a spring boot application and i am creating war file and deploying on Tomcat 8. The code works perfectly well when running in my Eclipse Oxygen and i am getting below exception when running application on Tomcat8.

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'methodValidationPostProcessor' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Unsatisfied dependency expressed through method 'methodValidationPostProcessor' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:223)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:702)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:527)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5311)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
... 10 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 32 more

Below is my pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.aditya</groupId>
    <artifactId>MyApp</artifactId>
    <version>Final</version>

<packaging>war</packaging>

<name>MyApp</name>
<description>MyApp</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<repositories>
    <repository>
        <id>oracle-repo</id>
        <name>oracle repo</name>
        <url>http://download.oracle.com/maven</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
            </exclusion>
        </exclusions> -->
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.4.0</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.4.0</version>
    </dependency> -->

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>


    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.5</version><!--$NO-MVN-MAN-VER$ -->
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.5</version><!--$NO-MVN-MAN-VER$ -->
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>1.16</version>
    </dependency>

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

    <!-- <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency> -->

    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.3.2</version>
    </dependency>

    <dependency>
        <groupId>pushpayment</groupId>
        <artifactId>en</artifactId>
        <version>2.0.2</version>
    </dependency>

    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>2.6.0</version><!--$NO-MVN-MAN-VER$ -->
    </dependency>

    <dependency>
        <groupId>net.sf.jt400</groupId>
        <artifactId>jt400</artifactId>
        <version>6.6</version>
    </dependency>

    <!-- <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-rest-hal-browser</artifactId>
    </dependency> -->

    <dependency>
        <groupId>net.jodah</groupId>
        <artifactId>expiringmap</artifactId>
        <version>0.5.8</version>
    </dependency>

</dependencies>

<build>
    <finalName>MyApp</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                    <id>install-external</id>
                    <phase>build</phase>
                    <configuration>
                        <file>C:/Users/adekbote/.m2/repository/pushpayment/en/2.0.2/en-2.0.2.jar</file>
                        <repositoryLayout>default</repositoryLayout>
                        <groupId>pushpayment</groupId>
                        <artifactId>en</artifactId>
                        <version>2.0.2</version>
                        <packaging>jar</packaging>
                        <generatePom>true</generatePom>
                    </configuration>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Below is my MyApp.java

@ComponentScan("com.ad.*")
@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(MyApp.class);
}

public static void main(String[] args) throws Exception {
    SpringApplication.run(MyApp.class, args);
}
}

Below is my Config.java

@Configuration
@EnableSwagger2
public class Config {

    private LoggerUtil log = LoggerUtil.getInstance();

    private static final String CLASSNAME = "Config";

    @Bean(name = "validator")
    @Qualifier("validator")
    public Validator validator() {
        log.doLog(2, CLASSNAME, "validator", "inside validator = ");
        ValidatorFactory validatorFactory = Validation
                .buildDefaultValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        return validator;
    }
}

Below is my AuthorizationServiceImpl.java

@Service
public class AuthorizationServiceImpl implements AuthorizationService {

    @Autowired
    @Qualifier("validator")
    private Validator validator;

    @Autowired
    @Qualifier("requestValidatorClass")
    private Map<String, String> requestValidatorClass;

    private LoggerUtil log = LoggerUtil.getInstance();

    private static final String CLASSNAME = "AuthorizationServiceImpl";

    @Override
    public ResponseBean validate(Object request, String type) throws Throwable {
        ResponseBean responseBean = new ResponseBean();
        final String methodName = "validate";
        String className = null;


        try {
            className = requestValidatorClass.get((type));
            log.doLog(2, CLASSNAME, methodName, "className = " + className);

            if(className != null){
                Class<?> cls = Class.forName(className);
                RequestValidator requestValidator = (RequestValidator) cls.newInstance();
                responseBean = requestValidator.validate(request, validator);
            }else{
                responseBean.setResponseCode(QRConstants.INVALID_FUNCTION);
                responseBean.setResponseMsg(Utils.getRespDesc(QRConstants.INVALID_FUNCTION));
            }
        } catch (Exception e) {
            log.doLog(3, CLASSNAME, methodName, LoggerUtil.getExStackTrace(e));
            responseBean.setResponseCode(QRConstants.TECHNICAL_ERROR_CODE);
            responseBean.setResponseMsg(Utils.getRespDesc(QRConstants.TECHNICAL_ERROR_CODE));
        }

        return responseBean;
    }

}

Can anyone let me know why i am getting this error while running my Tomcat.

Answer

Abhishek picture Abhishek · Nov 23, 2018

Spring-boot-starter-web adds a dependency to hibernate-validator, therefor spring expects to configure a validator dependency.

Remove that dependency , add exclusion. I see you have commented the exclusion:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
            </exclusion>
        </exclusions>
</dependency>

Or if you want to use this dependency, then upgrade to the latest version:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.13.Final</version>
</dependency>