Go lang

It has been a crazy few months in startup land. The interesting thing for me about startups is no matter how crazy it is compared to corporate work, I find myself really content amidst the chaos. The big change here is we have decided to build our backend architecture in Go instead of Java. Having done Java for 19 years this is a big change, but for business decisions we decided that the trade offs with Go were better for our long term business needs than the trade offs with Java. Now that I have been using it for a few months I figured I would discuss some of the differences between the languages and what I like and dislike about each.

First Impressions

Just from an initial impression to me, Go seems like a cleaned up C language. You basically have a low level language with primitives and structs, slices (lists in Java), maps, and not a lot more. You end up having to build and write more code than in Java. But in sort of a nod to the good parts of OO they have interfaces and methods that you can attach to structs. At that point it is almost like a super lightweight C++.

I find that I spend a lot more time wiring up code in Go. Having done Spring now for 10 years you spend very little timing wiring up your code as everything is autowired, and you mostly just focus on business logic. Same for SQL Spring Data provides such a nice DSL you don’t write that many database queries either. In my initial analysis it took about 10 times as much code to write a simple REST backend in Go as compared to Spring Boot. But it used 1/10 as much RAM or less. This is the reason we decided to spend more money on Development costs (as it is much more code to write than Java) as we believe the savings on cloud hosting costs down the line will make it a better decision for us.

Go produces a single binary just like Spring Boot gives you a fat jar so I consider them equal here, but the startup time for Go seems to be instant, where as due to all the reflection and wiring at startup in Spring it seems like those apps typically take about 5 seconds to start in my experience (if there is a database involved).

Ceremony

General

Go has taken some steps to remove the ceremony in the language. One of the big differences that I notice is that you no longer needs ()around your statements in for loops, while loops and if statements. I repeatedly find myself putting those in by default and then having the IDE remove them. Another big difference is you no longer have to terminate your statements with ;as the compiler automatically puts those in for you. A little bit like Groovy in that regard.

Iteration

You would think that after doing all that work to remove ceremony that the language would be clean in general. But here is where I see the low level C type stuff come through. In Java if I want to iterate through a list it looks like this:

for (item : list) {

Basically it reads as for each item in the list, and the you operate on it. Go has a range statement to iterate through an array or slice. Here in lies a big difference in Go between Java is that you can return multiple values from a function or method. The designers of the language decided to have the range statement return both the index and the value. Generally in Java if I am using a for each it is because I don’t care about the index, I use a standard for loop if I need the index. Go has the standard for loop but for some reason they decided to return the index as well. You end up having to throw it away if you don’t care about it which feels like more ceremony again so the above statement ends up reading:

for _, item := range list { It is hard to look at that and think that reads better than the Java even though they got rid of the parenthesis.

But even this sort of misses the point as I am not even using for each that much in Java these days instead we have moved to a higher level yet and now use stream operations and handle everything in a functional style. What ends up happening in Java is you spend your time telling the language what you want to happen and let it sort the details of how to do it (lazy execution, or parallel execution, it doesn’t really matter with streams). In Go you spend your time telling the language how you want it to do the iteration so it feels like you are back down in the weeds again.

Initialization

Initializing an empty list also feels like it is more ceremony in Go. In Java you might have:

var list = new ArrayList<String>();

You look at that line and you have the ceremonly of the generics and the () to state which constructor you are calling and then the semicolon to terminate the statement. In go you end up with something like

list := []string{} again I wouldn’t call that better, just different. The ceremony here is the := which allows you to leave out the var at the front and you have the braces at the end which are initializing the struct. It is shorter but again neither seems to read better nor worse, just different.

References

One other big difference which really brings me back to C is you have to specify whether you are dealing with a value type or reference type in Go. In Java all primitives are value types and all Objects are reference types so you don’t have to spend any time thinking about it especially in a world of autoboxing. The drawback to the Java approach is if you need performance and memory compactness sometimes you need to use arrays of primitives and not collections. This is something that can definitely trip up a new programmer. Another problem is if autoboxing isn’t handled correctly it is possible for a NullPointerException to be thrown which could also be confusing to a junior developer.

In Go you have to explicitly thing about whether you are passing a value to a struct or a reference to it. Arrays and slices and maps are automatically reference types but any of your structs you have to explicitly declare if it is a pointer or a value type. For example

type struct Person {
  Name string,
  Age uint
}

pointerToPerson := &Person{Name:"Jeff", Age:41}

valueTypePerson := Person{Name:"The Doctor", Age: 904}

If you want to use pointerToPerson above you have to dereference it with the *. If the pointer is nil you will panic if you dereference it. On the other hand the value type if you don’t initialize it goes to default values so the default for the string is an empty string ""and the default for the integer would be 0.

Concurrency

Concurrency is where Go both shines against Java and feels lacking at the same time. Let’s talk about what is great if you want to call a function concurrently it is amazing you simply do:

go handleData() and handleData() will be executed concurrently. The great thing about go calls is they are extremely lightweight. When I read about project loom where they want to bring fibers and continuations to Java. Because they are much lighter weight than a thread in Java you can have thousands of them without a performance issue. It is my understanding that their is a threadpool underneath that executes your different go routines I think similar to an executor in Java with runables, but again I think the go routines are using much less memory than a Java Runnable.

This kind of light weight concurrency seems to be the direction everything is going whether it is the node system of events and async callbacks or even the reactive movement going through spring. Everyone is trying to execute more things concurrently with a very small thread pool.

There is much more ceremony in a Java Runnable or Callable. First I have to implement an interface and then put my code in a specific method. Then I need a Thread or an Executor on which to execute the code. If it were a Runnable and I needed a return type I would need to pass in some sort of concurrent collection to safely send the data back to the other thread in, or I could return it directly in the callable when I get a future out of that callable that can give me the return value.

Java definitely has a ways to go to catch up to go with the ease of concurrency, but the types are much richer for concurrency in Java so with java.util.concurrent.* one has access to about anything you need. In Go you pretty much just have channels to safely pass data between separate Go routines this again has that simple feeling of C where you are building everything up from primitives vs Java where the libraries are much richer.

Tooling

Here in you can tell how young of a language Go is. To me the tools feel like going back in time to around 2005 in Java. The debugger (delve) is primitive and I often find it not stopping at my break points or not showing me the values of all of my variables. I remember using JBuilder and Visual Cafe and some of the early Java IDEs and having similar issues of the debugger just not working that well. I find myself using printf statements to debug again which feels like going back in time 20 years.

IDE support seems decent though otherwise (if you throw out the debugging issues). I am using IntelliJ Ultimate with their Goland plugin and find myself very productive in writing code. It is the same IDE that I know and love from my Java work, and the understanding of the syntax in general seems to be great. I hear that VSCode is also pretty good for writing Go.

Enterprise Features

This is a small point but one that I just hit in the last week or so and that is that the language lacks support for batching SQL statements. Given that Java is such a strong enterprise language I just assumed that would be built into Go as well, especially given that the language is 9 years old, but maybe most of the internet type software being built isn’t using batch operations to slam a lot of data into a database at once.

Conclusion

At this point I still think Java is a more enjoyable language to program in. I like the higher level you can operate at with things like the stream api, and I like how opinionated Spring is. I think that saves you time setting up a new service and leads to consistency when dealing with new code that you haven’t seen before. Go concurrency model feels like it could be more powerful which is why there is that Java project loom to bring fibers and continuations to the language. The value types are an advantage and result in Go using very little memory compared to a typical spring project, which is again why in the Java world they are working on bringing value types into the language. Go is definitely powerful and fast and effective at what it does. If I were still a C programmer I would probably love it, as it feels like C without all the annoyances. As it stands now I can use it, and it works well, but I am not yet passionate about the language.

Bug in Jackson JSON serialization of Immutable objects

The bug

I have been using Jackson for JSON processing for many years now. It is a great framework and mostly just works. It is the default framework in Spring Boot and mostly it just sits behind the scenes and drives most micro services in Java these days. That is why I was surprised when we hit a bug in the framework as I hadn’t really had any issues in the past.

The backstory

Anyone who has coded with me knows that I tend to favor immutability for most java objects. By default I make everything final and then only has non final things when they are necessary. This principle is documented in Effective Java Second Edition Item #15. As a side note everyone should read that book. Even senior developers benefit greatly flipping through the book once a year and reviewing the items. It may be the best Java book I have ever read for writing very good code. My hope is that Josh Bloch does a 3rd edition to cover all the new functional operations in the language.

The best way that I have found to create Immutable Data Transfer Objects in Java with Jackson is to have all the fields be final values, and to annotate the constructor with @JsonCreator and each property in the constructor with @JsonProperty("propertyName"). Just like that you have an object that won’t change state and works seamlessly between your Java Service and your JavaScript front end or between 2 Java back end services.

The problem

The problem we found with this approach occurred in an integration with another partner. Our developer was trying to use Java best practices so the variables are camel case and he is using @JsonCreator in the constructor and naming the properties there. While that works great for an inbound object when trying to serialize that object out to JSON Jackson is throwing away those property names and serializing off of the field name. Normally our field name matches our property name so this is no issue. But in this case the property on the other side was something like first_name, but we record the variable as firstName. Jackson is serializing that as firstName if you only use the Constructor approach. If you add @JsonProperty("first_name") to the field it will work. So you are basically left either double annotating the field or going with a mutable POJO object to get the correct output. I have created a project on github demonstrating the problem:

https://github.com/haskovec/jackson-serialization-bug

Additionally I have opened an issue on the Jackson project for anyone who is interested in following this issue. So far I haven’t heard anything back on it.

Closing thoughts

So the real question is how did this thing go through without getting caught. My suspicion is that most developers don’t actually create Immutable objects in general. The other possibility is that people don’t often have an output that doesn’t match the variable names. We could take the ugly approach and declare final String first_name; to fix it but that doesn’t make me happy either.

I will be interested in seeing if anyone responds to the issue and what they say. I think it is always a good test of a project to see how active it is by seeing how long it takes for the developers of the project to at least comment on a given issue found in their code. I did a little bit of debugging into the Jackson code and I can see where it is throwing away the correct property values, but I am not sure what the correct fix is. It feels like a method that if I tried to fix I could easily break some other use case.

Update

Turns out it wasn’t a bug and I got great help on the team to fix the issue.

TIL: default hashCode() in Java

I came across this blog post today which I thought was really good. It is a deep dive into the default hashCode() implementation in java. To me the most amazing outcome of the piece is that if a given class is going to be accessed by multiple threads you really need to override hashCode otherwise biased locking is disabled. All in all it is an interesting look in the guts of the JVM and worth a read: default hashCode

AWS Lambda or should I call them nano services?

Recently at work I worked on a project using Amazon AWS Lambda. This is a cool concept. Amazon calls it serverless computing, but really what it is, is abstracting the server so that you can just focus on a small task that needs to run.

In this case we had a rest endpoint that just stores some data in a database.  If we think about a traditional Spring Boot Microservice we would probably do Spring Data JPA, point it at a mysql DB, and then have some rest controllers that talk to a service tier which persists the data. With Spring Boot this isn’t much code, but you still have some embedded Tomcat Server and a fair amount of ceremony for doing something very simple. After building the app you will need to deploy it to Elastic Beanstalk instance or else an EC2 Nano Instance or something similar. That is a lot of DevOps overhead to do something very simple. With Lamdba we can create a simple class that takes a pojo java object (Jackson style). With Lambda you don’t have Hibernate, you are just dealing with raw JDBC but when you are just inserting 1 Row into a Database you don’t really need am object relational mapping. You then use Amazon’s API gateway to send any requests to an endpoint to the lambda function and you are all good to go.

That got me thinking S3 now has the ability to serve an S3 bucket as a website, so you could drop an angular app into an S3 bucket and serve that up and then point it at API Gateway which then hits a Lambda and talks to an RDS instance. If your site didn’t have much traffic it would be a super cheap way to host it as Lamdba is billed based on how much compute time you use and in our case our task runs so fast I am not sure we will even break out of the free tier with all the traffic we get. You could run an entire site with no server instances provisioned which is cool. In reality I think as the app grew it would be hard to manage as separate lambda functions and you would benefit greatly from a proper framework like Spring, but for something very small and light this seems super cool. The other neat thing about Lambda is the wide language support you can use, so I wrote my Lambda in Java and my boss just made a Lambda to do some logging that was written in Node. It is a super cool concept worth checking out.

MacOS Sierra massive slowdown in Java networking

I upgraded to MacOS Sierra, and have really been enjoying the shared clipboard. I haven’t really noticed any other new features that impact my day to day development, however I would advise Java developers to avoid it for the near future. I have searched and searched and I wasn’t coming up with any results. Then I found this blog post. This is definitely part of the problem. I made the host file changes and got a slight boost, but not enough to explain the whole thing.

First our original application is a monolithic Spring 4.2 app running in Tomcat. On my MacBook Pro it was taking 21-25 seconds to launch. After going to Sierra it started taking 75 seconds. Once I did the host file fix in the blog post above it started launching in 59 seconds. Still much worse than before.

Another Spring Boot micro service we have that does a lot of external api calls and also communicates through Amazon SQS would previously launch in 11 seconds on my laptop and now takes 141 seconds (150 prior to the fix outlined above). Even worse the messages to and from SQS and the third party API’s are painfully slow, sometimes taking 30 seconds or more to go through when previously they were almost instantaneous.

I am still searching for a fix for the issue, but it is practically unusable. I am debating if I am going to roll back to El Capitan, but at this point I would recommend people hold off on upgrading until there is a good understanding of what the slowdown is and how to fix it. Java itself when not hitting the network seems as fast as ever.

JHipster

I was reading the Spring Blog the other day and I came across this story. I was intrigued because I found the name funny so I read the post and watched the embedded youtube video and was completely blown away. Take all the excitement I had for Spring Boot after SpringOne and multiply it by 10. Not only does this build on top of Spring Boot it integrates in all the trendy front end technologies that are in use today. All the pain of bootstrapping and setting up a full on website is taken away while they do all the work for you.

JHipster is built on Spring Boot, Spring Security, Node.js, Angular.js, and Yeoman. Basically it manages to boil down every trendy front end technology with every trendy back end technology and do all the integration for you so you can start ripping code. They support Maven and Gradle as well as Grunt or Gulp. I admit I had never really heard of Yeoman or looked into it, but it is amazing. You can really automate a ton of your repetitive tasks with it so you can focus on solving the real problems you are facing. This project seems like a startup companies dream since all that monotonous configuration can just be skipped and you can focus on getting your application up and running and just out there.

This also fits in with my themes for the year where I wanted to spend more time working with Spring Boot as well as learning Angular and now I can all in the context of trying to build a small project under JHipster. Anyway the technology looks amazing and I would encourage everyone to give it a look and see what you think. Oh and a pro-tip if you are a non-hipster like myself running windows, when you do yo jhipster to generate your app, do it from inside of your git-bash window as if you use a normal windows cmd prompt it seems to fail in the course of generating the app.

Code Coverage

In my current position one of the metrics we track is code coverage for our unit tests. When I started at the company we were using JUnit with Mockito and JaCoCo. This was a pretty good setup we got good coverage reports and Mockito makes the testing writing much easier.

One of the limitations of Mockito is that you can’t mock private methods or static methods. This presented an issue for us in reaching our desired level of coverage. We initially worked around some of the private method issues using reflection, but it wasn’t always ideal. The decision was made to use PowerMock. PowerMock solved all of our Mockito issues immediately. It was compatible with Mockito but gave us some new powerful features to allow us to get much better unit test coverage. Then we ran our Jacoco reports and found that the reporting no longer worked. Due to the way PowerMock uses byte code manipulation in order to mock static methods it is not compatible with JaCoCo and there is no plan for them to support measuring that.

So we figured no big deal and switched to Cobertura. The first problem with this change is that Cobertura 2.0.3 has a regression in it so it won’t report coverage with Powermock. We figured no big deal we will run the 1.9.4.1 release of it until they release a bug fix so we can update. Unfortunately the update has never come. You go to the roadmap for the site and you see it hasn’t been updated since November 7, 2013. There appears to be very little activity on the project, and we haven’t seen an update in 2 years. I see work going on in the github repository but there seems to be no attempt and doing any maintenance or fixing the issues for the existing users, and I can’t get a feel for when the 2.1 release is ever going to come out. A second issue is that the current version doesn’t support Java 8 and I would like to update to Java 8 in the very near future. At what point when dealing with open source software do you say the project is either dead or too inactive for us to rely on for business needs?

Cut to last week I was updating some libraries in the project and I wanted to upgrade from PowerMock 1.5.5 to PowerMock 1.6.1 and my coverage reports went to 0. So it seems our old version of Cobertura can’t handle the latest PowerMock. I did a test with Atlassian Clover and our coverage reports worked perfect and looked better than anything I have ever seen for a report. At that point I decided I had reached my breaking point with Cobertura and put in a request that we move to clover and buy some server licenses and work and in the meantime while waiting for approval I had to settle for PowerMock 1.5.6 until we can get approval to buy Clover licenses.

Going forward when someone suggests a new tool to fix an issue that we are having, I have to say that I am going to be looking into other things that tool drags along with it as I don’t want to be in the situation again where we are trading one problem for another.