3

I know this question is a duplicate of Execute method on startup in spring. however I have tried the advice posted in the accepted answer for that question, and nothing has worked for me. As such, I suspect that although it is the same question being asked here, I strongly feel that the root cause is different and thus requires a different answer/solution.

I am trying to get Spring to create a bean at start up and immediately execute one of its methods.

My spring config (heartbeat-config.xml):

<beans (all the xmlns stuff here ommitted for brevity)>
    <bean id="heartbeat" class="org.me.heartbeat.Heartbeat"/>
</beans>

And Heartbeat.java:

public class Heartbeat
{
    @PostConstruct
    public void start()
    {
        System.out.println("I should see this message in the logs somewhere!!");
    }
}

And finally, my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

    <!-- The display name of this web application -->
    <display-name>Heartbeat</display-name>

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

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</web-app>

When I run this in Tomcat I don't get any startup errors. Tomcat looks like its running healthy (as I can tell from the logs). I do not, however, see any output in the logs that should be generated by the System.out invocation in my start() method (Tomcat redirects all standard output to its log files).

Am I overlooking something here? Is there an obvious diagnosis I could be performing?

Community
  • 1
  • 1
IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756
  • You need to tell us what happened when you tried the solution from the other question, else we don't know how to answer differently, and this would still be a duplicate. – skaffman Feb 07 '12 at 20:32
  • Alternatively can you not execute this from a constructor? – flurdy Feb 07 '12 at 20:37
  • Ahhh, the only change I made from the other question was adding the `@PostConstruct` annotation. Same results either way, hence the solution did not work for me whereas it did work for the other asker. – IAmYourFaja Feb 07 '12 at 20:39
  • flurdy what would my other options be? Can you post an example? Thanks! – IAmYourFaja Feb 07 '12 at 20:40
  • Not sure it's the solution, but the API doc of ContextLoader uses `WEB-INF/applicationContext.xml`, and not `/WEB-INF/applicationContext.xml`. No leading slash. Could you put some debugging in the Heartbeat constructor to see if it's instantiated or not (or even start tomcat in debug mode). – JB Nizet Feb 07 '12 at 20:41
  • or this http://stackoverflow.com/a/3434449/706695 ? – HRgiger Feb 07 '12 at 20:43
  • Good suggestioned JB Nizet! Now we're getting somewhere. I put an output statement in the (added) constructor and saw it show up in the logs. I did not have to remove that leading slash (and actually, this web.xml is a near-clone of another one used in a perfectly-functioning WAR, so I know thats not the issue). Any ideas as to why I can instantiate the bean but not call its `start()` method?!?! – IAmYourFaja Feb 07 '12 at 20:47
  • HRigger - where would I place that context element? Under the `` element or inside my Heartbeat bean? – IAmYourFaja Feb 07 '12 at 20:48

1 Answers1

4

The most simple way to do that is to forget about annotations and change your bean definition to:

<bean id="heartbeat" class="org.me.heartbeat.Heartbeat" init-method="start"/>

If you want annotations you need to declare the context namespace and put this int your applicationContext.xml:

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

    <!-- Enable @PostConstruct, @PreDestroy and friends in Spring -->
    <context:annotation-config/>

    <bean id="heartbeat" class="org.me.heartbeat.Heartbeat"/>
</beans>

Note: check the namespaces, they are copypasted from the net.

gpeche
  • 21,974
  • 5
  • 38
  • 51