Robert's blog
Robert Važan

High productivity development stack

Too much code to write and too little time to spare? I was facing the same problem in my work and hobby projects. Take a look at how I do things today to save time and maximize value of my work.

TL;DR

Use linux on both the server and your workstation. Script everything instead of clicking around. Discover the new Java, but stay away from enterprise stuff. Run your app server-side and use HTML/CSS for the UI. Deploy to cloud, not bare metal. Build stateless servers that access cloud data. Enjoy the free stuff.

Linux

Linux remains the only workstation OS on the market after Microsoft took Windows down the tablet path. Of grave importance to developers, Microsoft's stack effectively guarantees startup failure.

Linux comes with one killer application: bash. Yes, I know about PowerShell, but bash is actually useful. Linux software takes shell-first approach to user interface. There is a command-line utility for everything. Shell scripts are simple, readable, and there is a simple way to control servers with them via ssh. Since moving to linux, I scripted everything that I used to do manually in GUIs.

Developers use a lot of tools and developer's workstation can get really messy very quickly. I control clutter and add a bit of security by wrapping messy things with docker or virtual machines (VirtualBox at the moment). I am using VMs for development environments, test machines, Windows tools, and some special apps. Virtualization eats a lot of hardware, but then, you cannot be productive on a notebook anyway.

Java

Java is kind of an obvious choice on linux. It lies on the intersection of language features, performance, and large community. Hard to beat that. I can tell, because I have also used C++, C#, Go, and JavaScript extensively in the past.

Java gets some bad rap, because it is perceived as enterprisey and associated with unpalatable jobs in financial institutions. But that's not my java. J2EE might be enterprisey, but java itself is a lean and modern language. Even more so when augmented with lombok, my noexception, and a bunch of collection & utility libraries.

I run Eclipse in a virtual machine. I am thus impatiently waiting for Che. Augmenting jUnit with mockito makes testing so much easier. I stick with maven for its widespread support.

Web

While java alone can support complex application logic, there is no use for it without user interface.

Desktop apps are dead and smartphone apps will die too. Web is the future. Distant future is in video streaming. The closest we can get today is to stream HTML updates over websocket in what I call server-side RIA framework as experimentally implemented by my pushmode server.

UIs tend to be full of events, which leads to incredibly complicated code. Recently, reactive programming is being widely adopted as a cleaner alternative to events. I have myself developed hookless reactive framework that implements what I call transparent reactive programming. I have a custom-coded reactive reload for templates, CSS, and even java code (eyeing Hotswap Agent + DCEVM).

While reactive server-side framework is a bit exotic, I am also using countless standard tools: measurement API for analytics, embedded jetty for REST APIs, link checker, favicon generator, and lots of online CSS / color generators. Some people prefer LESS or Sass over plain CSS.

Cloud

I came to understand that cloud is not merely a virtual machine hosting. Cloud involves completely new workflow and hundreds of lines of scripts and configuration files. In theory, standardized workflow would result in simple configuration, but I see no way to accommodate various server types, diverse ways people want them configured, non-VM cloud services, and unique features of the various clouds in one standardized workflow.

I personally stick with simpler, low-cost clouds (currently Vultr) that have APIs for scripting. I practice stateless server architecture where my scripts recreate the server from scratch instead of patching it. I don't bother with configuration tools (chef, salt, ...). I implement my workflow in bash, ssh, curl, and jq instead, which turns out to be much more productive and flexible.

Once the new app server is deployed, traffic is routed to it and the old server is discarded. I am switching traffic by updating HAProxy config or by updating DNS records via API. I don't bother with high availability at the moment. I keep the server tidy by wrapping messy stuff in docker.

Java code needs to be frontended with nginx, which provides HTTP2 transport and TLS encryption (using Let's Encrypt certificate). Static content is served from CDN.

Running a server is different from publishing software in that the server needs to be monitored to keep uptime reasonably high. Logs from java code fall through logback to syslog, which is then archived and monitored with free papertrail account. If the server goes down, I get an email notification from UptimeRobot.

Since my servers are stateless, I don't store any data on them other than cache. I mostly store data in Amazon AWS (S3 and DynamoDB), but I also run redis as a reactive database.