Unsatisfied dependency expressed through constructor parameter 1 with userRepository - spring

In a spring boot application who are reactive and use jwt, in my spring-cloud-gateway, I have this code.
#EnableDiscoveryClient
#SpringBootApplication
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
#Configuration
#EnableWebFluxSecurity
#EnableReactiveMethodSecurity
public class SpringSecurityWebFluxConfig {
private final UserServiceImpl userService;
private final JwtTokenUtil tokenUtil;
private static final String[] AUTH_WHITELIST = {
"/resources/**",
"/webjars/**",
"/authorize/**",
"/favicon.ico"};
public SpringSecurityWebFluxConfig(JwtTokenUtil tokenUtil, UserServiceImpl userService) {
this.tokenUtil = tokenUtil;
this.userService = userService;
}
..
}
#Service
public class UserServiceImpl implements ReactiveUserDetailsService, UserService {
private final UserRepository userRepository;
public UserServiceImpl(final UserRepository userRepository) {
this.userRepository = userRepository;
}
...
}
#Repository
public interface UserRepository extends ReactiveCrudRepository<User, Integer>{
}
public class JWTHeadersExchangeMatcher implements ServerWebExchangeMatcher {
#Override
public Mono<MatchResult> matches(final ServerWebExchange exchange) {
}
}
public class JWTReactiveAuthenticationManager implements ReactiveAuthenticationManager {
...
public JWTReactiveAuthenticationManager(final PasswordEncoder passwordEncoder, final UserServiceImpl userService) {
this.passwordEncoder = passwordEncoder;
this.userService = userService;
}
}
public class JwtTokenUtil {
...
}
public class TokenAuthenticationConverter implements Function<ServerWebExchange, Mono<Authentication>> {
private final JwtTokenUtil tokenProvider;
public TokenAuthenticationConverter(JwtTokenUtil tokenProvider) {
this.tokenProvider = tokenProvider;
}
}
public class TokenAuthenticationConverter implements Function<ServerWebExchange, Mono<Authentication>> {
private final JwtTokenUtil tokenProvider;
public TokenAuthenticationConverter(JwtTokenUtil tokenProvider) {
this.tokenProvider = tokenProvider;
}
}
[ main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling
refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'springSecurityWebFluxConfig' defined in
file
[/home/mac/Development/project/reactive-cloud/gateway-service/build/classes/java/main/com/example/gatewayservice/config/SpringSecurityWebFluxConfig.class]:
Unsatisfied dependency expressed through constructor parameter 1;
nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userServiceImpl' defined in file
[/home/mac/Development/project/reactive-cloud/gateway-service/build/classes/java/main/com/example/gatewayservice/service/UserServiceImpl.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'com.example.gatewayservice.repository.UserRepository' available:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {} 2019-06-27 11:47:23.336 INFO 53073 --- [
main] ConditionEvaluationReportLoggingListener :
Tried to put autowired
on UserServiceImpl in SpringSecurityWebFluxConfig class
on UserRepository in UserServiceImpl class
on UserServiceImpl in JWTReactiveAuthenticationManager.class
but get same error
Edit
if i use
#EnableR2dbcRepositories to GatewayServiceApplication, I dont't have this error but it search about DatabaseClient

Please add #Autowired annotation in UserServiceImpl class for UserRepository variable in constitute constructor or variable level.

Related

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type

2020-09-23T15:28:00.3483912Z java.lang.IllegalStateException: Failed to load ApplicationContext
2020-09-23T15:28:00.3489821Z Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'salecChannelEventProcessor' defined in file [/home/runner/work/calculation-service/calculation-service/target/classes/com/demo/calculation/saleschannel/SalecChannelEventProcessor.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'de.demo.json.schema.JsonValidator' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
import de.demo.json.schema.JsonValidator;
#Configuration
#ComponentScan( basePackages = {
"com.demo",
"de.demo" },
excludeFilters = {
#ComponentScan.Filter( Configuration.class )
} )
#ImportResource("classpath:/spring-context.xml")
#Import({SwaggerConfig.class, SalesChannelSqsConfig.class})
public class SpringMvcConfig extends WebMvcConfigurationSupport {
#Autowired private ApplicationContext applicationContext;
#Bean( name = "objectMapper" )
public ObjectMapper getObjectMapper( JacksonService jacksonService ) {
return jacksonService.getObjectMapper();
}
#Bean(name = "jsonValidator")
public JsonValidator jsonValidator() {
return new JsonValidator();
}
}
#Component
#Slf4j
#RequiredArgsConstructor
public class SalesChannelUpdateListerner {
#NonNull
private final SalesChannelService salesChannelService;
#NonNull
private final SalecChannelEventProcessor salecChannelEventProcessor;
#SqsListener(value = "${sales.channel.update.queue.name}", deletionPolicy = ON_SUCCESS)
#SneakyThrows
public void receiveSalesChannelUpdateEvent(
#NotificationMessage EnvelopedMessage envelopedMessage) {
log.debug("Received message from sales channel update event queue : {}"
}
#Component
#Slf4j
#RequiredArgsConstructor
public class SalecChannelEventProcessor {
private static final String MESSAGE_TYPE = "sales_channel_update";
#NonNull
private final ObjectMapper objectMapper;
#NonNull
private final JsonValidator jsonValidator;
#SneakyThrows(JsonProcessingException.class)
public boolean isValid(EnvelopedMessage envelopedMessage) {
if (!MESSAGE_TYPE.equals(envelopedMessage.getType())) {
return false;
}
return jsonValidator.validate(envelopedMessage);
}
You need to create the JsonValidator bean. You need to change yor SalecChannelEventProcessor to be:
#Component
#Slf4j
#RequiredArgsConstructor
public class SalecChannelEventProcessor {
private static final String MESSAGE_TYPE = "sales_channel_update";
#NonNull
private final ObjectMapper objectMapper;
#Bean
public JsonValidator jsonValidator(){
return new JsonValidator();
}
#SneakyThrows(JsonProcessingException.class)
public boolean isValid(EnvelopedMessage envelopedMessage) {
if (!MESSAGE_TYPE.equals(envelopedMessage.getType())) {
return false;
}
return jsonValidator().validate(envelopedMessage);
}
}

How to do integration testing for custom mongo repository?

These are the following configuration that I have done in my project.
#Configuration
public class AppMongoConfig {
#Autowired private MongoDbFactory mongoDbFactory;
#Autowired private MongoMappingContext mongoMappingContext;
#Bean
public MappingMongoConverter mappingMongoConverter() {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext);
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return converter;
}
}
#Configuration
#RequiredArgsConstructor
#EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {
private final MultipleMongoProperties mongoProperties;
#Primary
#Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate() throws Exception {
return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
}
#Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() throws Exception {
return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
}
#Bean
#Primary
public MongoDbFactory primaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClientURI(mongo.getUri()));
}
#Bean
public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
return new SimpleMongoDbFactory(new MongoClientURI(mongo.getUri()));
}
}
#Data
#ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
}
#Configuration
#EnableMongoRepositories(
basePackages = {"com.student.repository.primary"},
mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {}
#Configuration
#EnableMongoRepositories(
basePackages = {"com.student.repository.secondary"},
mongoTemplateRef = "secondaryMongoTemplate")
public class SecondaryMongoConfig {}
Repository code:
public interface StudentDAO {
Student save(StudentInfo studentInfo);
}
#Repository
public class StudentDAOImpl implements StudentDAO {
#Autowired #Qualifier("primaryMongoTemplate")
private MongoTemplate mongoTemplate;
#Override public StudentInfo save(StudentInfo userWatchlist) {
return mongoTemplate.save(userWatchlist);
}
}
Integration Testing code:
#RunWith(SpringRunner.class)
#DataMongoTest(includeFilters = #Filter(Repository.class))
public class WatchListDAOImplIT {
#Autowired private StudentDAO studentDAO;
#Test
public void save() {
StudentInfo studentInfo = getStudentInfo();
StudentInfo dbUserWatchlist = watchListDAO.save(studentInfo);
Assert.assertEquals(studentInfo.getId(), dbUserWatchlist.getId());
}
private StudentInfo getStudentInfo() {
StudentInfo studentInfo = new StudentInfo();
studentInfo.setId(9999999l);
return studentInfo;
}
}
Which is giving me following error:-
java.lang.IllegalStateException: Failed to load ApplicationContext
at
org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at
org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at
org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:
: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'appMongoConfig': Unsatisfied dependency
expressed through field 'mongoDbFactory'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'primaryFactory' defined in class path
resource [.../config/mongo/MultipleMongoConfig.class]: Unsatisfied
dependency expressed through method 'primaryFactory' parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.mongo.MongoProperties'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.mongo.MongoProperties'
available: expected at least 1 bean which

Implemetation not found and get a NoSuchBeanDefinitionException

I use spring boot 2 application with spring data jpa and hibernate with postgres
package com.acmor.togy.repository.util.postgres
#Component
public class HStoreParameter implements FormatParameter{
...
}
package com.acmor.togy.repository.util;
public interface FormatParameter {
String format(Map<String, String> properties);
}
package com.acmor.togy.repository.util;
public class AbstractRepository<T, ID> extends SimpleJpaRepository<T, ID> {
private ThreadLocal<Map<String, Object>> parameters = new ThreadLocal<>();
#Autowired
private FormatParameter formatParameter;
public AbstractRepository(JpaEntityInformation entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
}
public AbstractRepository(Class domainClass, EntityManager em) {
super(domainClass, em);
}
}
package com.acmor.togy.repository;
#Repository
public class EnumsRepositoryImpl extends AbstractRepository implements EnumsRepositoryCustom {
}
public interface EnumsRepositoryCustom {
...
}
I created a basic test
#RunWith(SpringRunner.class)
public class EnumsRepositoryCustomTest {
#Autowired
private EnumsRepositoryCustom enumsRepository;
#Test
public void test_advanced_search_using_properties() {
EnumsSearch search = new EnumsSearch();
...
Page<Enums> page = enumsRepository.search(search, PageRequest.of(0, 10));
...
}
}
When I run test I get
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'com.acmor.togy.repository.util.FormatParameter' available: expected
at least 1 bean which qualifies as autowire candidate. Dependency
annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have a implementation of FormatParameter, it's HStoreParameter

Unsatisfied dependency during test

I have a spring boot 2.0.0 M2 application who run well.
I use autowired on constructor
#RequestMapping(value = "/rest")
#RestController
public class AddressRestController extends BaseController{
private final AddressService AddressService;
#Autowired
public AddressRestController(final AddressService AddressService) {
this.AddressService = AddressService;
}
...
}
#Service
public class AddressServiceImpl extends BaseService implements AddressService {
#Autowired
public AddressServiceImpl(final AddressRepository AddressRepository) {
this.AddressRepository = AddressRepository;
}
private final AddressRepository AddressRepository;
...
}
public interface AddressRepository extends JpaRepository<Address, Integer>, AddressRepositoryCustom {
}
#Repository
public class AddressRepositoryImpl extends SimpleJpaRepository implements AddressRepositoryCustom {
#PersistenceContext
private EntityManager em;
#Autowired
public AddressRepositoryImpl(EntityManager em) {
super(Address.class, em);
}
...
}
When i try to run a basic test
#RunWith(SpringJUnit4ClassRunner.class)
public class AddressServiceTest {
#Autowired
private AddressService service;
#MockBean
private AddressRepository restTemplate;
#Test
public void getAddress(){
MockitoAnnotations.initMocks(this);
Pageable page = PageRequest.of(0, 20);
Page<Address> pageAdr = mock(Page.class);
given(this.restTemplate.findAll(page)).willReturn(pageAdr);
Page<AddressDto> pageDto = service.getAddress(page);
}
}
I get this error
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name
'com.sonos.arcor.service.AddressServiceTest': Unsatisfied dependency
expressed through field 'service'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type ''com.sonos.arcor.service.AddressService'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
I don't understand why i get this error.
You need to annotate the test with SpringBootTest so that spring initialize an application context
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications
#SpringBootTest
#RunWith(SpringJUnit4ClassRunner.class)
public class AddressServiceTest {
// the remaining test
}
Also you do not need MockitoAnnotations.initMocks(this);
Spring takes care of the mock handling
When [#MockBean is]used on a field, the instance of the created mock will also be
injected. Mock beans are automatically reset after each test method
see Mocking and spying beans

Spring Boot upgrade results in unresolvable circular reference

I upgraded my SpringBoot 1.3.5 to 1.5.2 RELEASE and am suddenly getting an error when my beans are being wired. I am not doing constructor injection anywhere, so the circular reference makes no sense.
Here is my main class:
#EnableGlobalMethodSecurity(securedEnabled = true)
#SpringBootApplication
public class MyApplication extends WebMvcConfigurerAdapter {
...
}
I have many #Configuration classes in my /src/java/../configuration/ such as
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Bean
public PasswordEncoder passwordEncoder() {
// default strength = 10
return new BCryptPasswordEncoder();
}
...
}
and
#Configuration
#ComponentScan()
public class MyApplicationConfiguration {
#Bean
#Order(Ordered.HIGHEST_PRECEDENCE)
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
return new SessionTimeoutEmbeddedServletContainerCustomizer();
}
...
}
I also have a CustomUserDetailsService that does use the passwordEncoder, but its never been a problem prior:
#Component
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserService userService;
#Autowired
private UserRepository userRepository;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private PasswordResetTokenRepository passwordTokenRepository;
...
}
And then I am using Spock for my IntegrationTests by extending
#ContextConfiguration(classes = MyApplication, initializers = ConfigFileApplicationContextInitializer.class)
#WebAppConfiguration
#SpringBootTest
public class BaseSpecification extends Specification {
def setup() {
RestAssured.port = serverPort;
}
#Value('${local.server.port}')
private int serverPort;
}
So all this worked with Spring-Boot 1.3.5 but now that I upgraded I get the following when I build or run tests:
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'customUserDetailsService': Unsatisfied
dependency expressed through field 'passwordEncoder'; nested exception
is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'passwordEncoder': Requested bean is
currently in creation: Is there an unresolvable circular reference?
... Caused by:
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'passwordEncoder': Requested bean is
currently in creation: Is there an unresolvable circular reference?
UPDATE
Based upon Andy comment, I moved some dependencies around and think I have it fixed.
Removed this from WebSecurityConfig and put them in MyApplicationConfiguration:
#Autowired
private CustomUserDetailsService customUserDetailsService;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
return;
}
#Bean
public PasswordEncoder passwordEncoder() {
// default strength = 10
return new BCryptPasswordEncoder();
}
While I do not have any constructor injection, it would seem the new Spring Security does it DI differently. I cannot confirm it, but this is no longer an issue.

Resources