Hi i was trying to work over an existing SpringBoot application. I created a service class and tried to autowire it in the existing controller, but when trying to build, its failing saying bean injection failed.
Cause: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'controller': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private
com.disooza.www.card.dispenser.service.FilaPartnerService
com.disooza.www.card.dispenser.controller.CardDispenserController.FilaPartnerService;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.disooza.www.card.dispenser.service.FilaPartnerService] found for
dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
Following is my controller class:
#Controller
#RequestMapping(value = "/service")
public class CardController {
private static final Logger LOGGER = LoggerFactory.getLogger(CardController.class);
#Autowired
private CardDao dao;
#Autowired
private PaymentService paymentService;
#Autowired
private FilaPartnerService filaPartnerService;
FilaPartnerService is the newly created interface, and rest all autowires are working fine in this controller.
Interesting thing is when I try to place this service class in any other controller it is working fine. Any help over this issue will be appreciated, since I'm stuck with it.
This is my service interface:
#Service
public interface FilaPartnerService {
RetrievePaymentTokenResponse retrieveXXX(SupplierRequest request);
}
This is the implementation class:
#Component
public class FilaPartnerServiceImpl implements FilaPartnerService {
#Autowired
private RestTemplate restTemplate;
#Autowired
private RetrieveRequestBuilder retrieveRequestBuilder;
#Value("${filaPartner.url}")
private String filaServiceUrl;
#Override
public RetrievePaymentTokenResponse retrieveFilaPaymentToken(SupplierTokenRequest request) {
RetrievePaymentTokenResponse tokenResponse = null;
RetrievePaymentTokenRequest paymentServiceRequest = retrievePaymentTokenRequestBuilder.retrievePaymentTokenRequestBuilder(request);
try {
tokenResponse =
restTemplate.postForObject( FilaServiceUrl, paymentServiceRequest, RetrievePaymentTokenResponse.class);
} catch (RestClientException exp) {
//TO-DO return error code
}
return null;
}
}
Related
I use psring boot 2, postgres and Jpa with hibernate.
I would like to test one of my class
#Component
public class ExportsFacade {
private SamplesService sampleService;
private SamplesRepository sampleRepository;
#Autowired
public ExportsFacade(SamplesService sampleService, SamplesRepository sampleRepository) {
this.sampleService = sampleService;
this.sampleRepository=sampleRepository;
}
...
}
I created this test
#RunWith(SpringRunner.class)
#DataJpaTest
#AutoConfigureTestDatabase(replace=Replace.NONE)
public class ExportsFacadeTest {
#Autowired
private ExportsFacade exportsFacade;
#Test
public void export() throws IOException {
exportsFacade.generateExport();
}
}
I get this error
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'com.lcm.facade.ExportsFacadeTest':
Unsatisfied dependency expressed through field 'exportsFacade'; nested
exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type 'com.lcm.facade.ExportsFacade' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have spring-boot-starter-data-jpa and spring-boot-starter-web. I try load List<Project> from mysql using Spring jpa but get bellow BeanCreationException in controller.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'controller': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.project.data.spring_jpa.ProjectRepository com.project.application.Controller.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.project.data.spring_jpa.ProjectRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Controller.java:
...
#RestController
public class Controller {
...
#Autowired
private ProjectRepository repository;
private ProjectAccessor projectAccessor = manager.createAccessor(ProjectAccessor.class);
public void setRepository(ProjectRepository repository){
this.repository = repository;
}
#RequestMapping("/test")
#ResponseBody
public List<Project> test() {
System.out.println("mysql test");
return repository.findAll();
}
...
ProjectRepository.java:
public interface ProjectRepository extends CrudRepository<Project, Long>{
List<Project> findAll();
}
Did you write #Repository annotation on ProjectRepository
#Repository
public interface ProjectRepository extends CrudRepository<Project, Long>{
List<Project> findAll();
}
Do make sure you enabled JpaRepository on your configuration using #EnableJpaRepositories
We get this exception usually when we don't specify where to look for the JPA repositories.
So mention #EnableJpaRepositories("your repository package") where you specify #Configuration or #SpringBootApplication.
It will work fine.
I'm struggling with Cucumber and Spring configuration.
I'm writing selenium framework using Page Object Pattern, with BrowserFactory.
When I use #ComponentScan, #Component and #Autowire annotations everything works fine, but when I want to create a bit more complicated bean with #Bean annotation (BrowserFactory which registers few browser drivers) in #Configuration class it does not work, during debug I'm getting nulls on every single variable I'm trying to Autowire.
I'm using Spring 4.2.4, all cucumber dependencies in version 1.2.4.
Config:
#Configuration
public class AppConfig {
#Bean
#Scope("cucumber-glue")
public BrowserFactory browserFactory() {
BrowserFactory browserFactory = new BrowserFactory();
browserFactory.registerBrowser(new ChromeBrowser());
browserFactory.registerBrowser(new FirefoxBrowser());
return browserFactory;
}
#Bean(name = "loginPage")
#Scope("cucumber-glue")
public LoginPage loginPage() throws Exception {
return new LoginPage();
}
#Bean(name = "login")
#Scope("cucumber-glue")
public Login login() {
return new Login();
}
}
POP:
public class LoginPage extends Page {
public LoginPage() throws Exception {
super();
}
...
}
Page:
public class Page {
#Autowired
private BrowserFactory browserFactory;
public Page() throws Exception{
...
}
}
Login:
public class Login {
#Autowired
private LoginPage loginPage;
public Login(){}
...
}
Steps:
#ContextConfiguration(classes = {AppConfig.class})
public class LoginSteps {
#Autowired
Login login;
public LoginSteps(){
}
#Given("^an? (admin|user) logs in$")
public void adminLogsIn(Login.User user) throws Exception {
World.currentScenario().write("Logging in as " + user + "\n");
login.as(user);
}
}
Error:
cucumber.runtime.CucumberException: Error creating bean with name 'LoginSteps': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: Login LoginSteps.login; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'login': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private LoginPage Login.loginPage; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginPage' defined in AppConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [LoginPage]: Factory method 'loginPage' threw exception; nested exception is java.lang.NullPointerException
And now for the fun part...
BrowserFactory in World class is properly Autowired!!
World:
public class World {
#Autowired
private BrowserFactory browserFactory;
...
}
So I'll answer my own question:)
Issue was that I was calling BrowserFactory inside of Page constructor.
Looks like this bean was not yet created and was causing NPEs.
In order to fix that I:
Added #Lazy annotation to configuration (all elements that use this configuration, both defined in that class and those which will be found by Scan will be created as Lazy)
Moved call to Browser Factory to #PostConstruct method
Two more things to increase readability of Spring config:
Added #ComponentScan to configuration
Classes with no constructor parameters are annotated with #Component and #Scope("cucumber-glue") annotation so bean creation can be removed from AppConfig.class
I'd like to create an autowired bean in a Dao class in order to do logging opperations. My way was hitherto static final statement like this:
private static final Log log = LogFactory.getLog(LoggedClass.class);
But now I'm trying to use IoC to turn classes decoupled.
If just add configuration in pom.xml and try to do sth like
#Autowired
Log log;
I receive an error message:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'funciDaoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.apache.commons.logging.Log br.com.bb.dirco.dao.impl.FunciDaoImpl.log; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'log' defined in class path resource [com/company/project/util/PersistenceConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.Class]: : No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.Class] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
In order to get a logger, I had to provide a class to getLog method on LogFactory class and attribute it to Log instance. There's a way to do it using #Autowired Spring IoC? Thanks!
You can inject only those objects which are managed/created by Spring container. You have to register your bean (or factory method creating the bean) with container (with annotations like #Component/#Singleton/... or directly in xml)
In your case it's not very applicable since you have to have many different types (for every class) of logger objects provided by Spring and then when you inject they would have to be identified by different name/type for every class.
P.S. I don't see any problem using it the way you use it now
Where I work we have implemented support for #Autowired SLF4J Loggers using Springs BeanPostProcessor.
First you need to define an Logger placeholder bean in your application context. This bean is going to be injected by Spring into all bean with a #Autowired Logger field.
#Configuration
public class LoggerConfig {
#Bean
public Logger placeHolderLogger() {
return PlaceHolder.LOGGER;
}
#Bean
public AutowiredLoggerBeanPostProcessor loggerPostProcessor() {
return new AutowiredLoggerBeanPostProcessor();
}
}
Then you an AutowiredLoggerBeanPostProcessor which inspects all beans, indetify bean that contain Logger fields annotated with #Autowired (at this point should contain a reference to the Logger placeholder bean), create a new Logger for the partilcar bean an assigned it to the fields.
#Component
public class AutowiredLoggerBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
attachLogger(bean);
return bean;
}
#Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
attachLogger(bean);
return bean;
}
private void attachLogger(final Object bean) {
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
if (Logger.class.isAssignableFrom(field.getType()) &&
(field.isAnnotationPresent(Autowired.class) ||
field.isAnnotationPresent(Inject.class))) {
ReflectionUtils.makeAccessible(field);
if (field.get(bean) == PlaceHolder.LOGGER) {
field.set(bean, LoggerFactory.getLogger(bean.getClass()));
}
}
}
});
}
#Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
}
When I run Cobertura, it causes the following Spring autowiring error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService; nested exception is java.lang.IllegalArgumentException: Can not set com.dnb.components.storage.service.UserService field com.dnb.components.storage.rest.resource.UserResource.userService to com.sun.proxy.$Proxy56 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
As suggested in other related posts, I tried forcing Spring to use CGLIB by changing "proxyTargetClass=true", but this results in a different error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.dnb.components.storage.repository.UserRepository com.dnb.components.storage.service.UserService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy54]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy54
This is what the Repository class looks like:
#Transactional
public interface UserRepository extends CrudRepository<User, Long> {
public User findByCrmId(String crmIdId);
}
Here is the service that gets injected with UserRepository:
#Service
#Transactional
public class UserService extends TraceablePersistenceService<User, UserRepository> {
#Autowired
UserRepository repository;
#Transactional
public Iterable<User> findAll() {
return repository.findAll();
}
public User findOne(Long id) {
return repository.findOne(id);
}
}
Our configuration is in
#Configuration
#EnableTransactionManagement(proxyTargetClass=true)
#EnableJpaRepositories(basePackages = {"com.dnb.components.storage.repository"})
#Profile("inmemory")
public class InMemoryStandaloneStorageConfig extends BasicJpaStorageConfig {
....
(omitted for brevity)
UserResource.java:
#Component
#Path(UserResource.uri)
public class UserResource extends AbstractResource {
public final static String uri = BASE_URI + "/users";
#Override
public String getURI() {
return BASE_URI + uri;
}
#Autowired
private UserService userService;
...
It seems that the Spring Data JPA generated Repository class cannot be proxied either way without screwing up the auto-wiring.
Is there a fix for this? Is it even a good idea to annotate Repository methods with #Transactional? Should the annotation be at the service level only?
usually, we do not inject concrete classes but we inject interfaces.
this is my suggestion.
a. refactor UserService to UserServiceImpl class
b. create UserService interface
c. UserServiceImpl implements UserService
d. add "findAll" and "findOne" method declaration to UserService interface