VMware has released several new components that enable developers using Java, Groovy, and other JVM languages to deploy applications to Cloud Foundry quickly and easily. This blog post will show the options available to JVM developers with this new tooling.
Maven and Gradle are two popular build tools for Java applications. Maven has been around for many years and enjoys widespread use. Gradle is newer but is gaining mindshare and adoption quickly (Gradle is used to build the core Spring projects and is becoming the recommended build tool for Android applications). VMware has released Cloud Foundry plugins for Maven and Gradle that allow developers to deploy and manage applications with the same tools used to build the applications. Using these plugins, you can build, test, and deploy your application to Cloud Foundry with a single command-line interaction.
With the Cloud Foundry plugin included and configured in your Maven build file, you can build and push your application to Cloud Foundry with this Maven command:
$ mvn clean package cf:push
The command to build the application and push it to Cloud Foundry with the Gradle plugin is just as simple:
$ gradle clean assemble cf-push
Want to quickly try it for yourself?
If you have an account on run.pivotal.io (you can sign up for one here), you can see the Gradle plugin in action by following these steps (a cf-login
task and login credential parameters are included here to do the initial Cloud Foundry login, which is a one-time step):
$ git clone https://github.com/cloudfoundry-samples/spring-music
$ cd spring-music
# on Windows, use gradlew.bat instead of ./gradlew
$ ./gradlew clean assemble cf-login cf-push [email protected] -Pcf.password=mypassword
:clean UP-TO-DATE
:compileJava
:processResources
:classes
:war
:assemble
:cf-login
Authenticating to 'https://api.run.pivotal.io' with username '[email protected]'
Authentication successful
:cf-push
Creating application spring-music
Uploading 'spring-music/build/libs/spring-music.war'
Starting spring-music
-----> Downloaded app package (19M)
-----> Downloaded app buildpack cache (38M)
-----> Downloading OpenJDK 1.7.0_21 JRE from http://download.pivotal.io.s3.amazonaws.com/openjdk/lucid/x86_64/openjdk-1.7.0_21.tar.gz (0.0s)
Expanding JRE to .java (1.0s)
-----> Downloading Auto Reconfiguration 0.7.2 from http://download.pivotal.io.s3.amazonaws.com/auto-reconfiguration/auto-reconfiguration-0.7.2.jar (0.0s)
Modifying /WEB-INF/web.xml for Auto Reconfiguration
-----> Downloading Tomcat 7.0.42 from http://download.pivotal.io.s3.amazonaws.com/tomcat/tomcat-7.0.42.tar.gz (0.0s)
Expanding Tomcat to .tomcat (0.1s)
Downloading Buildpack Tomcat Support 1.1.1 from http://download.pivotal.io.s3.amazonaws.com/tomcat-buildpack-support/tomcat-buildpack-support-1.1.1.jar (0.0s)
-----> Uploading droplet (55M)
Checking status of spring-music
1 of 1 instances running (1 running)
Application spring-music is available at http://spring-music-5pq6z.cfapps.io
BUILD SUCCESSFUL
Total time: 2 mins 45.045 secs
Plugin Configuration and Usage
Now let’s look at how to use the Maven and Gradle plugins in your own project. The plugins are configured in a build file – typically in the same build file used to build the application. Let’s start with an example of a Maven pom.xml
build file with the Cloud Foundry plugin included:
<project …>
…
<build>
<plugins>
…
<plugin>
<groupId>org.cloudfoundry</groupId>
<artifactId>cf-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<server>pivotal-cloud-foundry</server>
<target>https://api.run.pivotal.io</target>
<space>development</space>
<appname>my-java-app</appname>
<url>my-java-app.cfapps.io</url>
<memory>512</memory>
<instances>3</instances>
<env>
<greeting>Hello</greeting>
</env>
<services>
<service>
<name>app-db</name>
<label>elephantsql</label>
<provider>elephantsql</provider>
<version>n/a</version>
<plan>turtle</plan>
</service>
</services>
</configuration>
</plugin>
</plugins>
<build>
<project>
An equivalent Gradle build.gradle
file looks like this:
...
apply plugin: 'cloudfoundry'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.cloudfoundry:cf-gradle-plugin:1.0.1'
...
}
}
cloudfoundry {
target = "https://api.run.pivotal.io"
space = "development"
application = "my-java-app"
file = file("build/libs/my-java-app.war")
uri = "my-java-app.cfapps.io"
memory = 512
instances = 3
env = [
"greeting": "Hello"
]
serviceInfos {
"app-db" {
label = "elephantsql"
provider = "elephantsql"
version = "n/a"
plan = "turtle"
}
}
}
Notice that all details of the application’s deployment can be specified in the configuration, including the services that the application requires. The specified services instances will be created if necessary, and then bound to the application. This detailed configuration allows for a high level of repeatability in the application’s deployment. This is similar to the capability provided by the manifest.yml
file used by the cf
CLI. In fact, the build plugin configuration options are designed to be as similar as possible to the options available in manifest.yml
. Here is an example of a manifest.yml
file with the same configuration as the build file samples above:
---
applications:
- name: my-java-app
memory: 512M
instances: 3
host: my-java-app
domain: cfapps.io
path: my-java-app.war
env:
greeting: Hello
services:
app-db:
label: elephantsql
provider: elephantsql
version: n/a
plan: turtle
Configuration options can be overridden from the command line, allowing more flexibility in using the build tool plugins interactively. We saw this earlier with the username and password parameters to the Gradle cf-login
task. Here’s an example of overriding the application name with the Maven plugin:
$ mvn cf:restart -Dcf.appname=my-other-app
And here is the same interaction using the Gradle plugin:
$ gradle cf-restart -Pcf.application=my-other-app
The Maven and Gradle plugins support a subset of the commands provided by the cf
command line interface. The supported commands have also been designed to be as consistent with their cf
counterparts as possible, making it easy to switch between using cf
commands and build tool commands. The following table shows a sampling of some of the more common commands:
cf | Maven plugin | Gradle plugin | |
---|---|---|---|
Deploy an app | cf push | mvn cf:push | gradle cf-push |
Delete an app | cf delete | mvn cf:delete | gradle cf-delete |
Start an app | cf start | mvn cf:start | gradle cf-start |
List deployed apps | cf apps | mvn cf:apps | gradle cf-apps |
List provisioned services | cf services | mvn cf:services | gradle cf-services |
List available services | cf services -m | mvn cf:service-plans | gradle cf-service-plans |
The GitHub repositories for the Maven and Gradle plugins contain the full documentation on their usage and configuration.
The Cloud Foundry Maven and Gradle plugins can be used against run.pivotal.io or any other Cloud Foundry v2 compatible service provider.
Enabling Continuous Integration and Deployment
One interesting use case for the Maven and Gradle plugins is to enable continuous integration and deployment of applications to Cloud Foundry. The ability to deploy applications to Cloud Foundry using a build tool makes it very easy to configure a continuous integration (CI) server like Jenkins, JetBrains TeamCity, or Atlassian Bamboo to build, test, and deploy an application when triggered by a change in a source code control system. These CI servers integrate with Maven and Gradle already, so deploying an application to Cloud Foundry from a CI server is as simple as adding the Cloud Foundry plugin to your build file and invoking a “cf:push” goal (Maven) or “cf-push” task (Gradle) in the CI server’s project configuration when a build is successful.
CI servers can also be used to promote an application through various deployment environments (development, quality control, staging, production) using an automated trigger or manual user action. The configuration for the build tool plugins allow the Cloud Foundry target, organization, and space to be specified in a flexible way, enabling this promotion through a Cloud Foundry environment. See the Gradle plugin documentation for an example of this.
Cloud Foundry Java Client Library
The Maven and Gradle plugins, as well as the Cloud Foundry Eclipse plugin, use the Cloud Foundry Java Client Library to interact with Cloud Foundry. This library is a Java wrapper over the Cloud Controller REST API that makes interacting with a Cloud Foundry instance very easy and natural for Java, Groovy, and other JVM language developers. See the Cloud Foundry documentation for more information on using this library.
Contribute!
The Cloud Foundry Java tooling is in a single repository on GitHub. Feel free to contribute feature ideas, issues, and pull requests to make the tooling even better.
Scott Frederick
Community Engineer, Cloud Foundry at VMware
@scottyfred