Your browser (Internet Explorer 7 or lower) is out of date. It has known security flaws and may not display all features of this and other websites. Learn how to update your browser.

X

Spring 3.1 profiles and Tomcat configuration

Spring 3.1 introduced very useful feature called profiles. Thanks to that its easy to build one package that can be deployed in all environments (development, test, production and so on).

By defining system property spring.profiles.active Spring allows us to create different beans depending on active profile name using XML configuration or @Profile annotation. As we all know system properties can be used in Spring XML files and we will take advantage of that.

In this post I will show how to use Spring profiles to create one package for all environments and how to run it on Apache Tomcat.

Example architecture

I think the most common and wanted architecture is when applications deployed on dev, test and production differ only in used properties file containing configuration. WAR contains configuration for all environments and correct one is chosen during runtime. So it is the best if in application resources we have files like:

src
  main
    resources
      - config_dev.properties
      - config_production.properties
        ...

Configuring Spring property placeholder

In order to load properties files in Spring we use <context:property-placeholder /> or @PropertySource annotation. In my example I will follow XML configuration approach for loading properties file:

<?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:context="http://www.springframework.org/schema/context"
			 xsi:schemaLocation="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">

    <context:property-placeholder location="classpath:config_${spring.profiles.active}.properties" />

</beans>

Configuring Tomcat

Now its time to tell Tomcat which profile is active. There at least ways to do that:

  • defining context param in web.xml – that breaks “one package for all environments” statement. I don’t recommend that
  • defining system property -Dspring.profiles.active=your-active-profile

I believe that defining system property is much better approach. So how to define system property for Tomcat? Over the internet i could find a lot of advices like “modify catalina.sh” because you will not find any configuration file for doing stuff like that. Modifying catalina.sh is a dirty unmaintable solution. There is a better way to do that.

Just create file setenv.sh in Tomcat’s bin directory with content:

JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=dev"

and it will be loaded automatically during running catalina.sh start or run.

Conclusion

Using Spring profiles we can create flexible applications that can be deployed in several environments. How is it different from Maven profiles approach? With Maven a person who was building application had to define in which environment it was supposed to run. With approach described above environment decides if its development, testing or production. Thanks to that we can use exactly the same WAR file and deploy it everywhere.

If you enjoyed this post, then make sure you subscribe to my RSS feed

  • Bartosz Jamroz

    The problem with setting active profile by editing Tomcat env is that it will have influence on all spring applications deployed on this container. A more convenient way is to use ApplicationContextInitializer which is run before beans creation and set active profile from within. This way every application can use different profile.

  • Ralph Schaer

    We usually set the profile in the Tomcat context file (tomcat/conf/Catalina/localhost/mycontext.xml). This way it’s possible to specify the profile for every webapplication individually. 

       

  • MaciejWalkowiak

    Thanks guys for tips! Ralph – your solution is the best that i’ve seen so far when there is a need to have different active profiles for each application 

  • Pid

    You can also set a system property for your application by adding it to catalina.properties.

    • MaciejWalkowiak

      Thanks. I will update post soon to present that solution too.

  • Serge

    Hi,

    I thought it was possible to have multiple active profiles so how does this work out in that case ?

  • OffSpring

    What you showed here is not using Spring’s 3.1 profiles but the ‘old’ way of using property placeholers.