I have 2 classes in 2 different projects, and I have some difficulties to autowire a field.
In project pack, I have this Computation class :
package fr.aaa;
#Component
public class Computation {
#Autowired
#Qualifier("curveDAO")
CurveAccess curveDAO;
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
}
}
In project db, I have this CurveAccess interface :
package com.bbb
public interface CurveAccess {
// some methods
}
implemented by a CurveDAO class :
package com.bbb.impl
#Repository("curveDAO")
#Transactional("cvaTxManager")
public class CurveDAO implements CurveAccess {
// some methods
}
My applicationContext.xml file from pack project :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
xmlns:security="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
<import resource="classpath:spring/persistence.xml"/>
<context:annotation-config />
<context:component-scan base-package="fr.aaa.*, com.bbb.*"/>
<util:properties id="jdbcProps" location="jdbc.properties" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:configuration.properties</value>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
When running, I have this exception :
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Computation': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.bbb.CurveAccess fr.aaa.Computation.curveDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.bbb.CurveAccess] 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=curveDAO)}
How can I solve this problem ?
Actually, your code works perfectly fine:
#SpringBootApplication
public class So21481801Application implements CommandLineRunner {
public interface CurveAccess {
String hello();
}
#Repository("curveDAO")
public class CurveDAO implements CurveAccess {
#Override
public String hello() {
return "Hello";
}
}
#Repository("curveDAOWorld")
public class CurveDAOWorld implements CurveAccess {
#Override
public String hello() {
return "World";
}
}
#Autowired
#Qualifier("curveDAO")
CurveAccess curveDAO;
#Autowired
#Qualifier("curveDAOWorld")
CurveAccess curveDAOWorld;
#Override
public void run(String... args) {
System.out.println(curveDAO.hello());
System.out.println(curveDAOWorld.hello());
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(So21481801Application.class, args);
context.close();
}
}
Probably you have some problem on how you are using the component-scan configuration on XML and the Java annotations. Mix them is not a good idea.
You need a class that implements CurveAccess interface
#Component
public class CurveAccessImpl implements CurveAccess {
//methods
}
Also remove Qualifier from curveDao in Computation bean since there is no such bean with id curveDao.
#Autowired
CurveAccess curveDAO;
Related
I want to find a solution to configure my spring to support multi-level inheritance of interfaces.The considered scenario is as follow:
public class MainClass {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) ctx.getBean("textEditor");
te.spellCheck();
}
//--------------------
#Component
public class TextEditor {
#Autowired
private SpellChecker1 spellChecker;
public void spellCheck() {
spellChecker.checkSpelling();
}
}
//--------------------
public interface SpellChecker1 extends SpellChecker2{
}
//--------------------
public interface SpellChecker2 {
public void checkSpelling();
}
//--------------------
#Service
public class SpellCheckerImpl implements SpellChecker2 {
public SpellCheckerImpl() {
System.out.println("Inside SpellChecker constructor.");
}
#Override
public void checkSpelling() {
System.out.println("Inside checkSpelling.");
}
}
//--------------------
Also, my Beans.xml file is contain:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.mycompany.test"/>
<bean id="textEditor" class="com.mycompany.test.TextEditor" >
</bean>
</beans>
//The following error is issued when running the the MainClass
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'textEditor': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mycompany.test.SpellChecker1 com.mycompany.test.TextEditor.spellChecker; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mycompany.test.SpellChecker1] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
i have just started a course about Spring framework and i am struggling getting over this exceiption:
Exception in thread "main" org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [TrackCoach] for bean with name 'myCoach' defined in class path resource [applicationContext.xml]; nested exception is java.lang.ClassNotFoundException: TrackCoach
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1476)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:649)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1604)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1080)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:859)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at com.love2code.springdemo.HelloSpringApp.main(HelloSpringApp.java:9)
This is my main class:
package com.love2code.springdemo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpringApp {
public static void main(String[] args) {
//load the spring configuration file
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//retrieve bean from spring container
Coach theCoach = context.getBean("myCoach", Coach.class);
//call methods on the bean
System.out.println(theCoach.getDailyWorkout());
//close the context
context.close();
}
}
My TrackCoach class:
package com.love2code.springdemo;
public class TrackCoach implements Coach {
#Override
public String getDailyWorkout() {
return "Smoke 2 bl's";
}
}
And applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Define your beans here -->
<bean id="myCoach" class="com.luv2code.springdemo.TrackCoach">
</bean>
</beans>
Could someone help me out with this please?
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.spring.dto.Car2' available
Controller.java -
public class Controller {
public static void main(String[] args) {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("configu.xml");
Car2 c2 = (Car2) context.getBean(Car2.class);
System.out.println(c2);
}
}
Car2.java -
#ToString #Component
public class Car2 {
#Autowired
private Engine engine;
}
Engine.java -
#Setter #ToString
public class Engine {
private String modelYear;
}
configu.xml -
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.spring.dto.Car2" />
<context:annotation-config />
<bean class="com.spring.dto.Engine">
<property name="modelYear" value="2015"></property>
</bean>
</beans>
please ignore the annotation #ToString and #Setter- I am using Lombok project for my simplicity.
I think the error is here:
<context:component-scan base-package="com.spring.dto.Car2" />
The value should be a package, not a class. Change it to "com.spring.dto", then it should work.
My application uses struts and spring frameworks. I have a class FormA which has an autowired property in it. When I try to instantiate it while writing unit tests I get a Null Pointer Exception. Here is my code.
My ClassA:
public class FormA{
private String propertyOne;
#Autowired
private ServiceClass service;
public FormA(){
}
}
My unit test method:
#Test
public void testFormA(){
FormA classObj = new FormA();
}
#Autowired only works when object life cycle is managed by Spring.
You'll need to run your tests with #RunWith(SpringJUnit4ClassRunner.class), and instead of instantiating FormA manually, inject it in the test class as well, using #Autowired.
When you create an object by new, autowire\inject don't work...
as workaround you can try this:
create your template bean of NotesPanel
<bean id="notesPanel" class="..." scope="prototype">
<!-- collaborators and configuration for this bean go here -->
</bean>
and create an istance in this way
applicationContext.getBean("notesPanel");
PROTOTYPE : This scopes a single bean definition to have any number of object instances.
anyway a unit test should be
Test class
#RunWith( SpringJUnit4ClassRunner.class )
#ContextConfiguration(locations = { "classpath:META-INF/your-spring-context.xml" })
public class UserServiceTest extends AbstractJUnit4SpringContextTests {
#Autowired
private UserService userService;
#Test
public void testName() throws Exception {
List<UserEntity> userEntities = userService.getAllUsers();
Assert.assertNotNull(userEntities);
}
}
your-spring-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="userService" class="java.package.UserServiceImpl"/>
</beans>
I have just learnt Spring Framework and have been using Spring 2.5 for this learning. I have created three beans with these classes
Food.java
package com.spring.danipetrick;
public interface Food {
void ingredients();
}
NasiGoreng.java
package com.spring.danipetrick;
public class NasiGoreng implements Food {
public NasiGoreng() {
}
public void ingredients() {
System.out.println("Rice, Coconut oil, Egg, Crackers");
}
#Override
public String toString() {
return "Nasi Goreng";
}
}
Rendang.java
package com.spring.danipetrick;
public class Rendang implements Food {
public void ingredients() {
System.out.println("Beef, Coconut milk, spices");
}
#Override
public String toString() {
return "Rendang";
}
}
PecintaKuliner.java
package com.spring.danipetrick;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class PecintaKuliner {
#Autowired
#Qualifier("nasigoreng")
private Food food;
#Autowired
public void setFood(Food food) {
this.food = food;
}
public Food getFood() {
return this.food;
}
public void sayMaknyus() {
System.out.println(food.toString() + " memang maknyus...");
}
}
Xml configuration, qualifier-test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<bean id="bondan" class="com.spring.danipetrick.PecintaKuliner">
</bean>
<bean id="rendang" class="com.spring.danipetrick.Rendang"/>
<bean id="nasigoreng" class="com.spring.danipetrick.NasiGoreng" />
</beans>
Finally, class with main method is QualifierTestMain.java:
package com.spring.danipetrick;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class QualifierTestMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("/qualifier-test.xml");
PencintaKuliner bondan = (PencintaKuliner)context.getBean("bondan");
bondan.sayMaknyus();
}
}
When I run this project, I have an error like this
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
unique bean of type [com.spring.danipetrick.Food] is defined: expected
single matching bean but found 2: [rendang, nasigoreng]
Why #Qualifier annotation is not working in my case?
Both your method and field are annotated with #Autowired. As such, Spring will try to inject both. On one of the runs, it will try to inject
#Autowired
#Qualifier("nasigoreng")
private Food food;
which will work because the injection target is qualified.
The method however
#Autowired
public void setFood(Food food) {
this.food = food;
}
does not qualify the injection parameter so Spring doesn't know which bean to inject.
Change the above to
#Autowired
public void setFood(#Qualifier("nasigoreng") Food food) {
this.food = food;
}
But you should decide one or the other, field or setter injection, otherwise it is redundant and may cause errors.
I tried with Spring 4.2.4. Problem resolved just by adding
<context:annotation-config /> in configuration file.
Try only removing #Autowired from setFood() in PecintaKuliner
like
#Autowired
#Qualifier("nasigoreng")
private Food food;
public void setFood(Food food) {
this.food = food;
}
Try removing you constructor from the NasiGoreng class. It worked for me.
For others facing issue in Spring 5 -- Use xmlns based configuration..
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>