The spring boot exception org.springframework.beans.BeanInstantiationException: Failed to instantiate: Factory method threw exception occurs when the abstract class could not find the implemented class while auto-wiring using the factory method. The implementation class of the abstract class cannot be created or is not available in the java classpath or is not available in the spring boot context. The spring boot application throws the exception org.springframework.beans.BeanInstantiationException: Failed to instantiate: Factory method threw exception because the bean could not be instantiated.
If the class is dynamically loaded in the spring boot application, if the class or jar is not available, the exception will be thrown. This exception is commonly seen if loading a database driver using the javax.sql.datasource class. If the database driver jar is not present in the class path, the javax.sql.datasource class is not available. The datasource factory method, therefore will throw the exception Factory method threw exception.
The factory method attempts to load the abstract class using the implemented class. As the implemented class is not available, the abstract class will throw the exception.
Exception
The stack trace of the exception org.springframework.beans.BeanInstantiationException: Failed to instantiate: Factory method threw exception will be shown as like below.
2020-12-13 11:21:11.691 WARN 38974 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'animal' defined in class path resource [com/yawintutor/SpringConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.yawintutor.AbstractAnimal]: Factory method 'animal' threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'abstractAnimal' available
2020-12-13 11:21:11.699 INFO 38974 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-13 11:21:11.722 ERROR 38974 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Method animal in com.yawintutor.SpringConfig required a bean named 'abstractAnimal' that could not be found.
Action:
Consider defining a bean named 'abstractAnimal' in your configuration.
How to reproduce this exception
If an implemented class is not available for an abstract class, the abstract class will not be assigned to an object. The spring boot bean could not be created for the abstract class. The bean factory method will attempt to find the class implemented for the abstract class. As the implementation class is not located, the spring boot application will throw the exception.
package com.yawintutor;
public abstract class AbstractAnimal {
}
package com.yawintutor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Autowired
BeanFactory beanFactory;
@Bean
public AbstractAnimal animal() {
AbstractAnimal abstractAnimal = (AbstractAnimal)beanFactory.getBean("abstractAnimal");
return abstractAnimal;
}
}
Output
2020-12-13 11:21:11.691 WARN 38974 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'animal' defined in class path resource [com/yawintutor/SpringConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.yawintutor.AbstractAnimal]: Factory method 'animal' threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'abstractAnimal' available
2020-12-13 11:21:11.699 INFO 38974 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-12-13 11:21:11.722 ERROR 38974 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Method animal in com.yawintutor.SpringConfig required a bean named 'abstractAnimal' that could not be found.
Action:
Consider defining a bean named 'abstractAnimal' in your configuration.
Root Cause
The bean factory method attempts to load and create a bean using the string name specified in the getBean method. If the abstract class name is specified in the getBean method, the spring boot application can search for the implemented class. If the implemented class is not available in the spring boot context, the exception org.springframework.beans.BeanInstantiationException: Failed to instantiate: Factory method threw exception will be thrown.
Solution 1
The abstract class can be implemented with a class. The bean object could not have been created for an abstract class. It is necessary to create a new class that extends the abstract class. If the bean factory is attempting to get the bean by using the abstract class name, it can find and associate the implemented class. The exception would then be resolved.
package com.yawintutor;
public abstract class AbstractAnimal {
}
package com.yawintutor;
import org.springframework.stereotype.Component;
@Component
public class Lion extends AbstractAnimal{
}
package com.yawintutor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Autowired
BeanFactory beanFactory;
@Bean
public AbstractAnimal animal() {
AbstractAnimal abstractAnimal = (AbstractAnimal)beanFactory.getBean("lion");
return abstractAnimal;
}
Solution 2
If the spring boot abstract class could be converted to a normal class, the abstract class would have to be converted to a normal class. The spring boot application loads the class like a regular bean. This is going to solve the exception.
package com.yawintutor;
public class AbstractAnimal {
}
package com.yawintutor;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Autowired
BeanFactory beanFactory;
@Bean
public AbstractAnimal animal() {
AbstractAnimal abstractAnimal = (AbstractAnimal)beanFactory.getBean("abstractAnimal");
return abstractAnimal;
}
}
Solution 3
If the factory design pattern is used to load the implementation from the jar dynamically and the jar is not available in the java class path, the bean factory could not be locate the implemented class for the abstract class. For example, the datasource class is not available if the database driver jar is not available or loaded in the java class path. The database driver will throw exception. If you add the database driver jar, the exception will be resolved.