1

I'm currently using Spring @Profile to manage my web application's configuration based on the environment (DEV, TEST, PROD). In order to activate the right profile, I prefer not to hardcode the value for spring.profiles.active in web.xml. Rather, I want to rely on the JNDI from the server to determine the right profile to activate. I'm able to get this working by creating a JNDI string called spring.profiles.active with the value, say DEV, to activate the DEV profile in my web application.

The problem is my server environment already has a custom JNDI ( say, bla/environment ) that contains the value DEV, TEST or PROD.

Is it possible to set spring.profiles.active based on this custom JNDI so that I don't have to create another JNDI that does the same thing?

Thank you.

limc
  • 39,366
  • 20
  • 100
  • 145

3 Answers3

3

You can always create an application specific alias for the JNDI entry which points to the bla/environment. How to do this depends on your application server.

If that isn't feasible you can always implement a custom ApplicationContextInitializer (available since Spring 3.1). This will then read the custom jndi entry and set the active environment.

public class EnvironmentApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private final JndiLocatorDelegate jndi = JndiLocatorDelegate.createDefaultResourceRefLocator();

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        String profile = jndi.lookup("bla/environment", String.class); 
        applicationContext.getEnvironment().addActiveProfile(profile);
    }
}

Something like that, you wrap it in a try/catch so that if the entry doesn't exists the application doesn't fail but simply relies on the on the default mechanism.

You need to add an entry to your web.xml to activate it (or add it as an init-param to the DispatcherServlet if you want to use it there).

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>your.package.here.EnvironmentApplicationContextInitializer</param-value>
</context-param>
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
0

Haven't tried, but I guess you can do

<bean id="currentProfileName" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/bla/environment"/>
</bean>

and then put that as spring active profile

<bean
   class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
   <property name="targetClass" value="java.lang.System" />
   <property name="targetMethod" value="setProperty" />
   <property name="arguments">
    <list>
        <value>spring.profiles.active</value>
        <ref bean="currentProfileName" />
    </list>
   </property>
</bean>
eis
  • 51,991
  • 13
  • 150
  • 199
0

Create an app-specific alias for the profile JNDI entry (bla/environment). Have a look at the accepted answer to this question for details.

Community
  • 1
  • 1
Jukka
  • 4,583
  • 18
  • 14
  • Is `jndi-name` property server specific configuration? I couldn't get this to work and I don't see this property in web.xml 2.5 spec. – limc Oct 08 '13 at 13:49
  • Yes, you map the res-ref-name attribute to a container-managed JNDI name in server-specific configuration. Which app server are you using? – Jukka Oct 08 '13 at 20:03