05 December 2016

Simple REST Server With Kotlin


With micro services being the latest important development in Software Engineering anyone doing server side development needs to be involved in this area. One of the major areas where Kotlin is being used is in server side development, especially micro services. This post will be covering how to create a simple REST server using the following technologies:


  • Gradle (any 2.x version)
  • Kotlin v1.0.5-2 (stable version)
  • Grizzly v2.3.28 (embedded HTTP web server)
  • Grizzly Jersey Container v2.23.2 (JAX-RS implementation for Grizzly)
  • Jackson v2.23.2 (JSON library)
  • Linux PC (using Debian, Ubuntu or Linux Mint)

Setup Project Directory

  1. Create a project directory called hello_rest_server
  2. Copy the Gradle wrapper directory and the gradlew file to the project directory
  3. In the project directory create a file called settings.gradle containing rootProject.name = 'hello-rest-server'
  4. Create a Gradle build file called build.gradle in the project directory containing the following:

-------------------------------------------------------------------------------------
group 'org.example'version '0.1-SNAPSHOT'
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'    }
}

apply plugin: 'kotlin'apply plugin: 'application'
repositories {
    mavenCentral()
}

dependencies {
    compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.5-2'    compile 'org.glassfish.grizzly:grizzly-framework:2.3.28'    compile 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.23.2'    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.23.2'}

// A Task to run the program.run {
    mainClassName = 'org.example.hellorestserver.RestServerKt'    //args = ["arg1", "arg2"]}

// A Task to create a JAR file for the program.jar {
    from configurations.compile.collect { zipTree it }
    manifest.attributes 'Main-Class': 'org.example.hellorestserver.RestServerKt'}
-------------------------------------------------------------------------------------


Text version:

-------------------------------------------------------------------------------------
group 'org.example'
version '0.1-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.5-2'
    }
}

apply plugin: 'kotlin'
apply plugin: 'application'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.5-2'
    compile 'org.glassfish.grizzly:grizzly-framework:2.3.28'
    compile 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.23.2'
    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.23.2'
}

// A Task to run the program.
run {
    mainClassName = 'org.example.hellorestserver.RestServerKt'
    //args = ["arg1", "arg2"]
}

// A Task to create a JAR file for the program.
jar {
    from configurations.compile.collect { zipTree it }
    manifest.attributes 'Main-Class': 'org.example.hellorestserver.RestServerKt'
}
-------------------------------------------------------------------------------------

Create Kotlin Source Files


Create the following directory structure in the project directory, along with the kt files as shown below:

src
├── main
│   ├── java
│   ├── kotlin
│   │   └── org
│   │       └── example
│   │           └── hellorestserver
│   │               ├── HelloResource.kt
│   │               └── restServer.kt
│   └── resources
└── test
    ├── java
    ├── kotlin
    └── resources


To begin restServer.kt will act as the entry point file for the REST server, which will be edited first by adding the following code:

-------------------------------------------------------------------------------------
package org.example.hellorestserver

import org.glassfish.grizzly.http.server.HttpServer
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory
import org.glassfish.jersey.jackson.JacksonFeature
import org.glassfish.jersey.server.ResourceConfig
import javax.ws.rs.ProcessingException
import javax.ws.rs.core.UriBuilder


fun main(args: Array) {
    val HOST = "localhost"    val PORT = 9000    val baseUri = UriBuilder.fromUri("http://$HOST/").port(PORT).build()
    var server: HttpServer? = null
    try {
        server = GrizzlyHttpServerFactory.createHttpServer(baseUri, createConfiguration())
        println("REST Server Address: $HOST:$PORT")
    } catch (ex: ProcessingException) {
        println("Server Error: ${ex.message}")
        println("Exiting REST server...")
        server?.shutdown()
    }
}

private fun createConfiguration(): ResourceConfig {
    val config = ResourceConfig(HelloResource::class.java)

    // Optional but good practise to manually specify the JSON mapping implementation to use.    config.packages("org.example.hellorestserver").register(JacksonFeature::class.java)
    return config
}
-------------------------------------------------------------------------------------


Text version:

-------------------------------------------------------------------------------------
package org.example.hellorestserver

import org.glassfish.grizzly.http.server.HttpServer
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory
import org.glassfish.jersey.jackson.JacksonFeature
import org.glassfish.jersey.server.ResourceConfig
import javax.ws.rs.ProcessingException
import javax.ws.rs.core.UriBuilder


fun main(args: Array) {
    val HOST = "localhost"
    val PORT = 9000
    val baseUri = UriBuilder.fromUri("http://$HOST/").port(PORT).build()
    var server: HttpServer? = null

    try {
        server = GrizzlyHttpServerFactory.createHttpServer(baseUri, createConfiguration())
        println("REST Server Address: $HOST:$PORT")
    } catch (ex: ProcessingException) {
        println("Server Error: ${ex.message}")
        println("Exiting REST server...")
        server?.shutdown()
    }
}

private fun createConfiguration(): ResourceConfig {
    val config = ResourceConfig(HelloResource::class.java)

    // Optional but good practise to manually specify the JSON mapping implementation to use.
    config.packages("org.example.hellorestserver").register(JacksonFeature::class.java)
    return config
}
-------------------------------------------------------------------------------------

Above the host name and port number are stored in constants and referred to in the UriBuilder.fromUri function which creates a URI object. An attempt is made to start the server by creating an HttpServer object via the GrizzlyHttpServerFactory.createHttpServer function. Only 2 arguments need to be passed through, a URI and the resource configuration (ResourceConfig object).

Grizzly needs the resource configuration in order to know how to do the REST resource mapping. In this case the HelloResource class object (Java version) is passed as an argument to the ResourceConfig constructor in the defined createConfiguration function. If the server fails to start then a ProcessingException will be thrown. When that situation occurs the server error message is outputted to the console, followed by shutting down the server before exiting the program.

Now setup the REST resource mapping by adding the following code to HelloResource.kt:

-------------------------------------------------------------------------------------
package org.example.hellorestserver

import javax.ws.rs.GETimport javax.ws.rs.Pathimport javax.ws.rs.Producesimport javax.ws.rs.QueryParamimport javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response

@Path("/hello")
class HelloResource {
    @GET    @Produces(MediaType.APPLICATION_JSON)
    fun getMessage(@QueryParam("name") name: String): Response {
        println("Processing request...")
        return Response.ok(mapOf("msg" to "Hello $name! :)"), MediaType.APPLICATION_JSON).build()
    }
}
-------------------------------------------------------------------------------------


Text version:

-------------------------------------------------------------------------------------
package org.example.hellorestserver

import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response

@Path("/hello")
class HelloResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    fun getMessage(@QueryParam("name") name: String): Response {
        println("Processing request...")
        return Response.ok(mapOf("msg" to "Hello $name! :)"), MediaType.APPLICATION_JSON).build()
    }
}
-------------------------------------------------------------------------------------

Above the HelloResource class handles the REST resource mapping for the /hello path (part of the URI). There is a single function (getMessage) which handles a GET HTTP request that contains a single URI query parameter called name. All that the function does is output a message to the console, and returns a message (as a HTTP 200 response via Response.ok function) in JSON (specified in the Produces annotation) form.

To start the REST server execute ./gradlew run in the project directory. Use the curl command to test out the server (eg curl localhost:9000/hello?name=Elvis). Exit the server using the Ctrl+c keyboard shortcut in the same console running the server.

20 November 2016

Kotlin Scripting


Many people won't be aware that Kotlin has scripting support, which includes the REPL. If you run the Kotlin compiler without any arguments you end up in the REPL (Read Evaluate Print Loop) environment, which is similar to Python's.

Kotlin REPL

Within the REPL basic expressions can be executed. Can even do block declarations. Some of the BASH keyboard shortcuts work, like Reverse Search (Ctrl + r) which will bring up the last line of code that was entered if it matches the search terms entered. As is the case with Python the order of code execution is from top to bottom. Currently documentation on Kotlin scripting is very scarce. The best place to look is on the Gradle website.

Kotlin REPL running code

Compilation time with each line of code that is executed is very FAST. So fast that there will be some situations where it is significantly quicker to try things (eg prototyping) out in the REPL rather than writing and executing a basic Kotlin program in a IDE. There is a file format called kts that represents a Kotlin Script which can be run in the REPL via the :load command. Can also run kts files using the Kotlin Compiler. Do note that the :load command does not accept a path to the kts file which contains spaces. Hopefully that will be fixed in a future Kotlin release.

For a more advanced/functional Kotlin REPL use the one provided by IntelliJ (is available in the open source Community edition). Despite being slower and not as stable as the original it does make it much easier to execute/manipulate blocks of code, and provides code completion as well as pop-up API documentation. Also all code is highlighted depending on the syntax highlighter that is used.

Kotlin REPL in IntelliJ

Kotlin REPL in IntelliJ - Running code

Be aware that you may encounter the infamous IDE lock-up bug where you do some code completion, and the IDE doesn't respond to keyboard and mouse events. Should such a situation occur then the IDE will need to be force closed and restarted. Not sure if the bug is fixed in the current IntelliJ Kotlin plug-in but be on the lookout just in case.

IntelliJ doesn't have a template for creating a Kotlin Script project so you will have to improvise by doing the following in IntelliJ:

  1. Goto FileNewProject…
  2. On left side select Empty Project
  3. Click Next button
  4. Enter in the project's name and location
  5. Click Finish button
  6. Goto FileNewModule…
  7. On left side select Kotlin
  8. On right side select Kotlin (JVM)
  9. Click Next button
  10. Enter in Kotlin for the module name
  11. Click Finish button
  12. Create a folder called src


A big advantage with the improvised Kotlin Script project is that you will have a clean REPL environment that only includes the Kotlin default imports by default. Also you have a central place to manage Kotlin Scripts should you want to keep existing code snippets to run in the future. Do note that kts files in the project cannot be accessed in the REPL (includes items like classes, variables, constants etc).

In an ordinary Kotlin project the REPL can access items (classes, variables, constants etc) from a kt file provided the source file is pre-compiled and is in a package. You will need to be careful when importing an item to avoid name-space clashes, especially at the top level.

Kotlin REPL in IntelliJ - Accessing module item

One last thing to mention is that Kotlin can be used for scripting at the terminal level via the kscript project. Below is a sample script from the project:

--------------------------------------------------------------------------------------------------
#!/usr/bin/env kscript
//DEPS com.offbytwo:docopt:0.6.0.20150202,log4j:log4j:1.2.14

import org.docopt.Docopt
import java.util.*


val usage = """
Use this cool tool to do cool stuff
Usage: cooltool.kts [options]  ...

Options:
 --gtf      Custom gtf file instead of igenome bundled copy
 --pc-only           Use protein coding genes only for mapping and quantification
"""

val doArgs = Docopt(usage).parse(args.toList())

println("Hello from Kotlin!")
println("Parsed script arguments are: \n" + doArgs.joinToString())
--------------------------------------------------------------------------------------------------


23 September 2016

First Look At Kotlin


Has been a long time since I found an interesting programming language which changes the way you approach solving problems in certain areas. Last time I was into JavaFX Script however it didn't take off as expected mainly due to the Java community not embracing it in general, the language was too specific (domain orientated), and not enough resources were being allocated to improving/supporting it. Also when trying to use JavaFX Script in projects the interoperability with the Java ecosystem (JPA, JAX-RS etc) often ended up being a show stopper.

By chance when looking at alternatives for Android development I discovered Kotlin. Kotlin is reasonably easy to learn with its difficulty sitting in between Python and Java. What ended up being really attractive about the language is its pragmatism/industry driven approach to software development. Many features in Kotlin are very well thought out with every single one being a result of Software Engineering experience in the industry (ICT). There aren't many programming languages that manage to balance conciseness with readability. You end up more often than not reading rather than writing code.

One of my favourite Kotlin features is Delegated Properties, specifically storing properties in a Map. Below is an example of this:




Text Version:

class Person(val map: MutableMap){
     var firstName by map
     var lastName by map
     var age by map
}

fun main(args: Array){
     val map = mutableMapOf(age to 20, firstName to Joe, lastName to Bloggs)
     val aPerson = Person(map)

     map["lastName"] = "Burke"
     aPerson.firstName = "Jane"
     println("Person: ${aPerson.firstName} ${aPerson .lastName}, ${aPerson .age}")
     println(Person age is Int: ${aPerson.age is Int})
     println("Map -> First Name: ${map["firstName"]}")
}



What you have above is an example of bidirectional Data Binding (sort of), which opens up a number of interesting real world applications like binding a database model (the model class, not the actual database) to a view. Despite the MutableMap using mixed types for the values it works just fine for the Person properties that rely on type inference via delegation. Blogger unfortunately doesn't have syntax colouring support for Kotlin code, is Google planning to fix this?

Some people view Kotlin as a statically typed version of Python however it isn't entirely warranted. If anything Kotlin is most similar to Swift. Even the language goals are very similar:

  • Concise
  • Safe
  • High performance
  • Versatile
  • Tooling
  • Interoperable

Kotlin documentation isn't too bad (the quality of the references is good) however it is seriously lacking a decent tutorial. Confusingly the navigation of the documentation section of the Kotlin website is all over the place. The Kotlin Koans for instance is in the Tutorial area instead of the More resources area. There appears to be a “Getting Started Guide” in the Reference area. If it is a tutorial then it needs to be moved to the Tutorial area.

Some Kotlin design decisions are questionable/controversial. Closed (sealed) classes are one decision which is very odd considering that there are a significant number of libraries/frameworks that rely on open class design, and Software Engineers frequently design software using an open class architecture anyway. Another one is Data Classes where some implemented functions are included for free (toString, equals, hashCode), and object de-structuring is automatically supported, which should be in ordinary classes instead. Using Data Classes causes severe issues (no class inheritance etc) that would be easily avoided by going with ordinary classes anyway.

Below is a list (not exhaustive) that shows who is using Kotlin:


Companies

  • Amazon
  • Google
  • Netflix
  • NBC (NBC News, TODAY, and Nightly News Android apps)
  • American Express
  • Pivotal (own Spring framework)
  • Expedia
  • Square
  • 3D Robotics (3DR Tower Android app not available in Google Play)
  • Basecamp (creator of “Ruby On Rails”), Basecamp Android app
  • Prezi
  • JetBrains
  • MongoDB
  • BQ (various Android apps not available in Google Play)
  • Meizu (various Android apps not available in Google Play)
  • App Foundry
  • GMC
  • Allegro Group
  • Bryx 911 (first responder Android app not available in Google Play)
  • Trapit (builds Android apps for some fortune 500 companies using Kotlin)
  • Farm Logs (Android app not available in Google Play)
  • Nulab Inc (Android app not available in Google Play)
  • Pinterest

Software Projects

  • Anko (official Android application development library for Kotlin)
  • Kotter Knife (Android view binding library for Kotlin)
  • TornadoFX (JavaFX library for Kotlin)
  • MapDB (embedded NoSQL DB for the JVM)
  • Requery (SQL query and persistence library which has Kotlin support)
  • Exposed (official SQL library for Kotlin)
  • Spec (official unit testing framework for Kotlin)
  • Kara (web framework for Kotlin)
  • Quasar (JVM concurrency library which has Kotlin support)
  • Spring Boot (micro services framework which has Kotlin support)
  • Gradle (version 3 onwards has support for developing plug-ins using Kotlin)
  • RxKotlin (RxJava bindings for Kotlin)

Android Apps

Kotlin Jobs (Possible Users)

One of the major surprises with Kotlin is the significant interest in the language from the Android Development community. Certainly helps when Jake Wharton (likely the most well known person in the Android Development community) is endorsing Kotlin. Many in the community want Google to support Kotlin as an alternative to Java.

In Fragmented postcast #20 an out of blue question was asked by one of the presenters, “When is Google going to support Kotlin in Android Studio?”. Why hasn't Kotlin been covered in an Android Developers Backstage podcast yet? Since late last year there have been a few Googlers frequently visiting the Kotlin slack channel, which has recently celebrated reaching the 4000 registered users mark.

As you can see it is highly unlikely Kotlin will be going away considering the sheer number of major companies and Android apps using Kotlin. If anything this shows that all Java developers should be seriously looking into using Kotlin for some projects if they haven't done so already. Kotlin is highly likely to represent the biggest change to the JVM landscape after Java 8.