I am trying to use #Autowired Annotation in Spring for Dependency Injection
through a simple program but i give me following error
Exception in thread "main" java.lang.NullPointerException
at Customer.d(Customer.java:8)
at Main.main(Main.java:12)
Through xml configuration it give me correct result.
My xml file
<beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="person" class="Person">
<property name="name" value="khan"/>
</bean>
<bean id="cust" class="Customer"></bean>
</beans>
Customer Class
public class Customer {
#Autowired
private Person p;
public void display(){
System.out.println(p.getName());
}
}
Person Class
public class Person {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
}
Main Class
public class Main {
public static void main(String[] a) {
Resource r=new ClassPathResource("SpringXml.xml");
BeanFactory factory=new XmlBeanFactory(r);
Customer c=(Customer)factory.getBean("cust");
c.display();
}
}
Try like this
public static void main(String[] args) throws Exception {
ApplicationContext context= new ClassPathXmlApplicationContext("SpringXml.xml");
Customer c = (Customer) context.getBean("cust");
c.display();
}
try this :
<bean id="person" class="com.yourpackage.Person">
<property name="name" value="khan"/>
</bean>
<bean id="cust" class="com.yourpackage.Customer">
<property name="p" ref="person"/>
</bean>
dont forget to add your fullpath class package
Related
I was doing some #Autowired annotations in my code where I stumbled upon a doubt. I am getting the name as John even though I have not injected the Employee bean in GetName.java. The bean was getting injected even though I was not autowiring it using any annotation. Is there some specific prerequisite need to be kept in mind while using constructors ?
Employee.Java
package com.sample.employee;
public class Employee {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
GetName.java
package com.sample.salary;
import org.springframework.beans.factory.annotation.Autowired;
import com.sample.employee.Employee;
public class GetName {
// #Autowired
public Employee emp;
// #Autowired
public GetName(Employee emp) {
this.emp = emp;
}
public void displayName() {
System.out.println(emp.getName()); //prints John
}
}
spring.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"
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"
xmlns:context="http://www.springframework.org/schema/context">
<context:annotation-config />
<!-- <context:component-scan base-package="com.sample.employee"/> -->
<bean id="empl" class="com.sample.employee.Employee">
<property name="name" value="John" />
</bean>
<bean id="GetNames" class="com.sample.salary.GetName"/>
</beans>
MainClass.java
package com.sample.employee;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.sample.salary.SalaryCalculator;
public class MainCLass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
GetName cal = (GetName) context.getBean("GetNames");
cal.displayName();
}
}
Am I missing out something?
If there is only one Constructor for a Bean, Spring will do constructor injection and the #Autowired annotation can be omitted.
See https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.html
This feature was added with one of the more recent versions.
Hello i am using constructor injection in my spring demo app when i run this program i got :
java.lang.IllegalArgumentException exception
Anyone have solution where i am wong and whenever i run same program using setter injection it runs perfectly .
Here is my EmployeeBean.java
package cris;
public class Employee {
private int id;
private String name;
public Employee() { }
public Employee(int id,String name) {
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
void show() {
System.out.println(id+" "+name);
}
}
Here is my Address Bean using setter injection
package cris;
public class Address {
private String city,state,country;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String toString()
{
return city+" "+state+" "+country;
}
}
Here is my spring.xml ie spring config file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="a1" class="cris.Address">
<property name="city" value="Tikamgarh"></property>
<property name="state" value="Mp"></property>
<property name="country" value="India"></property>
</bean>
<bean id="e" class="cris.Employee">
<constructor-arg type="int" value="12"></constructor-arg>
<constructor-arg type="String" value="anil"></constructor-arg>
</bean>
</beans>
And here is my Application Main Method
package cris;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("cris/spring.xml");
Employee emp = (Employee)context.getBean("e");
emp.show();
}
}
kindly provide me suggestion where i am wrong so i will catch the exception thanks
The Exception:
Apr 03, 2017 4:16:16 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#27f8302d: startup date [Mon Apr 03 16:16:16 IST 2017]; root of context hierarchy
Apr 03, 2017 4:16:16 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [cris/spring.xml]
Apr 03, 2017 4:16:16 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#17550481: defining beans [a1,e]; root of factory hierarchy
Exception in thread "main" java.lang.IllegalArgumentException
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.asm.ClassReader.<init>(Unknown Source)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass(LocalVariableTableParameterNameDiscoverer.java:112)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:86)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:193)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1049)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at cris.Test.main(Test.java:8)
When filling POJO's, (for what I know) Spring calls the no-arg constructor by default. If you decide to write a cTor with parameters yourself, you will not get a default cTor generated and you'll have to add a no-arg cTor for spring yourself.
public Employee() { }
Add type to your constructor-arg
<constructor-arg type="int" value="12" />
and
<constructor-arg type="java.lang.String" value="anil" />
EDIT
or you can use indexes
<constructor-arg index="0" value="12" />
and
<constructor-arg index="1" value="anil" />
Have spring.xml like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
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.0.xsd">
<bean id="a1" class="cris.Address">
<property name="city" value="Tikamgarh"></property>
<property name="state" value="Mp"></property>
<property name="country" value="India"></property>
</bean>
<bean id="e" class="cris.Employee">
<constructor-arg type="int" value="12"></constructor-arg>
<constructor-arg type="String" value="anil"></constructor-arg>
</bean>
</beans>
EDIT
My example:
spring.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"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="bean" class="Bean">
<constructor-arg index="0" value="Test"/>
<constructor-arg index="1" value="2"/>
</bean>
</beans>
Bean.java
public class Bean {
private String test1;
private int test2;
public Bean(String test1, int test2) {
this.test1 = test1;
this.test2 = test2;
}
public String getTest1() {
return test1;
}
public void setTest1(String test1) {
this.test1 = test1;
}
public int getTest2() {
return test2;
}
public void setTest2(int test2) {
this.test2 = test2;
}
#Override
public String toString() {
return "Bean{" +
"test1='" + test1 + '\'' +
", test2=" + test2 +
'}';
}
}
Test.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
final ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
final Bean bean = (Bean) ctx.getBean("bean");
System.out.println(bean.toString());
}
}
prints:
Bean{test1='Test', test2=2}
I had the same issue and can't figure out why until I read each comment in current post and found out...
Using Spring 3.* and Java 11 that is a compatibility issue. When I downloaded the latest version (Spring 5.*) and set to the CLASSPATH. Then everything works.
I have a simple spring jdbc program but when I run the program I get a queryTimeOut exception.
Here is the complete stackTrace
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/dao/QueryTimeoutException
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:87)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:103)
at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:407)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:519)
at com.test.spring.EmployeeDao.saveEmployee(EmployeeDao.java:14)
at com.test.spring.Test.main(Test.java:13)
Caused by: java.lang.ClassNotFoundException: org.springframework.dao.QueryTimeoutException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 7 more
Table:
create table employee(emp_name varchar2(30),address varchar2(30),salery number(10),emp_id number(10));
Employee.java:
package com.test.spring;
public class Employee {
private String emp_name;
private String address;
private int salery;
private int emp_id;
public Employee()
{
}
public Employee(String emp_name,int emp_id)
{
this.emp_name=emp_name;
this.emp_id=emp_id;
}
public Employee(String emp_name,String address,int salery,int emp_id)
{
this.emp_name=emp_name;
this.address=address;
this.salery=salery;
this.emp_id=emp_id;
}
public String getEmp_name() {
return emp_name;
}
public void setEmp_name(String emp_name) {
this.emp_name = emp_name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getSalery() {
return salery;
}
public void setSalery(int salery) {
this.salery = salery;
}
public int getEmp_id() {
return emp_id;
}
public void setEmp_id(int emp_id) {
this.emp_id = emp_id;
}
}
EmployeeDao.java:
package com.test.spring;
import org.springframework.jdbc.core.JdbcTemplate;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public int saveEmployee(Employee e){
//String query="insert into employee (emp_name,address,salery,emp_id)values(?,?,?,?)";//not getting any exception
String query="insert into employee (emp_name,address,salery,emp_id)values("+e.getEmp_name()+","+e.getAddress()+","+e.getSalery()+","+e.getEmp_id()+")";//getting queryTimeOutException
return jdbcTemplate.update(query);
}
}
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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="mysql" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"></property>
</bean>
<bean id="edao" class="com.test.spring.EmployeeDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans>
Test.java:
package com.test.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
int status=dao.saveEmployee(new Employee("Amit","Pingla",35000,102));
System.out.println(status);
}
}
The error points out that you're missing a class from your classpath. It doesn't mean that specific exception would get thrown during that particular invocation; but it simply doesn't find the class for it.
To add the QueryTimeoutException class in your classpath, you need to add a dependency on the spring-tx module.
You can add this dependency
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
If your are using maven or this one
[group: 'org.springframework', name: 'spring-tx', version: '4.1.6.RELEASE'],
if you are using gradle.
JdbcTemplate has queryTimeout property, you can try to configure it to a desired value.
I am learning spring. while creating one example i got error.
The type ResultSetExtractor is not generic; it cannot be parameterized with arguments <List<Employee>>
I implement the app as below
Employee.java
package com.develop;
public class Employee {
private int id;
private String name;
private float salary;
public Employee(){}
public Employee(int id, String name, float salary){
this.id = id;
this.name = name;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSalary() {
return salary;
}
public void setSalary(float salary) {
this.salary = salary;
}
}
EmployeeDao.java
package com.develop;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
public class EmployeeDao {
private JdbcTemplate template;
public void setJdbcTemplate(JdbcTemplate template) {
this.template = template;
}
public List<Employee> getAllEmployees(){
return template.query("select * from employee",new ResultSetExtractor<List<Employee>>(){
#Override
public List<Employee> extractData(ResultSet rs) throws SQLException,
DataAccessException {
List<Employee> list=new ArrayList<Employee>();
while(rs.next()){
Employee e=new Employee();
e.setId(rs.getInt(1));
e.setName(rs.getString(2));
e.setSalary(rs.getInt(3));
list.add(e);
}
return list;
}
});
}
}
Test.java
package com.develop;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
EmployeeDao dao=(EmployeeDao)ctx.getBean("edao");
List<Employee> list=dao.getAllEmployees();
for(Employee e:list)
System.out.println(e);
}
}
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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="oracle" /> -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/springdatabase" />
<property name="username" value="root" />
<property name="password" value="admin123" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"></property>
</bean>
<bean id="edao" class="com.develop.EmployeeDao">
<property name="template" ref="jdbcTemplate"></property>
</bean>
</beans>
Created Table
CREATE TABLE employee(id number(10),NAME varchar2(100),salary number(10));
The error message clearly sais it:
The ResultSetExtractor is not generic.
The interface was made generic in a newer version of Spring. But anyway, you can still use it's raw form, although you'd be forced you do a cast when working with the result of the extractData() method.
public List<Employee> getAllEmployees(){
return template.query("select * from employee",new ResultSetExtractor(){
#Override
public Object extractData(ResultSet rs) throws SQLException,
DataAccessException {
List<Employee> list=new ArrayList<Employee>();
while(rs.next()) {
Employee e=new Employee();
e.setId(rs.getInt(1));
e.setName(rs.getString(2));
e.setSalary(rs.getInt(3));
list.add(e);
}
return list;
}
});
}
P.S.:
I assume you're using an old version of the Spring Framework, because in the newer version(s), the ResultSetExtractor is actually generic. So, you can either update your Spring version (but be careful, because this might cause you compilation problems and other issues), or stick to the approach used in the code snippet above.
//here I define all classes and interface which i used
//Service interface
public interface CustomerService {
public void addCustomer(CustomerTO cto);
}
//Service class implementation
public class CustomerServiceImpl implements CustomerService {
#Autowired
CustomerDAO cdao=null;
public void addCustomer(CustomerTO cto){
cdao.addCustomer(cto);
}
}
//CustomerTO Class
public class CustomerTO {
private int cid;
private String cname;
private String email;
private long phone;
private String city;
public CustomerTO(int cid, String cname, String email, long phone,
String city) {
this.cid = cid;
this.cname = cname;
this.email = email;
this.phone = phone;
this.city = city;
}
//Setter and Getters
public class JdbcCustomerDAO implements CustomerDAO {
#Autowired
JdbcTemplate jdbcTemp;
public void addCustomer(CustomerTO cto){
String sql="insert into customer values(?,?,?,?,?)";
Object ar[]={cto.getCid(),cto.getCname(),cto.getEmail(),cto.getPhone(),cto.getCity()};
jdbcTemp.update(sql,ar);
}
//Client COde
public class Lab24Client {
public static void main(String[] args) {
ApplicationContext ctc=new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerService c=(CustomerService)ctc.getBean("cs");
//add Customer
CustomerTO cust=new CustomerTO(102,"vsa","vsa#gmail.com",6154,"Pune");
c.addCustomer(cust);
}
//CustomerDAO
public interface CustomerDAO {
public void addCustomer(CustomerTO cto);
}
//spring ApplicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="dataSource class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/vik"/>
<property name="username" value="root"/>
</bean>
<bean id="jdbcTemp" class="org.springframework.jdbc.core.JdbcTemplate" autowire="constructor"/>
<bean id="cdao" class="com.jlc.JdbcCustomerDAO"/>
<bean id="cs" class="com.jlc.CustomerServiceImpl"/>
//CustomerRowMapper
public class CustomerRowMapper implements RowMapper<CustomerTO>{
#Override
public CustomerTO mapRow(ResultSet rs, int rn) throws SQLException {
CustomerTO cto=new CustomerTO();
cto.setCid(rs.getInt(1));
cto.setCname(rs.getString(2));
cto.setEmail(rs.getString(3));
cto.setPhone(rs.getLong(4));
cto.setCity(rs.getString(5));
return cto;
}
}
//when I am running the client i got following excpetion
Exception in thread "main" java.lang.NullPointerException
at com.spring.CustomerServiceImpl.addCustomer(CustomerServiceImpl.java:11)
at com.spring.Lab24Client.main(Lab24Client.java:12)
//Please tell me what mistake i did with code or what's the problem in following program
You have to enable/register annotation config like below code in your xml.
<context:annotation-config/>