Wednesday, October 17, 2018

Pushing a Java Project To Cloud Foundry

Pushing a self-contained Java artifact to Pivotal Cloud Foundry is very straightforward. However, I found the instructions to push an existing legacy application this is not self-contained sparse and not as clear as they could be. This blog post detail what I found out and how to do it.
As a code reference, you can look at this Java project and scripts in my GitHub repository here: https://github.com/thecodebeneath/cfpushdir
The project in this repo can be built with Maven and pushed to Cloud Foundry two ways:

1. Standard CF push pointing to a jar file

This is the easiest method and mirrors a simple uber-jar that the Java buildpack can easily upload, detect and start.

> cf push -f manifest-from-jarpath.yml

Where the manifest file looks like this:

---
applications:
- name: carservice-from-jarpath
  path: target/release/lib/carService-1.0-SNAPSHOT-shaded.jar
  buildpacks:
  - java_buildpack
  memory: 1G
  instances: 1
  random-route: true

2. CF push a directory of files that contain the jar

This is the method that caused me a lot of trouble trying to figure out. The key is understanding that the Java buildpack can handle three separate push styles: 1) jar/war, 2) zip file or 3) nested directories. The last two styles end up both being handled by the "distzip" capability of the Java buildback. This requires an explicit set of named directories, in addition to any that you might also need for your application. The two required directories are "bin" and "lib", as documented here: Dist Zip Container.
  • The "bin" directory must contain your start script
  • The "lib" directory must contain your main Java artifact
> cf push -f manifest-from-dirpath.yml

Where the manifest file looks like this:

---
applications:
- name: carservice-from-dirpath
  path: target/release
  command: "$PWD/bin/startCommand"
  buildpacks:
  - java_buildpack
  memory: 1G
  instances: 1
  random-route: true

The target/release directory on your development machine contains the "bin" and "lib" directories, and the startCommand script in the "bin" directory has a command that references the jar as a relative path inside of "lib": 

> $HOME/.java-buildpack/open_jdk_jre/bin/java -jar lib/carService-1.0-SNAPSHOT-shaded.jar 'manifest-from-dirpath'


Summary

I hope my instructions and git project help someone else avoid the time and confusion I had while trying to figure out this solution.

No comments: