Category Archives: Java 9

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

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

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

Java 9: Why Modules?

What Are Modules?

The Java Module System, a.k.a. Project Jigsaw, is an effort to introduce a higher-level structural concept into Java. In a nutshell: Classes assemble into packages, and packages assemble into modules. Modules declare the other modules on which they depend, and in turn export packages for other modules to depend on.

Modules are a fundamental new concept going deep into the JDK, and have been under development for years. Jigsaw was originally planned for Java 7. As work began it became clear that this was a huge undertaking reaching deep into the internals of the JVM and the Java language itself. Yet, despite being slipped to Java 8 and then to Java 9, the need for it has only increased. Why do we need modules in Java? Why is Project Jigsaw such a big deal?

Why Modules?

Mark Reinhold, the Chief Architect of the Java Platform Group at Oracle, gave a keynote speech at Devoxx Belgium where he described the purpose of a module system and why it is so important.

There are many use cases that modules solve, but they all boil down to two primary pain points:

  1. Brittle, error-prone classpath (AKA JAR Hell)
  2. Monolithic JDK

Let’s look more at each of these.

Brittle Classpath

Have you ever seen a ClassNotFoundException? How about NoClassDefFoundError, NoSuchFieldError, or NoSuchMethodError? Maybe even a ClassCastException: “Cannot cast com.foo.Bar to com.foo.Bar”? All of these are the results of a brittle classpath. What that means is that ClassLoaders don’t have a good mechanism for distinguishing one loaded class from another class of the same name, or for isolating classes loaded by one ClassLoader from classes loaded by another.

From the Wikipedia entry on JAR Hell, problems from a brittle classpath arise from one of these situations:

  • Accidental presence of two different versions of a library installed on a system. This will not be considered an error by the system. Rather, the system will load classes from one or the other library. Adding the new library to the list of available libraries instead of replacing it may result in the application still behaving as though the old library is in use, which it may well be.
  • Multiple libraries or applications require different versions of library foo. If versions of library foo use the same class names, there is no way to load the versions of library foo with the same classloader.
  • The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single “flat” classloader, but instead may be composed of several (potentially very many) nested, cooperating classloaders. Classes loaded by different classloaders may interact in complex ways not fully comprehended by a developer, leading to errors or bugs that are difficult to analyze, explain, and resolve

In some cases, build tools may help you detect some of these situations (such as incompatible dependency graphs). But the fact remains that tools will not prevent you from doing dangerous things, and they do not protect you from all of the situations described above.

Java Modules will provide reliable configuration and strong encapsulation. If you have incompatibilities, you will discover these at build time instead of some indeterminate time after your application has started running in production.

Monolithic JDK

The JDK has been big for years. At this point in 2016, the JDK is too big to fit comfortably on small devices, and we would really like it to be easy to use embedded devices and other devices on the Internet of Things.

Now you might say “But I run my software on a large server, we are not constrained by space.” However, even on large servers we want to run lots of VMs and optimize memory use. If every instance you have requires an extra 200MB of memory that it doesn’t need, that adds up across hundreds of instances, and those resources are something you pay for every second of every day. Additionally, with a monolithic JDK startup performance is slower because of loading unnecessary things. We would like to measure our startup time in milliseconds, not thousands of milliseconds.

Java Modules will allow us to break up the JDK into modules so that we only use what we need. We will be able to deploy modular runtime images that take less space and that start up faster.

Conclusion

The changes for Java 9 to support modules are far reaching, and it will take some work because we will have new language features and syntax to learn. But I think this will be worth it to make Java applications stronger, faster, and more reliable. In a subsequent post we will look more at the details of how modules work and how we can start to incorporate them into our own software.

What do you think? Have you had the problems that Jigsaw is trying to solve? Or are these non-issues for you?

Leave a comment

Filed under Java 9

Java 9: Multi-Release JAR Files, Part II

In Part I on multi release JAR Files, we learned what it is and why it is useful. In this part we will learn how to actually construct such a JAR and test it out.

For this demonstration we will be using just the command line as opposed to Maven or Gradle. Tooling support for Java 9 is still ramping up 🙂

in a src folder, we have two classes

public class Application {
   public static void main(String[] args) throws IOException {
      Generator gen = new Generator();
      System.out.println("Generated strings: " + gen.createStrings());
   }
}

and

public class Generator {
   public Set<String> createStrings() {
      Set strings = new HashSet();
      strings.add("Java");
      strings.add("7");
      return strings;
   }
}

Then in another src folder we have another implementation of the class using Java 9 features:

public class Generator {
   public Set<String> createStrings() {
      return Set.of("Java", "9");
   }
}

Finally, we need to specify a file containing a new manifest attribute to indicate that the JAR is a multi-release JAR. The manifest needs to include:

Multi-Release: true

And now, to compile! From the command line:

javac -d build -release 7 src/*.java
javac -d build/META-INF/versions/9 --release 9 src9/*.java
jar --create --file mrjar.jar --manifest MANIFEST.MF --main-class=Application -C build .

There are a couple things going on here: We need to compile in multiple phases like this because we literally need to generate different versions of bytecode and put it in different places. Also note that we are compiling with the new -release argument instead of -source and -target. Refer to JEP-247 for more details, but essentially it guarantees the class to be compatible with a given version of the JVM in a way that -source and -target can’t.

Finally, if we set our path to use the appropriate JVM, when running on Java 9 we see

java -jar mrjar.jar
Generated strings: [Java, 9]

But running the same JAR on Java 7 we see

java -jar mrjar.jar
Generated strings: [Java, 7]

Proving that a different class was used for each version of Java that was running it!

Admittedly this is still a bit crude, with the non-standard file locations and dropping to the command line to do everything. We will build up to a Gradle example soon!

2 Comments

Filed under Java 9