DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. Kotlin in action: wrapping vert.x

Kotlin in action: wrapping vert.x

Alex Tkachman user avatar by
Alex Tkachman
·
Jul. 18, 12 · Interview
Like (1)
Save
Tweet
Share
18.54K Views

Join the DZone community and get the full member experience.

Join For Free

This is pretty short note where I want to show power of Kotlin in real life use.

We will wrap amazing vert.x framework in order to make it a bit Kotlin-ish but the main goal will be to show couple of standard ways to wrap existing Java API.

Let us start with standard example from vert.x - Echo websocket server. Here is Java code

public class PerfServer extends Verticle {

  private static final int BUFF_SIZE = 32 * 1024;

  public void start() throws Exception {
    vertx.createHttpServer().setReceiveBufferSize(BUFF_SIZE).setSendBufferSize(BUFF_SIZE).setAcceptBacklog(32000).
        websocketHandler(new Handler<ServerWebSocket>() {
      public void handle(ServerWebSocket ws) {
        Pump.createPump(ws, ws, BUFF_SIZE).start();
      }
    }).listen(8080, "localhost");
  }
}

And here is the same code with Kotlin

public class PerfServer() : Verticle() {
class object {
val BUFF_SIZE = 32*1024
}

public override fun start() {
createHttpServer{
receiveBufferSize = BUFF_SIZE
sendBufferSize = BUFF_SIZE
acceptBacklog = 32000

websocketHandler { ws ->
//System.out.println("connected " + ++count);
Pump.createPump(ws, ws, BUFF_SIZE)!!.start();
}
}.listen(8080, "localhost");
}
}

We use very important pattern here - "function literal representing extension function" Probably the easiest way to explain what do I mean is to show what is the method createHttpServer we use in the code snippet above.

public fun Vertx?.createHttpServer(config: HttpServer.()->Unit) : HttpServer {
    val httpServer = this!!.createHttpServer()!!
    httpServer.config()
    return httpServer
}

public fun Verticle.createHttpServer(config: HttpServer.()->Unit) : HttpServer = getVertx().createHttpServer(config)

What we do here is "extension functions accepting extension function as parameter". We "extend" Vertx and Verticle interfaces from vertx Java API with new methods and when we pass function literal as parameter to a call to createHttpServer there is implicit this/receiver of the type HttpServer and we can use methods and properties without specifiing receiver explicitly. This is very powerful ingridient of building DSLs with Kotlin.

It is also interesting to notice that in the method Vertx?.createHttpServer we have to deal with nullability (Java API integration point) but in one we really use (Verticle.createHttpServer) we do not.

Now small note on extension properties. Vertx has convension of chainig setters. In Kotlin world each such setter returns HttpServer? (? means nullable), so we either have to use !!-operator (ensure not null) on every chained call or to do something different. My first (and very natural) solution was to make a lot of named arguments with default value for the createHttpServerMethod similar to what we did in previous article To make life more interesting we will use another power approach - "extension properties"

I hope following code in self explaining. We extend HppServer class from vertx Java API with new properties

public var HttpServer.sendBufferSize : Int
    get() = getSendBufferSize()!!
    set(v: Int) {
        setSendBufferSize(v)
    }

public var HttpServer.receiveBufferSize : Int
    get() = getReceiveBufferSize()!!
    set(v: Int) {
        setReceiveBufferSize(v)
    }

public var HttpServer.acceptBacklog : Int
    get() = getAcceptBacklog()!!
    set(v: Int) {
        setAcceptBacklog(v)
    }

And finally just for the sake of completeness I want to show probably the simplest part, which is definition of websocketHandler method

public fun HttpServer.websocketHandler(handlerFun: (ServerWebSocket)->Any?): HttpServer
        = websocketHandler(handler(handlerFun))!!

public fun <T> handler(handlerFun: (T)->Any?) : Handler<T?>  = object: Handler<T?> {
    public override fun handle(arg: T?) {
        handlerFun(arg!!)
    }
}

Utility function handler helps us to wrap Kotlin function literal in to Handler interface from vertx Java API and websocketHandler extension function let us use nice Kotlin function literal syntax.

You can find more examples and tricks on vertex-kotlin project on github

Thank you for reading. As usually I hope it was interesting.

Till next time.

Kotlin (programming language) Vert.x

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Connecting Your Devs' Work to the Business
  • Easy Smart Contract Debugging With Truffle’s Console.log
  • Using AI and Machine Learning To Create Software
  • Streamlining Your Workflow With the Jenkins HTTP Request Plugin: A Guide to Replacing CURL in Scripts

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: