Spring 3.1 contextInitializerClasses not Working on WebLogic 10.3.6 using web.xml Context-Param
Asked Answered
M

1

7

I'm trying to read properties from a properties file, whose filename will be different for each of our environments, like local.properties, dev.properties, etc. These properties files will only contain the connection information for their corresponding mongodb instances like host, port, and dbname. Normally this sort of thing would be done with a JNDI definition in our app server, but there are no implementations of that for Mongo currently.

Since I am using WebLogic 10.3.6, I am not able to use the Servlet 3.0 specification and therefore cannot use Java-configuration for Spring, only the XML at this time. So the approach I am trying to use is to have a contextInitializerClass context-param defined in my web.xml and then setting that to a class that implements ApplicationContextInitializer and sets the Spring active profile manually. However, at startup of WebLogic or at redeploy, neither are invoking my custom initializer class and my profile is not getting set.

My question is, does Spring's contextInitializerClass have a dependency on Servlet 3.0 or is there something else that I am missing?

Code that I have defined:

web.xml

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

<context-param>
    <param-name>contextInitializerClass</param-name>
    <param-value>com.myapp.spring.SpringContextProfileInit</param-value>
</context-param>

<!-- Location of spring context config -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</context-param>
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>      
...

SpringContextProfileInit.java

public class SpringContextProfileInit implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {

    private static final Logger log = LoggerFactory.getLogger(SpringContextProfileInit.class);

    public SpringContextProfileInit() {
        log.debug("Got the constructor");
    }

    @Override
    public void initialize(ConfigurableWebApplicationContext ctx) {
        ConfigurableWebEnvironment environ = ctx.getEnvironment();
        log.debug("Got the environment, no profiles should be set: "+ environ.getActiveProfiles());

        /*
        * Here I am setting the profile with a hardcoded name.  In the real app,
        * I would read from a separate properties file, always named app.properties
        * which would live on the app server's classpath.  That app.properties file
        * would contain a property directing the Spring Profile to use.
        */
        environ.setActiveProfiles("local");
        log.debug("Now should be set to local: "+ environ.getActiveProfiles());
        ctx.refresh();
    }

}

servlet-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo" 
    xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<context:property-placeholder properties-ref="deployProperties" />
...
<beans profile="local">
    <bean id="deployProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
            p:location="WEB-INF/local.properties" />
</beans>
<beans profile="beast, dev">
    <bean id="deployProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"
            p:location="WEB-INF/dev.properties" />
</beans>
</beans>

When I try to deploy the application, I get the exception: NoSuchBeanDefinitionException:No bean named 'deployProperties' is defined which would be expected if the profile is not set. My logs don't show that any of my debug statements are printed. I have also tried moving the contextInitializerClass parameter to be an init-param of my DispatcherServlet, but that gave the same results.

My constraints are that

  1. I cannot set the profile from within my Maven scripts because our company uses the same artifact to push to all environments.

  2. I also cannot change versions of WebLogic or use the newest servlet spec due to it being container dependent.

My current versions are:

  • Spring 3.1.2.RELEASE
  • WebLogic 10.3.6
  • javax.servlet-api 2.5

Has anyone else seen this problem and knows how I can get my initializer class loaded? Or is there a better way to do what I am trying to do?

This looks related to another poster's question that has not been answered: Spring MVC 3.1 Using Profiles for environment specific Hibernate settings

Meri answered 1/11, 2012 at 14:27 Comment(0)
W
7

The name of the context-param is I think wrong, it should be contextInitializerClasses not contextInitializerClass , that could be the reason why your ApplicationContextInitializer is not getting picked up

Also you seem to be missing the entry for ContextLoaderListener in your web.xml file, try adding that too:

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

This is the one which loads up the bean configuration xml file specified in the contextConfigLocation tag

Whimsy answered 4/11, 2012 at 0:57 Comment(1)
Well that is embarrassing, you are correct about the name, it needs to be *Classes. Thanks for the help.Dutton

© 2022 - 2024 — McMap. All rights reserved.