0

I am having a strange issue with Spring PropertyPlaceholderConfigurer

All the JUnit tests pass, but when I start Tomcat, I run into a properties initialization issue:

// First root initialization, the properties are fine
[...]
INFO: Initializing Spring root WebApplicationContext
14:21:13.195 INFO  [QuartzProperties] - QuartzProperties: false 0 0/30 * * * ? true 18:00 1

// Second 'servlet' initialization, the properties are empty
[...]
INFO: Initializing Spring FrameworkServlet 'global'
14:21:16.133 INFO  [QuartzProperties] - QuartzProperties: false  false ${quartz.triggertime} 0

The servlet context initialization doesn't use the properties, and triggers a crash of the Quartz library (invalid values).

I see nothing wrong in the configuration and don't really understand what's going on:

web.xlm

[...]
<servlet>
    <servlet-name>global</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>global</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:/applicationContext.xml
    </param-value>
</context-param>

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

applicationContext.xml

<bean id="allProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
    <property name="ignoreResourceNotFound" value="false" />
    <property name="locations">
        <list>
            <value>file:///${WEBSITE_HOME}/conf/jdbc.properties</value>
            <value>file:///${WEBSITE_HOME}/conf/hibernate.properties</value>
            <value>file:///${WEBSITE_HOME}/conf/quartz.properties</value>
        </list>
    </property>
</bean>

The WEBSITE_HOME value comes from the OS environment.

Have anyone an idea as why the properties are empty in the global servlet init?

Guillaume F.
  • 5,905
  • 2
  • 31
  • 59
  • Your actual problem is why are your beans (and thus your whole application) loaded twice! (your quartz stuff shouldn't run twice!). Also the `PropertyPlaceholderConfigurer` only works for the context it is defined it (the `ContextLoaderLIstenert`) it will not work for dependent contexts (the `DispatcherServlet`). It is a `BeanFactoryPostProcessor` and that (luckily) only operates on the same context it is defined in. – M. Deinum Apr 14 '17 at 13:51
  • Thanks for your comment. I've read that double Spring init is common. Look at this answer : http://stackoverflow.com/a/20753902/5444618 - What do you think? – Guillaume F. Apr 14 '17 at 14:03
  • No it isn't... It means you are loading your application twice and you shouldn't as that will eventually lead to strange to debug issues, transactional problems, database issues, memory issues. Yes you have 2 context, but those context should contain different beans and not the same... – M. Deinum Apr 14 '17 at 18:55
  • They are two different beans. But the servlet context bean doesn't load the properties, only the root bean does, which is what confuses me. It would be easier if only one bean was created for sure... – Guillaume F. Apr 14 '17 at 20:08
  • 1
    As I stated in my other comment, the `PropertyPlaceholderConfigurer` operates in the same context it is loaded in. To have it work in the servlet context as well you have to define it again. But why do you need two schedulers you should have need for 1... – M. Deinum Apr 17 '17 at 08:45

1 Answers1

2

You need to include the init param also in the servlet definition.

<init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:/applicationContext.xml</param-value>
</init-param>

[...]
<servlet>
    <servlet-name>global</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:/applicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>global</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:/applicationContext.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Guillaume F.
  • 5,905
  • 2
  • 31
  • 59
Gurpreet Singh
  • 380
  • 4
  • 9