Rapid Cloud Foundry Deployments with Maven |
|

Apache Maven is a very popular choice in the Java community for building and deploying applications. The Cloud Foundry team has released the Cloud Foundry Maven Plugin to integrate with applications’ development lifecycle, including deployment to the cloud. The same Maven plugin can be used to manage application pushes and updates to any Cloud Foundry instance.
One of Cloud Foundry’s main promises is to make your life as a developer a whole lot easier without limiting available choices. Cloud Foundry not only supports a plethora of languages (Java, Groovy, Scala, Ruby etc.) and frameworks (Spring, Grails, Rails, Sinatra, Lift etc.) but it also allows you to deploy your applications to different environments. This includes public clouds, such as Cloudfoundry.com and AppFog.com, partner-provided cloud offerings, single VM Micro Cloud Foundry, and your own private cloud using Cloud Foundry open source, which is available to everyone under a very liberal Apache License v2.
We want to give you complete choice on how you deploy your applications to Cloud Foundry. So far you can pursue the following avenues:
- VMC command line tool
- SpringSource Tool Suite (STS) / Eclipse Plugin
- Cloud Foundry Grails Plugin
- Spring Roo Add-On
Enter the Cloud Foundry Maven Plugin. Using the Cloud Foundry Maven Plugin, developers can now easily integrate cloud deployments into their Maven projects’ life cycle. This plugin also gives you an easier way to deploy your applications from continuous integration servers such as Hudson and Jenkins. Among other things, the Cloud Foundry Maven Plugin allows you to:
- Deploy (Push) Maven based projects to Cloud Foundry
- Undeploy Maven based projects from Cloud Foundry
- Redeploy (Update) Maven based Cloud Foundry projects
While this plugin is modeled after VMC, the Grails plugin, and STS, it ensures that the user experience feels native to Maven. Under the hood, it uses the open source Cloud Foundry Java Client library, which is also used by the STS Cloud Foundry plugin. In order to use the Cloud Foundry Maven Plugin, all you need is to have Apache Maven installed.
With the Cloud Foundry Maven Plugin, you can build and deploy your application simply using a command such as:
$ mvn cf:push
If you’re unfamiliar with Maven, take a look at Josh Long’s blog posting titled Green Beans: Getting Started with Maven and Spring.
The Sample Application
In order to get started and to illustrate the basic steps, I would like to use the super-simple Maven-based Hello Java application, that is part of SpringSource’s collection of Cloud Foundry samples. The sole function of this application is to output the host and port where this application is running.
Let’s download and build the sample application (Please make sure Git is installed):
$ git clone https://github.com/SpringSource/cloudfoundry-samples.git
$ cd cloudfoundry-samples/hello-java
$ mvn clean package
This should result in a war-file named ‘hello-java-1.0.war’ being generated in the project’s target folder.
Initial Deployment to CloudFoundry.com
Now, let’s setup the Cloud Foundry Maven Plugin. As a minimum configuration, you have to add the plugin to the project’s pom.xml file:
<plugin>
<groupId>org.cloudfoundry</groupId>
<artifactId>cf-maven-plugin</artifactId>
<version>1.0.0.M1</version>
</plugin>
Additionally, the milestone release of the plugin is not available in the Maven Central repository, yet. Therefore, please ensure that you also add the Spring Framework Milestone Repository to the pom.xml file as well:
<pluginRepositories>
...
<pluginRepository>
<id>repository.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</pluginRepository>
...
</pluginRepositories>
This represents the most basic configuration possible. Of course you typically want to add a few more configuration options such as:
- Cloud Foundry target url
- User credentials (username and password)
- The application url
- Used Cloud Foundry services (e.g. MySQL or Mongo)
Here is the pom.xml file with additional parameters:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.cloudfoundry</groupId>
<artifactId>cf-maven-plugin</artifactId>
<version>1.0.0.M1</version>
<configuration>
<server>mycloudfoundry-instance</server>
<target>http://api.cloudfoundry.com</target>
<url>hello-java-maven.cloudfoundry.com</url>
<memory>256</memory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
What about the Cloud Foundry login credentials? While it is possible, to store those credentials as configuration parameters in the pom.xml file, we recommend storing those separately in Maven’s settings.xml file instead. This file is usually located in your user home directory under the .m2 folder, e.g. ~/.m2/settings.xml.
A typical entry might look like this:
<settings>
...
<servers>
...
<server>
<id>mycloudfoundry-instance</id>
<username>demo.user@vmware.com</username>
<password>s3cr3t</password>
</server>
</servers>
...
</settings>
Notice that in your pom.xml you reference the server parameters in settings.xml using the configuration parameter (value ‘mycloudfoundry-instance’), that matches the element in settings.xml. As yet another option, you can also provide the Cloud Foundry credentials as command line parameters.
Keep in mind that ALL configuration parameters can also be set via command line properties, which can be quite handy for one-offs, testing etc. For example, you can express all configuration parameters shown above as:
$ mvn cf:info -Dcf.username=demo.user@vmware.com -Dcf.password=s3cr3t -Dcf.memory=256 -Dcf.url=hello-java-maven.cloudfoundry.com \
-Dcf.target=http://api.cloudfoundry.com
The command line parameters of the Cloud Foundry Maven Plugin take precedence over pom.xml based parameters. Furthermore, many of the configuration parameters have sensible defaults. For more details please read the reference documentation at https://github.com/cloudfoundry/vcap-java-client
For the sake of this example, we continue using the expanded configuration in pom.xml and settings.xml.
Now that we have configured the plugin for our project, we should be good to go to execute a few commands. Generally, all calls using the Maven plugin follow a similar pattern:
$ mvn cf:<<command>> [-Dcf.some_parameters] [-Dcf.some_other_parameter...]
Let’s do our initial deployment and push the application to Cloudfoundry.com:
$ mvn cf:push
This will probably fail as the url we defined above for the application (hello-java-maven.cloudfoundry.com) has already been taken (my instance). Consequently, you will see the following error message:
...'The URI: "hello-java.cloudfoundry.com" has already been taken or reserved'...
Therefore, please make sure that the url chosen for your application is not already in use by someone else. Please retry using a unique url parameter – and a few seconds later I can hopefully congratulate you for deploying your first application to Cloud Foundry using Maven!
Next we will do an application update. Let’s edit:
/src/main/java/org/cloudfoundry/samples/HelloServlet.java
I will just change some of the text output, e.g.:
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
writer.println("Cloud Foundry Rocks - Your application host's Ip address and port is: " + System.getenv("VCAP_APP_HOST") + ":" + System.getenv("VCAP_APP_PORT"));
...
}
}
After the change issue the following Maven command:
$ mvn clean cf:update
Once the command finishes, you should see the changes reflected in your deployed application.
Deploying to your local Micro Cloud Foundry
With the recent release of Micro Cloud Foundry, you can now run your cloud applications off-line straight from your laptop and of course the Cloud Foundry Maven Plugin will support you with those local deployments as well. In order to setup your Micro Cloud Foundry instance, please follow the steps outlined at:
http://support.cloudfoundry.com/entries/20316811
Once your Micro Cloud Foundry is running, you need to setup a local user. In order to do so, issue the following Maven command:
$ mvn cf:register -Dcf.target=http://api.YOURMICROCLOUDNAME.cloudfoundry.me -Dcf.username=<provide new username> \
-Dcf.password=<provide new password>
Be aware that the username must be in the form of an email address. Afterwards, we can start using our local Micro Cloud Foundry instance. The commands are exactly the same as when deploying to Cloudfoundry.com. For instance, you can deploy the sample application locally by executing:
$ mvn cf:apps -Dcf.target=http://api.YOURMICROCLOUDNAME.cloudfoundry.me -Dcf.password=s3cr3t -Dcf.username=the_username_registered_above \
-Dcf.url=hello-java.YOURMICROCLOUDNAME.cloudfoundry.me
Our app should be running now. To verify, let’s get a listing of deployed applications:
$ mvn cf:apps -Dcf.target=http://api.YOURMICROCLOUDNAME.cloudfoundry.me -Dcf.password=s3cr3t -Dcf.username=the_username_registered_above
...
+-------------+---+---------+--------+-----------------------------------------------+----------+
| Application | # | Health | Memory | URLS | Services |
+-------------+---+---------+--------+-----------------------------------------------+----------+
| hello-java | 1 | STARTED | 512 | hello-java.YOURMICROCLOUDNAME.cloudfoundry.me | |
+-------------+---+---------+--------+-----------------------------------------------+----------+
Future Development
Currently the Cloud Foundry Maven Plugin provides only a subset of functionality provided by VMC. Over the next few weeks we expect to reach feature parity as much as it makes sense. Please follow the project on Github and we would highly appreciate your feedback. Let’s get some coding done – worrying about infrastructure is so yesterday!
Resources
- Cloud Foundry Maven Plugin Source Code and Documentation: https://github.com/cloudfoundry/vcap-java-client/tree/master/cloudfoundry-maven-plugin
- Cloud Foundry Java Client – Source Code: https://github.com/cloudfoundry/vcap-java-client/tree/master/cloudfoundry-client-lib
- Sample Application: https://github.com/SpringSource/cloudfoundry-samples/tree/master/hello-java
Similar Posts
- Using Micro Cloud Foundry from Grails
- One-step deployment with Grails and Cloud Foundry
- Cloud Foundry integrated into developer tools
- Using Cloud Foundry Services with Spring: Part 1 – The Basics
- Using Cloud Foundry Services with Spring: Part 4 – Spring Profiles






Mark says:
Added on September 22nd, 2011 at 6:20 pmGreat plugin. This should further simplify deployment to Cloud Foundry. Actually it's already simple using VMC or STS. But at least this makes deployment even more compact.
Mike says:
Added on September 23rd, 2011 at 10:56 amGreat! I was just about to start creating my own.
Cloud Foundry deployments can now be orchestrated as part of my maven build.
labib says:
Added on September 24th, 2011 at 4:59 pmit is good work but
i have problem with configuration
this is the stack trace of error
WARNING: GET request for "http://api.cloudfoundry.com/apps/firstapp" resulted in 404 (Not Found); invoking error handler
org.springframework.web.client.RestTemplate handleResponseError
WARNING: POST request for "http://api.cloudfoundry.com/apps" resulted in 403 (Forbidden); invoking error handler
[INFO] ————————————————————————
[ERROR] BUILD ERROR
[INFO] ————————————————————————
[INFO] Error while creating application 'firstapp'. Error message: '403 Forbidden'. Description: 'External URIs are not enabled for this account'
Gunnar Hillert (blog author) says:
Added on September 26th, 2011 at 9:29 amThanks for checking out the plugin! What Maven goal were you executing? Also, what parameters did you use? External URIs are not enabled for this account indicates, that you probably provided an incorrect Url parameter. When you deploy to cloudfoundry.com your provided url parameters should look like:
<url>firstapp.cloudfoundry.com</url>-Dcf.url=firstapp.cloudfoundry.comFor example, if you used an incorrect parameter like:
-Dcf.url=firstappyou may encounter an error message as described above. Nevertheless, I believe the provided error message is not user-friendly. Therefore, I created the following ticket in the Github issue tracker: https://github.com/cloudfoundry/vcap-java-client/issues/1I hope this answers the issue you encountered. If not, please provide more details. Thanks!
labib says:
Added on September 26th, 2011 at 5:26 pmthank you i tried it and worked fine
thanks for this Great work
Gunnar Hillert (blog author) says:
Added on September 26th, 2011 at 10:19 pm@labib Glad that it finally worked and thank you for the kind words.
Jesica Wills says:
Added on September 30th, 2011 at 12:49 amThis is great plugin. Great work. This article on Cloud Foundry is simply nice. And that worked. Thanks.
coal crusher says:
Added on October 18th, 2011 at 10:39 pmthanks for this Great work
charles says:
Added on October 24th, 2011 at 4:42 amhow to let the vcap-java-client to use an http proxy?
seems that the "mvn cf:push" command does not use the maven proxy settings.
Nicholas Hrycan says:
Added on January 22nd, 2012 at 8:10 pmVery easy to follow guide for the cloud foundry maven plugin. Thanks!
Anuj says:
Added on May 10th, 2012 at 8:58 amHi,
The Maven CF plugin works great. i have one question. How do I specify the services that might be associated with my application. So I have a Spring web application which has an associated mysql service. How do i specify it in my pom.xml file. I saw the example here : https://github.com/cloudfoundry/vcap-java-client/tree/master/cloudfoundry-maven-plugin
that specifies using it like this :
mongo-instance, my-sql-instance
But It doesnt work and throws an error.
Can you tell me the correct way of doing it.
Thanks,
Anuj
Gunnar Hillert (blog author) says:
Added on May 10th, 2012 at 11:17 amHi Anuj,
Thanks for checking out the Maven plugin for Cloud Foundry. Is it possible that the service you want to use, does not exist, yet? The Maven Plugin is currently not able to create services for you. The plugin can only bind your application to "Existing" services.
Thus, the following example configuration in a typical pom.xml file works:
<plugins> <plugin> <groupId>org.cloudfoundry</groupId> <artifactId>cf-maven-plugin</artifactId> <version>1.0.0.M1</version> <configuration> <username>your-user</username> <password>top-secret</password> <target>http://api.cloudfoundry.com/</target> <url>my-application.cloudfoundry.com</url> <memory>64</memory> <services>mysql-test</services> </configuration> </plugin> </plugins>However, you must ensure that you created a service named "mysql-test", prior to executing the Maven command 'mvn cf:push'. Otherwise you will see the observed message 'Service not found'.
I hope this explains the issue. Please let me know if you have further problems.
Cheers,
Gunnar