DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Data Engineering
  3. Data
  4. Single Spring Application Deployment for both Local and CloudFoundry.com Servers

Single Spring Application Deployment for both Local and CloudFoundry.com Servers

David Salter user avatar by
David Salter
·
Apr. 29, 11 · Interview
Like (0)
Save
Tweet
Share
10.25K Views

Join the DZone community and get the full member experience.

Join For Free

In my previous post I showed how it’s possible, using Spring 3.0, to deploy a database application to CloudFoundry.com and what changes are needed for a CloudFoundry.com datasource.  In this post, I’m going to show how a Spring 3.1 application can be configured at runtime to use either a local MySQL database or a CloudFoundry.com MySQL database thus allowing a single deployable Spring application to be deployed either locally or on CloudFoundry.com.

Deploying a Spring application to CloudFoundry.com does not mandate the use of Spring 3.1, however Spring 3.1 makes the process much easier due to the new profile features. So, first off, we must upgrade to Spring 3.1

Upgrading to Spring 3.1

To upgrade a Spring STS application to use Spring 3.1 is an easy procedure. In the project’s pom.xml file, we first need to change the version number of Spring to 3.1.0.M1. I say it’s easy with a STS application as everything else (for example, Spring’s Milestone Maven repository) is already preconfigured in the pom.xml file.

<properties>
<org.springframework-version>3.1.0.M1</org.springframework-version>
</properties>

If you’re not using Maven, you can download Spring 3.1 M1 from the Community Download page.

Having upgraded the version in Maven, we need to change the namespaces for any application context files. This is as straightforward as changing schema locations to be xxx-3.1.xsd instead of xxx-3.0.xsd

<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">

Upgrading to Spring 3.1.M1 will unfortunately have some side effects within STS. After upgrading, you may see that some lines within application context files are flagged with errors such as:

Error occured processing XML 'org/springframework/core/convert/support/ArrayToCollectionConverter'. See Error Log for more details

This is because STS (v2.6) does not currently fully support Spring 3.1 due to some API changes in 3.1.  Support for Spring 3.1 can be tracked on SpringSource’s Jira issue #1655.

Configuring Bean Definition Profiles

After configuring an application to use Spring 3.1, we can start using the new profiles feature to specify both a cloud datasource and a local datasource.

<beans xmlns=http://www.springframework.org/schema/beans …

<beans profile="default">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}" />
</beans>
<beans profile="cloud">
<cloud:data-source id="dataSource" />
</beans>
</beans>

In this XML fragment, we can see that there are embedded <beans /> elements inside the main <beans /> element.  This is a new feature of Spring 3.1 that allows different configurations to be easily specified within one configuration file. Here we’ve defined a bean called dataSource as a JDBC datasource and as a CloudFoundry.com datasource.  The profile attribute allows us to specify which profile the bean is to be instantiated in.  So, in the “default” profile, i.e. a local profile where development and testing is most likely to be performed, a JDBC datasource is defined.  The “cloud” profile specifies a datasource for CloudFoundry.com.  A bean profile can be set to cover multiple profiles, but in this example, the dataSource bean is either a local JDBC datasource or a CloudFoundry.com datasource and can never be defined in both cases.

For a detailed description of Spring’s bean definition profiles, check out Chris Beams blog post.

Choosing a Profile at Runtime

The final stage of changing an application to use the bean definition profiles defined above is to add a class that implements the org.springframework.context.ApplicationContextInitializer interface.  This interface allows the spring container to be customised before it in initialized. In our instance, we can hook into this and, depending on the environment, set the active profile to be the “default”, local JDBC datasource, or the “cloud” CloudFoundry.com datasource.

public class Initializer implements

ApplicationContextInitializer<ConfigurableWebApplicationContext> {

protected final Log logger = LogFactory.getLog(getClass());

public void initialize(ConfigurableWebApplicationContext ctx) {
ConfigurableEnvironment environment = ctx.getEnvironment();

ApplicationInstanceInfo instanceInfo = new CloudEnvironment()
.getInstanceInfo();

if (instanceInfo == null) {
// We are running locally.
logger.info("Setting default profile.");
environment.setActiveProfiles("default");
} else {
// We are running in the cloud.
logger.info("Setting cloud profile.");
environment.setActiveProfiles("cloud");
}
}
}
 

In this class, we attempt to get the instanceInfo of the CloudEnvironment class.  If this returns null, the application is not running on CloudFoundry.com and the local “default” bean definition profile is set as the active profile.  If, however, a valid instance is returned, then the app is running on CloudFoundry.com and the “cloud” bean definition profile is set as the active profile.

That’s all there is to it and now the application can be developed and deployed as easily locally as it can on CloudFoundry.com

The sample code used in this post can be found on GitHib at https://github.com/daveys/spring-todo

From http://www.davidsalter.co.uk/1/post/2011/04/single-spring-application-deployment-for-both-local-and-cloudfoundrycom-servers.html

 

Spring Framework Database application Profile (engineering) Datasource

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How to Submit a Post to DZone
  • DZone's Article Submission Guidelines
  • Spring Boot vs Eclipse Micro Profile: Resident Set Size (RSS) and Time to First Request (TFR) Comparative
  • Unlocking the Power of Elasticsearch: A Comprehensive Guide to Complex Search Use Cases

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: