Java 8 Optional Anti-pattern

One occasionally comes across an anti-pattern involving the java.util.Optional<T> class that was introduced by Java 8. It looks like this:

Optional<String> maybeName = getName();
if (maybeName.isPresent()) {
    return maybeName.toUpperCase();
} else {
    return "NOBODY";

The above code is written in the imperative style: a sequence of statements that the computer is instructed to follow. The code works, but it's well... awkward by comparison with the following alternative:

return getName()

The alternative (immediately above) is written in the functional style: expressions chained together to form other more powerful expressions. For my money, the functional style more clearly expresses the programmer's intent: get a name and transform it to upper case, or else return "NOBODY". I get that in one glance, whereas I have to pause a little to walk my mind through the steps specified in the previous example.

If you needed to do some processing to construct the or-else part, you might prefer to use the orElseGet() method, which will only do the expensive work if it's needed:

return getName()
    .orElseGet(() -> getDefaultName());

In fact, supposing that getDefaultName() is defined as a static method on MyClass, the orElseGet() could be further refined as follows:

return getName()

If you wanted to throw an exception if the 'happy' path could not be traveled, you could use the orElseThrow() method, like this:

return getName()
    .orElseThrow(() -> 
        new IllegalArgumentException("No name"));

The imperative style will gradually become less idiomatic as the influence of Java 8 and its successors takes hold.

The functional style of programming encouraged by Java 8 features like the Optional class is worth learning because it makes for more perspicuous code.

Using Charles Proxy with Play Framework


I got Charles Proxy working with Play Framework in such a way that I can record all of the web requests initiated by my Java-based web application. It was very easy to get Charles to intercept HTTP requests emanating directly from the browser; it was less easy getting Charles to intercept HTTP requests originating in the Java code.


Charles is a web debugging proxy application for Windows, Mac OS, and Linux. You run Charles on your computer, and it logs web traffic on your machine, whether that traffic is HTTP(S) requests initiated by your computer, or HTTP(S) requests received by your computer. You then examine the history of requests, responses and HTTP headers in Charles' user interface. As you can imagine, Charles is an extremely useful tool for web application developers.

Play Framework is a web framework on which you can build a web application in Java or Scala. Play Framework is currently at version 2.4, and that's the version that I'm using.

I'm using Firefox, which is currently at version 43.0.4.

I'm developing the web application on Mac OS X 10.9.5, and this blog post therefore relates to that operating system.

Installing Charles on Mac OS

Installing Charles is pretty easy. Just follow the directions in the documentation. Under Browser & System Configuration, the doco says this about installation on Mac OS:

"When you first install Charles you will be prompted to grant permissions to Charles to autoconfigure the proxy settings. After that, Charles will configure and then reconfigure the Mac OS X proxy settings whenever Charles is started or quit."

In other words, when you start Charles it automatically wedges itself into the networking components of your computer so that HTTP traffic originating in Safari and other Mac OS applications passes through Charles on its way out of your computer. After starting Charles, you'll be able to see the proxy enabled in your network settings:


Getting Charles to intercept HTTP requests from your browser

If you visit a web page in Safari you'll see the HTTP GET request, and the corresponding HTTP response listed in the log inside Charles.

If you're using Charles with Firefox, you need to ensure that the requisite plug-in is installed in that browser. The Charles configuration doco says:

"When you first install Charles, it will check for and prompt you to install the Firefox add-on. If you don’t install the Firefox add-on immediately you will later need to enable Firefox configuration in the Proxy Settings in the Proxy menu."

The good news is that once the plug-in has been installed in Firefox, you can forget about it. Whenever Charles starts it activates the Firefox plug-in, and when you quit Charles the Firefox plug-in is automatically deactivated. Sweet!

What about HTTPS?

The Charles documentation explains this issue better than I could. In short, Charles installs its own Root Certificate in the trusted certificate store on your machine so that it can act as a 'man in the middle' of HTTPS requests that your computer makes to particular websites.

To enable HTTPS man-in-the-middl-ing for a particular website, right-click on a host name in Charles' structure view and turn on SSL Proxying.

Getting Charles to intercept HTTP requests from the JVM running your Play Framework application

So far so good. If you type a URL into the address bar of your browser, a request is logged in Charles. If your Play Framework application fires off an HTTP redirect (302) request, which goes via your browser, a request is logged in Charles. If you use cURL or HTTPie or something similar to manually fire off an HTTP request, it is likewise logged in Charles.


if your Java code running inside Play Framework fires off an HTTP request using the Play Framework web services API (WS API), then you won't see that HTTP request in Charles unless you do some more configuration work.

You need to follow the instructions under 'JAVA APPLICATIONS' on the SSL Certificates page in the Charles documentation.

Download Charles Root Certificate

In Charles go to the Help menu and choose "SSL Proxying > Save Charles Root Certificate". Save the root certificate (as a .crt) to ~/Desktop as charles-ssl-proxying-certificate.crt.

Verify the location of the Java cacerts file

In a terminal window, run the following command:

find $JAVA_HOME -name cacerts

It will return something like this:


Install the Charles Root Certificate in Java's key store

sudo keytool -import -alias charles \
-file ~/Desktop/charles-ssl-proxying-certificate.crt \
-keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

Note that the default keystore password is 'changeit', so that's the storepass value you should use unless you've explicitly changed it sometime in the past.

Verify that the certificate was installed

keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts \
-storepass changeit | grep charles

Set the HTTP_PROXY environment variable

Now set the HTTP_PROXY environment variable, as explained under 'Proxy Setup' in the Play Framework installation instructions.

export HTTP_PROXY=

Run the activator

You can now run the activator as normal. All being well, you'll find that Java-initiated HTTP requests are logged in Charles.

Semantic versioning and micro-services

Semantic versioning is about assigning software version numbers that convey meaning about the extent of changes that have been made. Perhaps the most popular scheme is the one specified at A summary of the semver scheme is given in the introduction:

"Given a version number MAJOR.MINOR.PATCH, increment the:

    1. MAJOR version when you make incompatible API changes,
    2. MINOR version when you add functionality in a backwards-compatible manner, and
    3. PATCH version when you make backwards-compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format."

There have been some criticisms of semantic versioning; for example, the article, "Why Semantic Versioning Isn't", in which the author argues that there is no substitute for detailed release notes. Fair enough, but I think semantic versioning has value nevertheless.

I will make one observation from personal experience about the use of semantic versioning in the context of microservices.

Since the meaning of the term 'microservices' is not (yet) universally agreed, I'll be specific about my understanding of it, which comports with that provided by Martin Fowler:

" approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API." --

I believe that semantic versioning is even more helpful for development teams that use microservices because it does what the compiler cannot: provide a way to inform developers about potential incompatibilities between microservices that interact with each other.

Imagine an application that offers a platform for plug-ins, components that can be integrated with the core of the application at run-time. Suppose those plug-ins are to be deployed as microservices, all of them complying with a specification of the REST end-points that the plug-ins must provide:

REST API 1.0.0

GET /item          
Returns a list of items: { itemNo: string, name: string }

GET /item/{itemNo} 
Returns an item { itemNo: string, name: string }

POST /item?name={name} 
Creates a new item

Every plug-in that wants to be registered with the core must provide those end-points. The Core is released, along with two plug-ins: PlugInA and PlugInB.

Core 1.0.0      (compatible with API 1.0.0)
- PlugInA 1.0.0 (compatible with API 1.0.0)
- PlugInB 1.0.0 (compatible with API 1.0.0)

Note that there are version numbers assigned to the software components, and also to the API; everything is at 1.0.0. It's sunshine and lollipops all around.

Now suppose that the developers want to enhance PlugInA so that it uses a description of each item in addition to the item name. The developers make the necessary alterations to the REST API, specifying that the item descriptions are optional elements of each end-point.

REST API 1.1.0

GET /item          
Returns a list of items: { itemNo: string, name: string[, desc: string] }

GET /item/{itemNo} 
Returns an item { itemNo: string, name: string[, desc: string] }

POST /item?name={name}[&desc={desc}] 
Creates a new item

To indicate that the updated API is backwards-compatible with the original one, the developers assign it a version number that differs only in the MINOR part.

The developers now make changes to the Core and to PlugInA to support REST API 1.1.0. They assign the updated Core version 1.1.0, and they assign the updated PlugInA version 1.1.0 too. PlugInB is not updated at this point because there isn't time to work on it before the next big release.

Because of the semantics attached to the API version numbers, we can draw conclusions about which versions of the plug-ins work with which versions of the Core:

Core 1.0.0      (compatible with API 1.0.0)
- PlugInA 1.0.0 (compatible with API 1.0.0)
- PlugInB 1.0.0 (compatible with API 1.0.0)

Core 1.1.0      (compatible with API 1.0.0 and 1.1.0)
- PlugInA 1.0.0 (compatible with API 1.0.0)
- PlugInA 1.1.0 (compatible with API 1.0.0 and 1.1.0)
- PlugInB 1.0.0 (compatible with API 1.0.0)

Without the adherence to our semantic versioning scheme, the overall project could become very messy indeed, as more plug-ins are built, and their development cycles proceed independently of each other.

My recent experience on one such complex microservices-based project has proven semantic versioning to be essential. Throughout the project, the developers have maintained a wiki page containing a matrix of software component versions, mapped to REST API versions. We were pleased we did.