Category Archives: Uncategorized

Scala Spray Can using Gradle with Cloud foundry and the java buildpack

What we are trying to do

Use gradle to build and package our app. We are using gradle as our build tool as we did not like the Sbt way of doing things.

Deploy a single self contained running Spray application with all required runtimes dependency on Cloud Foundry as a java application.

If possible get off using our self written wrapper java tools to deploy and manipulate Cloud Foundry using the cloud foundry jar.

Background

We were trying out different gradle plugins to try and get our Spray app deployed.  We had settled on oneJar as there was documentation of people using it with gradle to create and run a self contained file.

Onejar

The oneJar plugin changes the class loader to accept self contained single file that is a jar with jars inside it.

Messing around with class loading means you are going to have a bad time.

An idea from Spring Boot deployment

Chatting with some other devs I was also explaining we had problems deploying our Spring boot app, so were prevented from deploying onto our latest and greatest Cloud Foundry instance.  We have hard gained experience on out how to deploy our apps on an older version of CF but it never started properly on the new CF.  I was pointed to this by another developer as to how to deploy a Spring Boot application properly from the java buildpack documentation.

Cloud Foundry docs for Spring boot deployment

DistZip to the Rescue

This got me thinking of how Spring boot uses the distZip style deployment and could I leverage it to deploy my Spray app. Spring boot uses the distZip which comes from the  application gradle plugin.

What distZip does

Creates a zip file with all the runtimes needed your application with the correct  META-INF/MANIFEST.MF info and a start script to run it.  Cloud Foundry is happy to deploy this.

You will need to set your main class to tell distZip what to run

mainClassName = "org.gradle.sample.Main"

Success

On Cloud Foundry the application needs to bind to a port provided on deployment time to accept connections, else CF will not let it succeed in starting and kill it.

Here is a code snippet of what it takes to bind the Spray to CF.


import com.typesafe.config._
....

val envConf: Config = ConfigFactory.systemEnvironment()
def serverPort = envConf.getInt("VCAP_APP_PORT")

....
 IO(Http) ? Http.Bind(actorSystem.actorOf(Props(wire[YourActor]), "your-actor"), interface = "0.0.0.0", port = serverPort)
}

Using the Cloud Foundry Gradle Plugin

After getting a successful deployment using the command line tool(CLI) I was then able to use the Gradle CF plugin to configure and deploy.  This makes it easier for Jenkins as we do not have to change our build slaves to deploy the CLI and change our chef scripts for build slaves.

Docs for CF gradle plugin

Setup snippet

<pre>
cloudfoundry {
    target = "https://YOUR_INSTANCE.com"
    space = "snapshot-YOURS"
    file = file("./build/distributions/YOUR_DIST_ZIP.zip")
    buildpack = "https://github.com/cloudfoundry/java-buildpack.git#v3.2"
    application = "YOUR_APP_NAME-dev"
    trustSelfSignedCerts = true // needed for our managed instance
    memory = 1024
    instances = 2
    env = ["SPRING_PROFILES_ACTIVE": "A_PROFILE"]  //we are using the spring boot style way of dealing with different properties files for different enviornments.
}</pre>

CF Commands

It is a bad idea to hold the credentials in your source control system. so you or your build slave  should login and out using secured credentials.

  1. gradle cfLogin -PcfUsername=’your-user-name’ -PcfPassword=’your-password’  -PcfOrganization=’your-organisation’

With the above snippet the target, space, buildpack, file and application name you can just do a push without any additional commands.

2. gradle cfPush

Different Environments

Just override the needed elements to deploy to new environments with -PcfThingToOverride=’NEW_VALUE’

E.G.:

gradle cfPush -PcfTarget=’https://staging.your.company.com&#8217; -PcfSpace=’stage-space’ -PcfInstances=’4′ -PcfApplication=’YOUR_APP-stage’ ….

 

 

 

Managed Script plugin and SCM sync on Jenkins

If you are using https://wiki.jenkins-ci.org/display/JENKINS/Managed+Script+Plugin  and the https://wiki.jenkins-ci.org/display/JENKINS/SCM+Sync+configuration+plugin

You will have to add a Manual synchronization includes: 

buildstep-config-files.xml

to get it to save the managed files configuration.  Otherwise all your managed script files you share across jobs will be lost if you lose the jenkins server and have to rebuild it.

 

Angularjs and Grails withFormat and json

I have been doing a mixed angularjs and grails project and ran into problems getting json to come back from the controller request with a withFormat block.

What I expected

I expected that it would call the grails app controller index method and with the withFormat to pick out that the request came is as a json request so return json. This is not the case, it would send me back the html page instead.

The problem was that grails would see */* as the accept headers and return just the html.

Grails code from the grails controller

def index() {
        def books = Book.findAll().collectEntries { book -> [book.title, book] }.values()
        withFormat {
            html books: books
            json { render books as JSON }
        }
    }

Angularjs json request that returns html

$http.get('/book/index').success(function(response) { };
}

Continue reading

Synology NAS blinking orange light and no hard drive lights

I started to get a orange blinking light and the hard drive lights were not coming on for my synology NAS drive.

I had tried to add another old backup to the usb ports in the back.

After much searching and trying to reinstall the entire DSM.

This gave me a Error 38 could not find the NAS to install upon.

The hard drives had come dislodged at some point.  After reinserting them again it is back working properly.

There is a design fault where you cannot lock the drives into place so they can come dislodged if you hold the unit the wrong way, or shake the unit.

 

 

Gradle could not resolve commons-logging

My gradle build would fail for an unexpected reason. This could be any common jar but one I know would be in the maven central repo without any problems.

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all dependencies for configuration ‘:sham-core:testCompile’.
> Could not download artifact ‘commons-logging:commons-logging:1.1.1@jar’
> Artifact ‘commons-logging:commons-logging:1.1.1@jar’ not found.

Problem with repositories

My build.gradle had the following for resolving repositories

buildscript {
repositories {
mavenLocal()
mavenCentral()
}
}

Turns out that my maven local had some sort of problem with gradle when the jar is not present in the maven local.

Options to fix this

  1. remove mavenLocal() from your gradle build script
  2. Move the maven local repo mv ~/.m2/repository ~/m2/repo-tmp . Build the project and move it back mv ~/m2/repo-tmp ~/.m2/repository
  3. Delete the maven local repo rm -rf ~/.m2/repository/ .

I do not use much maven so I just did 3.

Gradle and Could not initialize class YYYYYY

In Gradle I got stumped by this even though class YYYYYY was on the classpath.
java.lang.NoClassDefFoundError: Could not initialize class YYYYYY

I put a try catch block around the code that was failing. This gave me a more direct error than before.
It turned out that I had XML reading error where a class was trying to read a file that was not present on the classpath

The class was present but the initialization failed, check your setup.