#Configuration
public class Class1 {
#Bean
public JavaMailSenderImpl mailSender() {
....
}
}
#Component
public class Class2 {
#Autowired
JavaMailSenderImpl mailSender;
And I still get:
No qualifying bean of type [org.springframework.mail.javamail.JavaMailSenderImpl] 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)}
Could not autowire field: org.springframework.mail.javamail.JavaMailSenderImpl (path_of_where_autowiring); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.mail.javamail.JavaMailSenderImpl] 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)}
The Class1 bean location is in Package1 and the Class2 location is in Package2.
Why my bean is not found? Help
(Also tried this link but didn't helped me)
EDIT
public static void main(String[] args) throws URISyntaxException, IOException {
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);
Implclass nsi = applicationContext.getBean(Implclass.class);
nsi.the_method_here();
}
#Component
public class Implclass implements Implinterface {
#Autowired
JavaMailSenderImpl mailSender;
#Override
public void the_method_here(){
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(sender);
message.setTo(receiver);
message.setSubject(subject);
message.setText(content);
mailSenderService.send(message);
}
}
#Configuration
#ComponentScan
public class SpringConfiguration {
#Bean
public PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertyPlaceholderConfigurer.setLocations(new ClassPathResource("some_property.file"));
propertyPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
return propertyPlaceholderConfigurer;
}
}
EDIT (TREE)
x - src/main/java
x -- package_1
x - Class1
x -- package_2
x - Class2 (ImplClass)
Use #ComponentScan({"Package1", "Package2"})
Can you please try with using different names.
Reference Link : https://dzone.com/articles/playing-sround-with-spring-bean-configuration
#Configuration
public class Class1 {
#Bean
public JavaMailSenderImpl mailSenderWithInjection() {
....
}
}
#Component
public class Class2 {
#Autowired
JavaMailSenderImpl mailSender;
}
you can use#ComponentScan
or
ctx = new AnnotationConfigApplicationContext();
ctx.register(Config.class); // config
ctx.refresh();
// and try
Implclass nsi = ctx.getBean(Implclass.class);
AnnotationConfigApplicationContext can take multiple configuration classes in the constructor. Can you try passing all the configuration files in the constructor as Step-1. Then it can be further debugged to better the solution.
AnnotationConfigApplicationContext(Class<?>... annotatedClasses)
e.g.
ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext(Class1.class, Class2.class, SpringConfiguration.class);
Also, where is your ImplClass, posting a tree structure would have been very helpful.
Related
In my Config I define two beans of the same class that differ in the value of an enum:
#Bean
public MyClass myClassNew() {
return new MyClass(Source.NEW);
}
#Bean
public MyClass myClassOld() {
return new MyClass(Source.OLD);
}
The Class looks like this:
#Component
#RequiredArgsConstructor
public class MyClass {
private final Source source; // Source is an enum
}
When I autowire a bean in a test:
public class MyClassTest {
#Autowired
private MyClass myClassNew;
}
Spring gives me the following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...AClass$Source' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
This is totally weird. Why does Spring trying to find a bean of an enum?
I want to inject a mock into my Springboot application. I get this error:
Error creating bean with name 'ca.company.TestA': Unsatisfied dependency expressed through field 'a'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ca.company.hello.A' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I'm stuck and don't understand how to process. I Defined A to be autowired. What's the problem?
Here is my test file:
#RunWith(SpringJUnit4ClassRunner.class)
public class TestA {
#Autowired
private A a;
private B Bmock;
#Before
public void before() {
Bmock = Mockito.mock(B.class);
ReflectionTestUtils.setField(a, "b", Bmock);
}
#Test
public void testSpeak() {
when(Bmock.writeToScreen()).thenReturn("Everything will be alright");
assert(true);
}
}
here is the config file:
#Configuration
public class Config {
#Bean
public B b() {
return new B();
}
// The error persists whether I define this bean or not
#Bean
public A a() {
return new A();
}
}
And here is the class in question:
#Component
public class A {
#Autowired
private B b;
public void speak() {
System.out.println(b.writeToScreen());
}
}
And finally here is my file structure:
What am I doing wrong, I don't get it.
Your configuration class is not processed by Spring. The simplest way to achieve that is to put #ContextConfiguration(classes = Config.class) in your test class.
I create spring-boot-starter, which registers some bean:
#Configuration
#EnableConfigurationProperties(ClusterJProperties.class)
#ConditionalOnProperty(prefix = "clusterj", name = {"connectString", "dataBaseName"})
public class ClusterJAutoConfiguration {
private final ClusterJProperties clusterJConfigProperties;
#Autowired
public ClusterJAutoConfiguration(ClusterJProperties clusterJConfigProperties) {
this.clusterJConfigProperties = clusterJConfigProperties;
}
#Bean
#ConditionalOnMissingBean
public SessionFactory sessionFactory() {
Properties clusterJProperties = new Properties();
clusterJProperties.setProperty("com.mysql.clusterj.connectstring", clusterJConfigProperties.getConnectString());
clusterJProperties.setProperty("com.mysql.clusterj.database", clusterJConfigProperties.getDataBaseName());
clusterJProperties.putAll(clusterJConfigProperties.getProperties());
return ClusterJHelper.getSessionFactory(clusterJProperties);
}
}
I want using this starter in another module. For this, I created a component, and inject this bean there:
#Component
public class GetEntityHandler implements VoidTreeNodeHandler {
private final SessionFactory sessionFactory;
#Autowired
public GetEntityHandler(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public void handle(TreeContext context, Map<String, Object> parameters) {
//do smth
}
}
But, when, properties clusterj.connectString and clusterj.connectString not present in application.yml, bean SessionFactory not create. It is ok, but GetEntityHandler want to create, and fall with error:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'getEntityHandler' defined in file [GetEntityHandler.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.mysql.clusterj.SessionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
How to make my GetEnityNandler component not be created if the SessionFactory bean is not present in context?
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})
I'm using Spring Boot to bootstrap a spring-data-neo4j application. My unit tests (with no dependencies injected) run fine, but when I try to run an integration test with an #Autowired dependency on a #Service-annotated class, it's failing on a NoSuchBeanDefinitionException.
It seems like the context isn't being loaded in the unit test for some reason, but I've annotated the test with #SpringApplicationConfiguration(classes = AppConfig.class) - is there something else I need to do here?
Configuration class
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages = "net.foo.bar")
#EnableNeo4jRepositories(basePackages = "net.foo.bar.repo")
public class AppConfig extends Neo4jConfiguration {
public AppConfig() {
setBasePackage("net.foo.bar");
}
#Bean(destroyMethod = "shutdown")
#Scope(BeanDefinition.SCOPE_SINGLETON)
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase(filePath);
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(AppConfig.class, args);
}
}
Service class:
package net.foo.bar.core.service
#Service
public class PostService implements EntityService<PostDAO,Post> {
#Autowired
Neo4jTemplate template;
//...
//don't think anything else here is relevant
}
Test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = AppConfig.class)
public class PostTests {
#Autowired
PostService postService;
#Test
public void someTest(){
postService.doSomething();
//...
}
}
Stack trace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'net.foo.bar.PostTests': ....
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [net.foo.bar.core.service.PostService] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 31 common frames omitted
Update:
As a workaround, rather than autowiring my service directly, I tried autowiring a reference to the ApplicationContext and instantiating my service through a call to getBeanOfType() in my setUp() method:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Epublic.class)
public class PostTests {
#Autowired
ApplicationContext ctx;
PostService service;
#Before
public void setUp() {
service = ctx.getBean("postServiceImpl", PostService.class);
}
}
This is working, but I feel like I'm hitting the target but missing the point here...
You don't have basePackages for #ComponentScan. You have only for NeojConfiguration
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages = { "net.foo.bar" })
#EnableNeo4jRepositories(basePackages = "net.foo.bar.repo")
public class AppConfig extends Neo4jConfiguration {
public AppConfig() {
setBasePackage("net.foo.bar");
}
#Bean(destroyMethod = "shutdown")
#Scope(BeanDefinition.SCOPE_SINGLETON)
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase(filePath);
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(AppConfig.class, args);
}
}