Cloud Foundry logo in white on a blue background
blog single gear
Engineering

Improved Java Tooling for Cloud Foundry

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 -Pcf.username=user@example.com -Pcf.password=mypassword
:clean UP-TO-DATE
:compileJava
:processResources
:classes
:war
:assemble
:cf-login
Authenticating to 'https://api.run.pivotal.io' with username 'user@example.com'
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