Cant inject autowire bean into my class - java

I have a Spring bean defined, but when I am add the last 4 lines for Autowiring another RestClient rest bean, I am getting error (If I remove the last 3 lines, my spring container loads fine):
#Component
public class TimeseriesServiceImpl {
private static Logger log = Logger.getLogger(TimeseriesServiceImpl.class);
#PostConstruct
public void init() {
System.out.println("MyService init method called");
}
#PreDestroy
public void destory(){
System.out.println("MyService destroy method called");
}
#Autowired
#Qualifier("restClient")
public RestClient rest ;
Error:
2016-02-07 18:46:41.609 WARN 11084 --- [main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'timeseriesServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.ge.predix.solsvc.restclient.impl.RestClient com.tcs.timeseries.service.TimeseriesServiceImpl.rest; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.ge.predix.solsvc.restclient.impl.RestClient] 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), #org.springframework.beans.factory.annotation.Qualifier(value=restClient)}
2016-02-07 18:46:41.612 INFO 11084 --- [main] o.apache.catalina.core.StandardService : Stopping service Tomcat
2016-02-07 18:46:41.623 ERROR 11084 --- [main] o.s.boot.SpringApplication : Application startup failed
I am using maven spring boot application
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackages={"com.tcs.timeseries.*","com.ge.predix.solsvc.restclient.config.*", "com.ge.predix.solsvc.restclient.impl.*"})
#PropertySource("classpath:application-default.properties")
#ContextConfiguration(locations = {
"classpath*:META-INF/spring/application-context.xml"
})
public class TimeseriesclientApplication {
private static final Logger log = LoggerFactory.getLogger(TimeseriesclientApplication.class);
public static void main(String[] args) {
//SpringApplication.run(TimeseriesclientApplication.class, args);
SpringApplication springApplication = new SpringApplication(TimeseriesclientApplication.class);
ApplicationContext ctx = springApplication.run(args);
log.info("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames)
{
log.info(beanName);
}
}
Details of the RestClientImpl bean:
#Component(value = "restClient")
public class RestClientImpl
implements RestClient, ApplicationContextAware
{
private static Logger log = LoggerFactory.getLogger(RestClientImpl.class);
/**
*
*/
#Autowired
protected IOauthRestConfig restConfig;
private javax.net.ssl.SSLSocketFactory sslSocketFactory;
private SSLContext sslContext;
private ApplicationContext applicationContext;
static private final ObjectMapper mapper = new ObjectMapper()
.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,
false).setSerializationInclusion(
JsonSerialize.Inclusion.NON_NULL);
/**
*
*/
static final String DEFAULT_CONTENT_TYPE = "application/json"; //$NON-NLS-1$
private PoolingHttpClientConnectionManager poolManager;
/**
*
*/
public RestClientImpl()
{
super();
}
#PostConstruct
private void init()
{
setupSecureContext(this.restConfig.getOauthCertLocation(), this.restConfig.getOauthCertPassword());
poolManager = new PoolingHttpClientConnectionManager();
if(poolManager !=null ) {
poolManager.setMaxTotal(this.restConfig.getOauthPoolMaxSize());
poolManager.setDefaultMaxPerRoute(this.restConfig.getOauthPoolMaxSize());
}
}

Do not include * while specifying the basePackages attribute in the #ComponentScan Annotation.
So replace the same with the code below -
#ComponentScan(basePackages={"com.tcs.timeseries","com.ge.predix.solsvc.restclient.config", "com.ge.predix.solsvc.restclient.impl"})
This will properly scan the packages and sub-packages.

The issue was with the profile declaration, in properties file where I need to mention as local. After I created application.properties file in config folder and put this line spring.profiles.active=local , it was able to inject RestClient bean without any issue

Related

Spring AOP: UnsatisfiedDependencyException error with configuration with annotation

I'm having a trouble while configuring Spring AOP.
I created an aspect class which is below:
#Slf4j
#Aspect
#RequiredArgsConstructor
#Component
public class LoggingAspect {
private static final Logger logger = CommonLogger.getLogger(LoggingAspect.class);
private final ObjectMapper mapper;
private final JobExecutionService jobExecutionService;
}
Then I added a configuration file:
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass = true)
#RequiredArgsConstructor
public class AspectConfiguration {
private final ObjectMapper objectMapper;
private final JobExecutionService jobExecutionService;
#Bean
public LoggingAspect loggingAspect() {
return new LoggingAspect(objectMapper, jobExecutionService);
}
}
But when I started the application, I am getting below errors:
Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.context.support.ClassPathXmlApplicationContext]: Constructor threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'aspectConfiguration' defined in URL: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I have added aspectjrt and aspectjweaver dependencies to pom.xml.
Spring version is 4.3.6
I couldn't figure out where the problem is. Any help would be appreciated.
Add class:
#Configuration
public class BeanConfig {
#Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

Autowire class with arguments in constructor fails

I have the following class :
public class ProducerWrapper<K, V> {
Producer<K, V> producer;
ThreadPoolExecutor threadPoolExecutor;
#Autowired
public ProducerWrapper(Properties p, int poolsize) {
......
log.info("Created kafka producer");
}
....
I try to inject it in a different service :
#Service
public class mainService{
#Qualifier("ProducerX")
#Autowired
private ProducerWrapper<Long,CustomObject1> p1;
#Autowired
#Qualifier("ProducerY")
private ProducerWrapper<Long,CustomObject2> p2;
And I created the following configuration :
#Configuration
#ComponentScan("main_package..")
public class MyConf {
#Bean(name = "ProducerX")
public ProducerWrapper<Long, CustomObject1> createProducerWrapper() throws IOException {
FileInputStream propertiesFile = new FileInputStream("producerx.properties");
properties = new Properties();
properties.load(propertiesFile);
return new ProducerWrapper<>(properties,5);
}
#Bean(name = "ProducerY")
public ProducerWrapper<Long, CustomObject2> createProducerWrapper() throws IOException {
FileInputStream propertiesFile = new FileInputStream("producery.properties");
properties = new Properties();
properties.load(propertiesFile);
return new ProducerWrapper<>(properties,5);
}
}
As you can see I have a different properties file for each producer. The error I'm getting is the following :
Error creating bean with name 'ProducerWrapper' defined in file [..../ProducerWrapper.class]: Unsatisfied dependency expressed through constructor parameter 1;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'int' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Parameter 1 of constructor in com.xx.xx.ProducerWrapper required a bean of type 'int' that could not be found.
If I remove the autowired annotation on top of the constructor, I'm getting a different error that the default constructor can't be found by Spring.
In addition, in the logs I see the following message that indicates that everything in the constructor was run :
2020-06-24 12:14:49.331 INFO 30912 --- [ main] c.a.a.ProducerWrapper : Created kafka producer
What am I doing wrong ?
You have this signature:
#Autowired
public ProducerWrapper(Properties p, int poolsize) {
...
You have not provided the "poolsize" parameter to be autowired. i.e. there's no integer that exists in your config that can be autowired into this variable.
To resolve this: Create a PoolSize class that wraps an int value. Then create a PoolSize object in your config to be autowired.
It says in the error output:
...No qualifying bean of type 'int' available: expected at least 1 bean which qualifies as autowire candidate.
I found the solution in the following stackoverflow post
Bottom line :
The constructor in the ProducerWrapper class shouldn't have any annotation :
//None annotation above constructor
public ProducerWrapper(Properties p, int poolsize) {
......
log.info("Created kafka producer");
}
Create a configuration class for the beans just like I pasted in my main comment.
3.Remove the Service annoatipn from the ProducerWrapper

Spring application context has my bean but #autowired doesn't see it

I am trying to configure my Spring Boot application with annotations and to use #Autowired annotation in it. When I check whether I have my Bean loaded or not, it is loaded, but with #Autowired it says NoSuchBeanDefinitionException
As you can see further I tried to check if my Beans were actually loaded, so when I run my application, I can see my Bean's name in the console.
Also, I tried to add 'scanBasePackages = "com.log.iei.Logistica"' to my #SpringBootApplication annotation, but it changed nothing.
Also, I tried field autowiring
Here is my main class:
#SpringBootApplication(scanBasePackages = "com.log.iei.Logistica")
public class LogisticaApplication extends Application {
public static ConfigurableApplicationContext context;
#Override
public void init() throws Exception {
SpringApplicationBuilder builder = new SpringApplicationBuilder(AppConfig.class);
context = builder.run(getParameters().getRaw().toArray(new String[0]));
String[] beanNames = context.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}
Here is part of VehicleService class:
#Component("vehicleService")
public class VehicleService implements IDao<VehicleEntity> {
private static VehicleService vehicleService;
GenericDao<VehicleEntity> dao;
public VehicleService(){
dao = new GenericDao<>(VehicleEntity.class);
System.out.println("==== VehicleService was created ====");
}
Here is part of #Autowired part:
#Component("cargoPage")
public class CargoPage extends TablePageTemplate {
#Autowired
public CargoPage(VehicleService vehicleService){
getAboveTableLine().getChildren().addAll(getAboveTableLineSetup());
setTable(getTable(), vehicleService.findAll(), VehicleEntity.getTableMapping());
And here is an error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.log.iei.Logistica.data.controllers.Services.VehicleService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760)
... 24 more
UPD: Maybe the problem is with VehicleService implementing Generic interface.
First, you have to set your base package to this:
#SpringBootApplication(scanBasePackages = "com.log")
You mapped everything correctly, however, the constructor used to #Autowire beans is not supposed to invoke any other logic. If you need to do something right after bean initialization use #PostConstruct.
This is how your code would look like:
#Service
public class CargoPage extends TablePageTemplate {
private VehicleService vehicleService;
#Autowired
public CargoPage(VehicleService vehicleService) {
this.vehicleService = vehicleService;
}
#PostConstruct
public void init() {
getAboveTableLine().getChildren().addAll(getAboveTableLineSetup());
setTable(getTable(), vehicleService.findAll(), VehicleEntity.getTableMapping());
}
}
You should check if your files are inside base packages.
For example, if you have:
com.log
.service
VehicleService.java
CargoPage.java
LogisticaAplication.java
So, inside your LogisticaApplication.java, you should add the base as the following:
#SpringBootApplication(scanBasePackages = "com.log")
public class LogisticaApplication extends Application {
public static ConfigurableApplicationContext context;
#Override
public void init() throws Exception {
SpringApplicationBuilder builder = new SpringApplicationBuilder(AppConfig.class);
context = builder.run(getParameters().getRaw().toArray(new String[0]));
String[] beanNames = context.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
}

Autowiring fails in Junit testing and spring #configuration

I have two #Configuration classes. I need a bean from one configuration class to another. I have autowired the configuration 1 into 2. All works fine. When executing the unit testing, am getting the below exception.
setUpContext(com.trafigura.titan.framework.services.messaging.loader.SpringLoadTest)
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.xxx.MessagingServicesConfig': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.EMSJMSConfig com.xxx.MessagingServicesConfig.emsJmsConfig;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type[com.xxx.EMSJMSConfig] 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)}
Is there anything I need to do additionally to make this working?
Below is the setup for testing.
#Configuration
#Import({MessagingServicesConfig.class,...,EMSJMSConfig.class
})
public class MessagingConfig {}
#Profile("EMS-MESSAGING")
#Configuration
public class EMSJMSConfig {
#Bean
public javax.jms.ConnectionFactory jmsSubscriberConnectionFactory() throws JMSException {
SingleConnectionFactory singleConnectionFactory = new SingleConnectionFactory(tibjmsConnectionFactory());
return singleConnectionFactory;
}
}
#Configuration
public class MessagingServicesConfig {
#Autowired
private EMSJMSConfig emsJmsConfig;
#Bean(destroyMethod = "shutdown")
public MessagingService messagingService() throws JMSException {
...
ConnectionFactory cf=emsJmsConfig.jmsSubscriberConnectionFactory(); // Getting NPE at this line.
}
}
and finally the test class,
public class MessagingServicesConfigTest {
private MessagingServicesConfig config;
private EMSJMSConfig emsJmsConfig;
#BeforeMethod
public void setUp() throws Exception {
config = new MessagingServicesConfig();
... //what needs to be done here to have the EMSJMSConfig
}
#Test
public void testBuildsCorrectService() throws JMSException {
MessagingService service = config.messagingService();
...
}
}
By calling new you're creating object yourself, Spring doesn't know anything about it.
Moreover, you should have a test configuration which will be aware of your beans.
Use an appropriate Runner to load SpringContext.
#ContextConfiguration(classes = TestConfig.class)
#RunWith(SpringRunner.class)
class Tests {
#Autowired // if needed
private MessagingServicesConfig config;
}
While in TestConfig you can create beans or import configuration from the Application:
#Configuration
#Import({MessagingServicesConfig.class})
public class TestConfig {}
#Configuration
#Import({EMSJMSConfig.class})
public class MessagingServicesConfig {}
Or you can refer to your config classes directly:
#ContextConfiguration(classes = {MessagingServicesConfig.class, EMSJMSConfig.class})

How could I get #FeignClient bean when spring boot application initializing

I need use a bean inject with #Component #FeignClient(name = "xxx") when my spring boot application initializing, but it always throws exception like this:
20180706 10:18:40,043 WARN [main]
[org.springframework.context.annotation.AnnotationConfigApplicationContext]
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'feignContract' defined in org.springframework.cloud.netflix.feign.FeignClientsConfiguration: Unsatisfied dependency expressed through method 'feignContract' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feignConversionService' defined in org.springframework.cloud.netflix.feign.FeignClientsConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.format.support.FormattingConversionService]: Factory method 'feignConversionService' threw exception; nested exception is java.lang.StackOverflowError
my feignClient code:
#Component
#FeignClient(name = "domain-account")
public interface IDomainService {
#RequestMapping(value = "/userInfos", method = RequestMethod.GET)
public String getUserInfos(#QueryMap Map<String, Object> condition);
}
ApplicationListenner code:
public class GlobalInit implements ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
System.out.println("======== GlobalInit ========");
IDomainService domainService = contextRefreshedEvent.getApplicationContext().getBean(IDomainService.class);
System.out.println("*********************" + domainService);
GlobalInitManager.getInstance().doInit();
}
}
It's not entirely clear for me what you try to do with the GlobalInit but the 'standard' way of designing your Feign client in Spring Boot would the following:
#SpringBootApplication
#EnableFeignClients
#EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
#EnableCaching
public class MyHelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(MyHelloWorldApplication.class, args);
}
}
#Component
public class HelloWorldServiceImpl implements HelloWorldService {
#Autowired
private IDomainService iDomainService ;
public void myMethod() {
String userinfo = iDomainService.getUserInfos(...);
}
}
Hopefully this helps.
All the best,
Wim

Categories