Java 9: Why Is There A New HTTP Client?

Regarding JEP 110: HTTP/2 Client one might reasonably ask the question: “Why is Java 9 introducing a new HTTP client when there are so many high-quality and time-tested libraries out there?”

There are several answers:

  1. The first is provided by the the JEP itself: “A number of existing HTTP client APIs and implementations exist, e.g., Jetty and the Apache HttpClient. Both of these are both rather heavy-weight in terms of the numbers of packages and classes, and they don’t take advantage of newer language features such as lambda expressions.”
  2. Another reason is that with a built-in http client, we can easily use it in the new REPL (thanks Java 9!) without needing to bring in another library.
  3. Finally, this way the Java platform is free to use a high quality http client for other Java platform features without needing a dependency on an external third-party library.

This question and the thoughtful answer #3 have been brought to you by The Audience from my talk on Java 9 with the Philly Java Users Group. Thanks Philly JUG!

Advertisements

Leave a comment

Filed under Java 9

Philly JUG Introduction to Java 9

Recently I had the pleasure of doing a presentation for the Philly Java Users Group about the exciting new features coming to Java 9.

We covered what I considered to be the highest-priority items that would have the broadest interest:

  • Module System
  • REPL
  • Multi-Release JARS
  • Milling Project Coin
  • Process API
  • HttpClient API

For those who missed the talk (or who just want to go back and review) the slides are available online and contain links to original Java 9 documentation, blog posts and github code covering much of the presentation content.

Thanks to all of the Philly JUG members who came to the talk on Java 9, and I look forward to seeing you at many JUG meetings to come!

1 Comment

Filed under Java 9

Java 9: Milling Project Coin

One of Java 9’s new language features is JEP-213: Milling Project Coin. According to the JEP description: “The small language changes included in Project Coin / JSR 334 as part of JDK 7 / Java SE 7 have been easy to use and have worked well in practice. However, a few amendments could address the rough edges of those changes.”

Milling Project Coin incorporates 5 language changes:

  • Allow @SafeVargs on private instance methods
  • Allow effectively-final variables to be used as resources in the try-with-resources statement
  • Allow diamond with anonymous classes if the argument type of the inferred type is denotable
  • Complete the removal, begun in Java SE 8, of underscore from the set of legal identifier names
  • Support for private methods in interfaces, thereby enabling non abstract methods of an interface to share code between them

They say a picture is worth a thousand words. I say a code example is worth a thousand words of explanation. We can actually use all of these language features at the same time in a relatively small piece of code, so let’s take a look!

public class Main {

	public static void main(String[] args) throws Exception {

		// Allow effectively-final variables to be used as resources in the try-with-resources statement
		Reader reader = new InputStreamReader(new FileInputStream("Main.java"));
		BufferedReader in = new BufferedReader(reader);
		try(in) {
			String line;
			while ((line = in.readLine()) != null) {
				System.out.println(line);
			}
		}
	}

	interface ListProcessor {

		default List<String> uniquelyFlatten(List<String>... lists) {
			return flattenStrings(lists);
		}

		// Allow @SafeVargs on private instance methods
		// Support for private methods in interfaces, thereby enabling non abstract methods of an interface to share code between them
		@SafeVarargs
		private List<String> flattenStrings(List<String>... lists) {

			// Allow diamond with anonymous classes if the argument type of the inferred type is denotable
			// Complete the removal, begun in Java SE 8, of underscore from the set of legal identifier names
			Set<String> _strings = new HashSet<>(){};
			for(List<String> list : lists) {
				_strings.addAll(list);
			}
			return new ArrayList<>(_strings);
		}

	}
}

My favorite of these is diamond operator for anonymous classes, as this has caught me before. What’s your favorite new language feature in Milling Project Coin?

Leave a comment

Filed under Java 9

Database Migrations For Zero Downtime Deployments

One of the biggest challenges with blue-green deployments is migrating the database. While it’s easy to run two different versions of your software at the same time, you can only run one database (i.e. schema) at a time. For example, if you change a table to use a different column name, and then try to run both versions of your software at the same time (as you’d want to with a blue-green deployment) then the old software will break because it doesn’t know about the new column name.

This situation presents a large but not insurmountable challenge. We can resolve this challenge by following some basic principles.

Basic Principles

  • The most basic principle is that each version N of the software MUST work with both version N and version N+1 of the database.
  • Version N and version N+1 of the software must both be able to safely run at the same time on version N+1 of the database.
  • Additionally, migrating the database and migrating the code are independent. The database usually migrates first because version N+1 of the software is not required to work with version N of the database.

This diagram illustrates the directions in which compatibility must be maintained between the code and the database.

screen-shot-2016-09-30-at-8-34-12-am

The consequence of these conditions is that we can do any database refactoring that we like with zero downtime, the refactorings just need to be broken down into smaller refactorings and spread across multiple deployments. Also the individual refactorings don’t need to be in consecutive deployments, they can be spread across more deployments as long as they are done in order.

One complication is that this approach becomes very difficult if your releases are very far apart. Imagine a release schedule of once every three months, and imagine a database refactoring spread over three releases… It becomes increasingly likely that things will get forgotten or de-prioritized, and you will end up with a lot of half-finished database refactorings in your system.

The closer together your refactorings are in time, they easier they are to manage. In fact, if you are practicing continuous deployment, the database cleanup steps in subsequent deployments can happen almost immediately after the release once you are confident with the release and the old code has been retired. Blue Green deployment operates in a feedback loop: it enables you to do smaller and more frequent deployments, and it works much better and is much easier if you do smaller and more frequent deployments.

In the table below we see some sample refactorings and how they can be reduced to a set of compatible changes. Note that each column represents changes you would make for an individual release N, and the refactorings (rows) are split by database change and software change. Imagine overlaying the diagram above onto the table below and seeing in which directions compatibility needs to be maintained. Finally, sets of database changes for a single release should be done in a single transaction of course and the changes should be atomic.

screen-shot-2016-09-30-at-8-32-16-am

Testing

This should always be tested against production-scale data and while the database is in use in a perf environment. You can see how long the schema migration takes, the performance impact of the migration to a system under load, and find solutions to these impacts if necessary.

Conclusion

We’ve outlined here just one technical component of zero downtime deployments. There are many other important non-technical components of zero downtime deployments, including considering the culture of your organization, the maturity of your devops practice, and the release cadence expected by customers or mandated by your industry. There are even other possible technical components such as how to migrate non-database data stores, collaborating service migration, and code that depends on data not on schema.

However, with the basic principles above, I am confident that one of the more difficult components of zero downtime deployment (database migrations) can be solved, and that the other components that apply to your own situation can similarly be solved if you are willing to do the work.

Happy deploying!

Leave a comment

Filed under Software Engineering

Java 9: JShell, a Read-Eval-Print Loop (REPL)

What’s a REPL?

A Read-Evaluate-Print-Loop, or, REPL, is a command line interface for interacting with a programming language. In the words of JEP 222, the new Java REPL (JShell) is to “provide an interactive tool to evaluate expressions of the Java programming language, together with an API so that other applications can leverage this functionality.”

Why Does Java Need This?

According to JEP 222: JShell, “The number one reason schools cite for moving away from Java as a teaching language is that other languages have a ‘REPL’ and have far lower bars to an initial ‘Hello, world!’ program.” If we want Java to have a bright future (and don’t we all?) then Java has to compete with other languages (Scala, Groovy, Clojure, Python, Ruby, Haskell…) in academia that have REPL’s and a low barrier to entry.

The REPL is a good feature for students, but what about professional developers? Ask a professional Scala developer, and it becomes clear that the REPL is an iterative development tool with even faster feedback than TDD. Additionally it lets us experiment with third-party libraries with less ceremony than setting up a new project. Finally, it allows us to execute arbitrary Java code from the command line, bringing Java much closer in usability to a scripting language. So at a professional level, the REPL aims to make us more productive in a very direct way.

What Features Does It Have?

JShell maintains history, has a built-in editor, has tab-completion, saves and loads code, and has automatic addition of semicolons. It has forward references (except in method signatures) so we can reference a variable or method before it’s defined. To see everything it can do, call jshell -help from the command line, or /help from within jshell.

How Else Can I Use It?

JShell is pretty flexible and has an API, so people are likely to come up with creative uses for it.

People may use it like a Java oriented shell for doing regular work like we do with the bash shell right now. I can imagine Java moving at least partially into the scripting space, so people have another language at their disposal to work from the command line with files and data, connect to servers or databases, retrieve and manipulate data, etc.

The fact that JShell includes an API means we are likely to see this included with IDE’s, providing a Java “scratch pad” for our daily work. The API also means it could potentially integrate with build tools and increase the flexibility of build scripts.

Personally I would like to see a Github Gist browser and downloader so it’s easy to experiment with other people’s ideas!

Example: Try A Library

We can load jars or classes to try them out in JShell, just specify a jar file when calling jshell –class-path from the command line, or call /classpath from within the shell.

To try out a library like Google Guava, call this from the command line:

wget http://central.maven.org/maven2/com/google/guava/guava/19.0/guava-19.0.jar
jshell --class-path guava-19.0.jar 

then inside jshell, we can type in some code like this:

import com.google.common.base.Optional;
Optional b =  Optional.of(new Integer(10));
b.get()

// java 8's Optional has .ofNullable()
Optional a = Optional.fromNullable(null);
a.or(5);

Example: Pretend Java Is A Scripting Language

I think .jsh makes a good file extension for Java snippets intended for use with JShell. Let’s put this in a file called hello.jsh:

System.out.println("hello world!")
/exit

Then from the command line

jshell hello.jsh

Yay, a compiled language that runs like a script!

Example: Load Code At Startup

What if we wanted Linux bash shell-like capabilities inside JShell? We could write code to accomplish that capability, and have that code loaded at startup time.

Let’s put this code in a file called bash.jsh

// a startup file completely replaces the default
// so need to bring in the default imports yourself

import java.util.*
import java.io.*
import java.math.*
import java.net.*
import java.util.concurrent.*
import java.util.prefs.*
import java.util.regex.*

void ls() {
  File cur = new File(".");
  for(String s : cur.list())
    System.out.println(s);
}

Then from the command line:

jshell --startup bash.jsh

Now when we type “ls()” from within jshell we get the file listing of the current directory. It would probably be a bit of work, but in theory we could replicate a complete shell environment. But, you know, we already have a shell. 🙂 What we will see in practice is more likely to be freely available snippets for working with data and code at a higher level.

Conclusion

JShell has a lot of potential to change the way we learn and use Java. I have high hopes for its expanded use in Java 9!

How will you use JShell?

Leave a comment

Filed under Java 9

The Business Case For Zero Downtime Deployments

This post describes the business advantages of zero-downtime, (a.k.a. blue-green) deployments. If you are not familiar with blue-green deployments, you can read the excellent Martin Fowler article about blue-green deployments. But in a nutshell this amounts to the idea of releasing to production by deploying a release to a separate production environment and behind the scenes gradually redirecting user activity to the new environment from the old one.

Why Do I Want This?

  • Eliminate downtime: Done correctly, your users will literally see zero downtime. Many organizations do deployments at midnight local time so that they can takenthe entire service offline “when nobody’s using it.” But if your software is successful in a global environment (or if your target demographic’s usage time is split between midnight and mid-day), there is no time when “nobody’s using it” and the best time for one group of users may be the worst time for another.
  • Increase support: Production deployment is potentially the single most dangerous activity your team does. Instead of midnight deployments when everybody is exhausted or asleep, deploy during business hours when the entire team is available and alert.
  • Reduce risk: allows easy and safe rollback, if something unexpected happens with your release, you can immediately and safely roll back to the last version by simply directing user traffic back to the previous environment
  • Provide for staging: when the new environment is active, the previous environment becomes the staging environment for the next deployment. If you didn’t have a staging environment, you should probably have one anyway.
  • Hot backup for disaster recovery: after deploying and we’re satisfied that it is stable, we can deploy the new release to the previous environment too. This gives us a hot backup in case of disaster.

What’s The Catch?

Zero-downtime deployment isn’t free: it requires a certain diligence and maturity of process and devops, but not any more than you really need to play with the big kids in the world of software engineering anyway. Details at the engineering level to follow in a future post!

Conclusion

The benefits of this kind of deployment are actually huge. If you can deploy with zero downtime once per month, why not once per sprint? Why not every day? Why not as you finish features and fix bugs so that your customers see their bug fixes and feature requests in a fraction of the time?

If you can do deployments this way, your users with thank you. And your boss will thank you. 🙂

Leave a comment

Filed under Software Engineering

Java 9: The New HttpClient

With JEP-110: HTTP/2 Client, Java 9 will “Define a new HTTP client API that implements HTTP/2 and WebSocket, and can replace the legacy HttpURLConnection API.”

The Problem

Java’s existing HttpURLConnection has some problems. It is hard to use, in part from being abstracted to work with multiple protocols (like FTP and Gopher). It turns out 20 years later that HTTP was the big winner in protocol land. But the biggest problem is that HttpURLConnection works only in blocking mode so there is only one thread per request/response.

There are other HTTP clients out there that solve some of these problems, such as Jetty and the Apache HttpClient. Jetty even has a non-blocking mode. However, both of these are sizable libraries to bring in, and neither take advantage of lambdas.

The Solution

Introducing: Java 9’s HttpClient!

The new API works with HTTP/2, deals with multiple responses (server push), can stream the request and/or response bodies, and can work with synchronous or asynchronous requests or responses. So there is a lot of flexibility to taylor the behavior of your client to the problem you’re trying to solve. If that was not enough, the API makes it very easy to work with your request and response bodies as strings, bytes, input streams, even directly as files.

The HttpRequest Javadocs are thorough and provide a number of examples demonstrating various use cases. After reading the Javadocs, you’ll find that you’ll really understand the API more fully when you try to use it yourself. The rest of this post will explore a specific use case that I wanted to accomplish as I learned the API myself.

An Example: Stream It

I had in mind a specific problem: What if I wanted to download a very large document in a response body that I didn’t want to save to disk, but instead wanted to parse as it was downloading? One could make the argument that downloading to a file and processing after the download is a better separation of concerns, and that it allows you to retry the download or retry the processing if something goes wrong in either step. But for sake of argument let’s say the response body is unreasonably huge, the client is on a device with limited space, etc.

To get started, we can obtain an HttpClient with the builder from HttpClient.create() which provides a fluent API for creating a client. If you are ok with the defaults you can get started a little more quickly with the HttpRequest.Builder obtained from HttpRequest.create(), which is what happens in the code below.

The important things to learn from this example are that:

  1. The possible arguments to HttpRequest.Builder.body() allow for reading the request body from a file or or other source. Using RequestBuilder.body(fromInputStream(…)) allows you to stream the request body.
  2. The corresponding .body() and .bodyAsync() of the HttpResponse allow us to optionally stream the response body, again into a String, file, etc
  3. The HttpRequest’s .response() and .responseAsync() allow us to optionally block on the response itself

The code shows this in action with a blocking non-streaming request and a non-blocking streaming response (although we can choose to block with .join()).

import java.io.*;
import java.net.http.*;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;

import static java.net.http.HttpRequest.*;
import static java.net.http.HttpResponse.*;

public class Main {

   public static void main(String[] args) throws Exception {

      requestStreaming("http://stackoverflow.com");

      System.out.println("Program done.");
      System.exit(0);
   }

   public static void requestStreaming(String url) throws Exception {

      HttpRequest request = HttpRequest.create(new URI(url))
                                       .body(noBody())
                                       .GET();

      request.response()
             .bodyAsync(HttpResponse.asInputStream())
             .thenAccept( s -> readBody(s))
             .join();
   }

   public static void readBody(InputStream stream) {

      try(BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"))) {
         String line = br.readLine();
         while(line != null) {
            processLine(line);
            line = br.readLine();
         }
      }
      catch(Exception e) {
         e.printStackTrace();
      }
      System.out.println("Stream processing Done!");
   }

   public static void processLine(String line) throws Exception {
      System.out.print(".");
   }
}

Conclusion

Java 9’s new HttpClient provides a lot of flexibility and incorporates the latest language features. I expect we will see lots of creative uses!

Leave a comment

Filed under Java 9