The Modern Java Platform - 2021 Edition

Many developers were burned by the overly complex world of Java back in the early 2000s. The Gang of Four patterns and middleware / J2EE / Java EE led to ridiculous levels of alleged decoupling as is evident in this sequence diagram from an open source J2EE ecommerce system I worked on in 2002: BrowseCatalogForProduct

Back in 2014 I wrote about how things had changed: Java Doesn’t Suck – You’re Just Using it Wrong.  But six years have passed since I wrote that and things have continued to improve, making the Java platform a fantastic option when building microservices, data pipelines, web apps, mobile apps, and more.  Let’s walk through some of the “modern” (as of 2021) aspects to the Java platform.

Running One-Off/Admin Jobs for Cloud Run Services

Disclaimer: This is not officially supported by Google Cloud.

Cloud Run hosts services that handle HTTP requests but sometimes you need a way to run one-off / admin jobs with the same settings and container image. At this time the managed Cloud Run service doesn’t provide a way to run those kinds of processes and running them through HTTP handlers can result in short timeouts (5 minutes by default, max 60 minutes), the possibility to accidentally run them more than once, and potential security issues. Whether you need this for schema migrations, management tasks, or something else, I’ve made it easy for you. Click to launch a tool in Cloud Shell that will walk you through it:

One-Off Cloud Run

Want to see more about how it works? Watch this short demo:

Container-based Serverless Scheduled Jobs on Google Compute Engine

Most of my compute workloads today are on Cloud Run, a serverless for containers platform. But some workloads like scheduled jobs don’t fit the service-oriented model of Cloud Run. There are many places I can run those workloads but I’d like to keep the serverless “pay for what you use” model and still use containers as my packaging format. I could use Kubernetes for these and use Cloud Run for Anthos to run everything in one place but I wanted something more bare-bones. I created a way to hook up Cloud Scheduler so that it starts scheduled jobs from containers on Google Compute Engine. Here is a video walkthrough for how to set it up and use it:

GraalVM Native Image Tips & Tricks

Elastic infrastructure that scales up & down based on demand is not just a “serverless” fad but an operational model which reduces cost and waste. Yet there is a little devil lurking under the covers… When an application / microservice needs to spin up based on demand there can be some lag as the application needs to be downloaded to the node, potentially a VM needs to be started, the application itself needs to be started, and potentially local caches need to be hydrated. In traditional enterprise systems this “cold start” process can realistically take tens of minutes. But it’s near impossible to have demand-based scaling when things take that long to start.

GraalVM is a Java Virtual Machine implementation that addresses parts of the “cold start” problem by doing Ahead-Of-Time (AOT) compilation on JVM-based applications. GraalVM can create a “native image” of your application so that it no longer needs to run inside a JVM. This can reduce startup time and in some cases improve overall performance. The native images can also be much smaller than the usual OS + JVM + all dependency JARs. For example, a recent application I was working on went from a pretty trim 208MB docker image (OS + JVM + deps + app) that started in 2 seconds, down to 14MB and a 0.5s startup time. Sounds amazing! But there are some caveats, tips, and tricks I’d like to share with you.

When you hear ‘Monad’, think ‘Chainable’

There comes a point in every Functional Programmer’s life where they feel the curse of the Monad has lifted and they must now explain Monads to their friends who just don’t get it. What follows is probably wrong and confusing, cause there is no escaping the curse. But here goes… Suppose you have a system property that contains the name of another system property, like: KEYNAME=FOO And you want the value of FOO, like:

Thank You for 12 Years in Developer Evangelism

Even though it was 12 years ago, I vividly remember sitting in a musty conference room with big-name analysts from Gartner. My palms were sweaty and I was almost too terrified to speak. Macromedia had brought me into this meeting to be the customer voice for their new programming platform, Flex. I was an early adopter building a customer portal using this new technology. But I was a coder—not someone who talks publicly.

Connecting to the Salesforce REST APIs with Spring Boot and Java

Broadly speaking there are two types of integrations with Salesforce, either a system-to-system integration or a user interface integration. One of the primary ways to do these integrations is by using the Salesforce REST API. When using the Salesforce REST API you need to obtain an access token that identifies who is making the requests. OAuth 2 provides an HTTP interface to obtain a Salesforce access token. When using the Salesforce OAuth 2 API there are three options for obtaining an access token:

Quick & Easy ETL from Salesforce to MySQL with Workflow & Heroku

While sometimes unfortunate it is often necessary to have data silos that share data. The Extract, Transform, and Load (ETL) pattern has been around for a long time to address this need and there are tons of solutions out there. If you just need a quick and easy way to copy new & updated records in Salesforce to an external data source, a simple Heroku app and Salesforce Workflow might be the quickest and easiest solution.

Scalable Continuous Delivery Pipelines

Back when I first started building web apps we’d just “do it in production” by vi’ing Perl & PHP files on the server. This was fine because the risks and expectations were low. No big deal if I broke the app for a few hours. Good thing I made an app.php-bak copy! As software became more critical to businesses, the risks of making changes to production systems increased. To cope with these risks we slowed down delivery through processes.