10

getting some problem into my spring application.

I have very fairly simple spring beans, they are injected into various other spring beans. While debugging I found, they are being called twice, Constructor & @PostConstruct both called two times.

My application have no front end technology. Its simply for backend task related.

Spring 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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:lang="http://www.springframework.org/schema/lang" 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
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-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/lang http://www.springframework.org/schema/lang/spring-lang.xsd">


    <context:component-scan base-package="com.green.integration" />

    <!-- ######################################################## -->
    <!-- EXPOSING SPRING BEAN VIA HTTPINVOKER SPRING REMOTING -->
    <!-- ######################################################## -->

    <bean name="/switch"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="service" ref="SwitchController" />
        <property name="serviceInterface"
            value="com.green.ISwitchController" />
    </bean>

    <!-- Load in application properties reference -->
    <bean id="applicationProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties" />
    </bean>


    <bean id="mongo" class="com.mongodb.Mongo">
        <constructor-arg value="${mongo.server}" />
        <constructor-arg value="${mongo.port}" />
    </bean>

    <bean id="morphia" class="com.google.code.morphia.Morphia">
    </bean>


</beans>

Spring Bean Class

@Repository
public class TransactionDAO extends BasicDAO<Transaction, ObjectId>  {
    private Datastore datastore;

    @Autowired
    public TransactionDAO(Mongo mongo, Morphia morphia) {
        super(mongo, morphia, "itransact");
        morphia.map(Transaction.class);
        // TO USE MONGO WITHOUT SECURITY
        this.datastore = morphia.createDatastore(mongo, "itransact");
        logger.debug("***** CONNECTED TO MONGODB SUCCESSFULLY *****");
        this.datastore.ensureIndexes();
        // this.datastore.ensureCaps();
    }
}

Constructor "TransactionDAO" is being called twice.

I tried to watch call stack trace by

Throwable t = new Throwable();
System.out.println(t.getStackTrace()[1].toString());

and each time it showed the following

sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
Faisal Basra
  • 1,624
  • 4
  • 25
  • 40
  • 1
    Are you absolutely sure `@PostConstruct` is called twice as well? Constructor being called twice can be easily explained, but not `@PostConstruct`. – Tomasz Nurkiewicz May 28 '12 at 20:32
  • 1
    Do you have a dispatcher servlet configuration? – Juan Alberto López Cavallotti May 28 '12 at 20:37
  • Maybe you have your application context xml imported from another context's xml configuration file via ? – Boris Treukhov May 28 '12 at 20:37
  • 1
    Your spring configuration doesn't include the DAO class you listed. There is missing information here. – stevedbrown May 28 '12 at 22:39
  • @JuanAlbertoLópezCavallotti Yeah, I do have a dispatcher servlet for spring httpinvoker. Is it causing the problem? – Faisal Basra May 29 '12 at 05:38
  • @BorisTreukhov Boris, I was having multiple spilt spring config files & importing into one main spring config file. Then I removed all imports and put all config into the main spring file, but it did not make any difference. – Faisal Basra May 29 '12 at 05:40
  • 1
    @JuanAlbertoLópezCavallotti Juan, I verified by removing the dispatcher servlet and beans are once initialized. Its the dispatcher that causing twice initialization. So what's the fix, please? – Faisal Basra May 29 '12 at 05:50
  • What is your environment? Are you sure that your classes are managed by spring only stackoverflow.com/questions/9077966/postconstruct-method-called-twice-for-the-same-request – Boris Treukhov May 29 '12 at 06:07
  • @BorisTreukhov Yeah, all classes are being managed by spring container. – Faisal Basra May 29 '12 at 06:16
  • @FaisalBasra if your dispatcher is scanning the packages then you may be scanning the same beans in two different contexts! – Juan Alberto López Cavallotti May 29 '12 at 13:48
  • @FaisalBasra I'll add it as an answer if it solved the problem – Juan Alberto López Cavallotti May 29 '12 at 13:56
  • @TomaszNurkiewicz _Constructor being called twice can be easily explained, but not @PostConstruct_ ...if called from different contexts in the same JVM, `PostConstruct` is called each time after the constructor; what was the rational behind your comment? – raffian Nov 30 '13 at 22:13

2 Answers2

17

I just figured out the problem and special thanks to @Juan Alberto who give me hint to the problem.

Description: Actually I was giving the one applicationContext.xml file for both contextListner and dispatcher servlet. So 1st bean was initializing for spring core and 2nd time for spring dispatcher.

I spilt the configuration now, into applicationContext.xml and applicationContext-dispatcher.xml which have only their relevant configurations and my beans are initializing once properly.

Problematic Configs

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>


<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

Solved Configs

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>


<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext-dispatcher.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>
Faisal Basra
  • 1,624
  • 4
  • 25
  • 40
  • 4
    I don't understand the what contain we should put in `applicationContext-dispatcher.xml` and what should be put in `applicationContext.xml` – Allan Ruin Mar 11 '14 at 06:56
5

Actually your issue is that you may be defining the beans in the dispatcher servlet and also your spring context, the dispatcher provides a different context but It (a sub context I think) of the main context so the right way to do things is having your main context scan your "model classes" and the dispatcher just only scan for the controllers.

I hope this helps you.