0

Whoever answers correct will be rewarded My Implementation is as follows:

NextShipmentDaoImpl.java

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

LoginController.java

@Controller  
public class LoginController {  

      @Autowired
      private NextShipmentDao nextShipmentDao;

      public void setNextShipmentDao(NextShipmentDao nextShipmentDao) {
        this.nextShipmentDao = nextShipmentDao;
     }

While Creating the required above bean like this:

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

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"  
 xmlns:tx="http://www.springframework.org/schema/tx"  
 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  
http://www.springframework.org/schema/tx  
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
<property name="driverClassName" value="com.mysql.jdbc.Driver" />  
<property name="url" value="jdbc:mysql://localhost:3306/board" />  
<property name="username" value="root" />  
<property name="password" value="root" />  
</bean>

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>

 <security:http auto-config="true" >  
 <security:intercept-url pattern="/index*" access="ROLE_USER" />  
 <security:form-login login-page="/login.htm" default-target-url="/index.htm"  
  authentication-failure-url="/loginerror.htm" />  
 <security:logout logout-success-url="/logout.htm" />  
 </security:http> 


<context:component-scan base-package="com.ibrahim.controller,com.ibrahim.domain,com.ibrahim.dao" />  

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
<property name="viewClass"  value="org.springframework.web.servlet.view.JstlView" />  
<property name="prefix" value="/WEB-INF/views/" />  
<property name="suffix" value=".jsp" />  
</bean>
</beans>

Everything works fine. But when I try to create a bean This shows the error

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ibrahim.dao.NextShipmentDao com.ibrahim.controller.LoginController.nextShipmentDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    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:628)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4728)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5166)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.ibrahim.dao.NextShipmentDao com.ibrahim.controller.LoginController.nextShipmentDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 22 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'nextShipmentDao' defined in ServletContext resource [/WEB-INF/board-dao.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1007)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    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.findAutowireCandidates(DefaultListableBeanFactory.java:912)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 24 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ibrahim.dao.NextShipmentDaoImpl]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1000)
    ... 35 more
Caused by: java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.jdbc.support.JdbcAccessor.afterPropertiesSet(JdbcAccessor.java:134)
    at org.springframework.jdbc.core.JdbcTemplate.<init>(JdbcTemplate.java:165)
    at com.ibrahim.dao.NextShipmentDaoImpl.<init>(NextShipmentDaoImpl.java:28)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    ... 37 more

May 07, 2015 12:21:48 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
May 07, 2015 12:21:48 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/13.1SecuringUrlAcces] startup failed due to previous errors
May 07, 2015 12:21:48 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
May 07, 2015 12:21:48 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
May 07, 2015 12:21:48 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
May 07, 2015 12:21:48 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 12402 ms

Here's My NextShipmentDaoImpl.java

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    JdbcTemplate jdbcTemplate= new JdbcTemplate(dataSource);

    @Override
    public List<NextShipment> display() {

        String sql = "SELECT * FROM NEXTSHIPMENT";

        List<NextShipment> shipments = new ArrayList<NextShipment>();
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql);
        for (Map row : rows) {
            NextShipment shipment = new NextShipment();
            shipment.setOid((String) row.get("OID"));
            shipment.setAddress((String) row.get("ADDRESS"));
            shipment.setPack_Date((Date) row.get("PACK_DATE"));
            shipment.setIsAvailable((Boolean) row.get("ISAVAILABLE"));
            shipment.setAssignShipper((String) row.get("ASSIGNSHIPPER"));
            shipment.setInTransit((Boolean) row.get("InTransit"));
            shipments.add(shipment);
        }
        return shipments;
    }
}
MS Ibrahim
  • 1,789
  • 1
  • 16
  • 28
  • 2
    When you post code, post the code as it actually is, your code doesn't match what is being told in the stack trace. You are creating a `JdbcTemplate` in the constructor at that point the datasource is still null. Use constructor injection instead. – M. Deinum May 07 '15 at 07:06
  • As of now Constructor injection is not used, If I used it then it shows error on the constructor mapping insisting us to define the index/type/name of the member that we r trying to pass – MS Ibrahim May 07 '15 at 07:11
  • With a single constructor argument that isn't true (or you are doing things the wrong way). Also it is a required so it doesn't really make sense to have a setter for that... – M. Deinum May 07 '15 at 07:12
  • I'm having only setter method.There's no constructor in my codings. stack trace says that it as constructor – MS Ibrahim May 07 '15 at 07:12
  • . Here you are referring the dataSource bean. Have you created this `dataSource` bean – Ronald Randon May 07 '15 at 07:17
  • @Deinum.. Used both constructor and setter it shows different errors on creating beans. What u actually think of this scenario as of now. – MS Ibrahim May 07 '15 at 07:17
  • I will add my complete xml file guys please wait – MS Ibrahim May 07 '15 at 07:18
  • The stack trace tells me that you are trying to instantiate a `JdbcTemplate` in the constructor (or you are extending `JdbcDaoSupport`) and that isn't working if there isn't a datasource. Either way I highly doubt that the code you posted is the code you actually run. – M. Deinum May 07 '15 at 07:20
  • trying to declare beans for JdbcDaoImpl class, Not yet extending JdbcDaoSupport – MS Ibrahim May 07 '15 at 07:24
  • I keep repeating myself but the stack trace tells a different story then your code. So either the stack trace isn't the one belonging to this code or the code doesn't belong to the stack trace (or the code isn't what you actually have). As mentioned the stack trace clearly indicates you are trying to instantiate a `JdbcTemplate` in the constructor of the `NextShipmentDaoImpl ` at that point no datasource eis injected. How could spring inject something into something that doesn't exists. A bean instance only exists after the call to the constructor after which setters will be called. – M. Deinum May 07 '15 at 08:45
  • Previously I had constructor and I removed it since it doesn't work. But stack trace is showing constructor invoked.. How shall i remove that – MS Ibrahim May 07 '15 at 08:58
  • 1
    @M.Deinum Do u want me to show the NextShipmentDaoImpl – MS Ibrahim May 07 '15 at 09:00
  • Yes the actual `NextShipmentDaoImpl` and not some that you think is enough for here (as the stack trace clearly indicates something else).... – M. Deinum May 07 '15 at 09:15
  • @MS Ibrahim it will be really helpful if you can list down all jar you are using in your project!!! – Dev May 08 '15 at 12:58
  • @Dev I found the answer Thanks a lot bro – MS Ibrahim May 08 '15 at 13:37
  • has any answer helped to resolve your problem?,If yes please accept one or if you figure out all by yourself then edit your question and put details what was wrong and how you resolved you problem, should give closer to your question....thanks ... – Dev May 08 '15 at 13:44

3 Answers3

0

The times of the XML-based configuration are over.

I strongly recommend you to use Annotated Configuration

Something like this:

@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan(basePackages = "com.myapp.*")
public class AppConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public DataSource myDataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("<full.driver.class.name>");
        dataSource.setUrl("url");
        dataSource.setUsername("dit");
        dataSource.setPassword("pass");

        return dataSource;
    }

    [...] other Beans like TransactionManager....

}
alex
  • 8,904
  • 6
  • 49
  • 75
  • [Annotations have their use, but they are not the one silver bullet to kill XML configuration. I recommend mixing the two!](http://stackoverflow.com/a/183401/1225328) – sp00m May 07 '15 at 07:53
  • @sp00m The referenced answer is now a bit old, even if there's nothing wrong with it. Spring Java configuration has now other advantages (unsure it existed in 2008) and is heavily based on annotations. But I do agree that XML is **far** from being deprecated, and there are still some (rare) cases where XML is the only way. – Serge Ballesta May 07 '15 at 08:23
  • @sp00m I'm not sure it makes sense to use 7 years old answer as reference. Mixed configuration is hard to maintain, because the configuration is spread over several files. – alex May 07 '15 at 09:24
0

The stacktrace says :

  • you correctly autowire nextShipmentDAO in loginController
  • but dataSource property is null is the NextShipmentDAOImpl bean
  • and the exception occurs in JdbcTemplate initialization

The NextShipmentDAOImpl gives the cause : you correctly inject the datasource, but initialize the JdbcTemplate at construction time. So here is what happens :

  • jvm creates a NextShipmentDaoImpl object
  • jvm initializes all fields of the object including jdbcTemplate
  • spring sets the datasource field ... too late !

[It had been noted in comments by @M.Deinum, but I did not give it enough attention]

You shall never use an injected field at creation time, because at that moment it has not been injected. You should instead use an initialization method called by spring after all properties have been set :

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    JdbcTemplate jdbcTemplate;

    void init(void) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }

and declare the bean that way :

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl" 
    init-method="init">
<property name="dataSource" ref="dataSource"></property>
</bean>
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • All my xml files are loaded. I'll check and come back to you. – MS Ibrahim May 07 '15 at 07:55
  • Do you think that mixing annotations and defining a bean manually for data Source Configuration may lead to error – MS Ibrahim May 07 '15 at 09:03
  • @MSIbrahim Spring explicitely allows mixing annotations, Java configuration and XML files. And it can make sense, provided you know what configuration files are used and how they are. Here, what is `board-dao.xml`? – Serge Ballesta May 07 '15 at 09:48
  • I had seperated dao specific beans to board-dao.xml similarly board-servlet.xml board-service.xml board-security.xml – MS Ibrahim May 07 '15 at 10:00
  • I am experiencing this only in spring3.2.4 in spring2.5.6 and spring 4.0.1 I had not experienced bean creation exception whether shall I use spring 4.0.1 jar files.. – MS Ibrahim May 07 '15 at 10:06
  • @MSIbrahim : Spring allows same bean to be declared in many XML files. In that case, the last declaration read will win. That means that if board-dao.xml if read after applicationcontext.xml and contains `` with no reference to datasource, the datasource will **not** be injected. – Serge Ballesta May 07 '15 at 10:26
  • Files are different, No beans are going to be same in my 4 diff config files, – MS Ibrahim May 07 '15 at 10:46
  • @MSIbrahim : I got it. The cause was in NextShipmentDaoImpl. – Serge Ballesta May 07 '15 at 11:58
  • What's there in NextShipmentDaoImpl – MS Ibrahim May 07 '15 at 12:09
0

NextShipmentDaoImpl.java looks like this

public class NextShipmentDaoImpl implements NextShipmentDao{

    private DataSource dataSource;

    JdbcTemplate jdbcTemplate;

    public NextShipmentDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

In the above lines of code I had declared JdbcTemplate inside its implementation function itself. Where it is used.

And the relevant bean I had declared is:

<bean id="nextShipmentDao" class="com.ibrahim.dao.NextShipmentDaoImpl">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>

LoginController remains the same:

@Controller  
public class LoginController {  

     @Autowired
      private NextShipmentDao nextShipmentDao;

       public void setNextShipmentDao(NextShipmentDao nextShipmentDao) {
        this.nextShipmentDao = nextShipmentDao;
     }

I had shifted my spring and spring security jars from 3.2.4 to 3.2.7 Problem got solved in this manner.

MS Ibrahim
  • 1,789
  • 1
  • 16
  • 28