Wednesday, November 2, 2016

Inside Java 9 – Part I

Two months back I took you for a dive into Java 9, looking at new language features and APIs. But there are lots of things I had to left out, so here comes a two-parter to fix that. In this first part we'll be looking at new version strings and command line syntax, multi-release JARs, improved logging, and much more.

JShell

In the first part we skipped Jigsaw because everybody's talking about it already. In this part we'll do the same with JShell, the brand-new REPL for Java. (I.e. a thing where you can type Java code and it immediately evaluates it.) If don't know (much) about it yet but would like to, watch this great introduction Robert Field gave last year at Devoxx Belgium (I think).

New Version Strings

To ease into this, let's start with something simple: version strings.

Or so I thought until I tried to understand Java's version naming schema. It started with JDKs 1.0 and 1.1 - so far so easy but things go downhill from there. Apparently, versions 1.2 to 1.5 were at some point rebranded as Java 2. (Remember J2SE? That's the 2 in there.) With JDK 1.5 it became clear that this didn't really work out so Sun started calling it Java 5. Sometime around Java 6 the whole idea of Java 2 was silently buried and ever since things cleared up a little - we simply say "Java X". (Did you know that all Java version up to and including Java 7 had cool project names like Tiger and Mustang?)

The version strings reported by the JVM were untouched though - they always reported 1.x.... Now, with JEP 223, version strings and the naming schema align. If you check the relevant system properties (see the demo), this is the output you will get:

java.version: 9-ea
java.runtime.version: 9-ea+138-jigsaw-nightly-h5561-20161003
java.vm.version: 9-ea+138-jigsaw-nightly-h5561-20161003
java.specification.version: 9
java.vm.specification.version: 9

This is not overly informative because it's run on an early access build. In the future java.version will report strings like 9.1.2, which follow the schema $MAJOR.$MINOR.$SECURITY:

  • $MAJOR marks the major version Oracle is planning to release every two to three years.
  • $MINOR marks the smaller releases for bug fixes and other details that follow regularly in between - it resets to zero when a new major version is released.
  • $SECURITY is really interesting - it gets bumped with every release that "contains critical fixes including those necessary to improve security" and is not reset when $MINOR increases.

To make parsing that string unnecessary we get Version, a nice little class that does it for us.

Version version = Runtime.version();
System.out.println("Reported by runtime: " + version);
switch (version.major()) {
    case 9:
        System.out.println("Modularity!");
        break;
    case 10:
        System.out.println("Value Types!");
        break;
}

GNU-style Command Line Options

Java's tools have a lot of idiosyncrasies when it comes to the syntax of their command line options:

  • some use a single dash for long versions (-classpath), others use two (--gzip)
  • some separate words with dashes (--no-gzip), others don't (again -classpath)
  • some have single letter forms (-d), others two (-cp, seriously what's wrong with that option?!)
  • some assign values with the equals sign (-D<name>=<value>), others require a space (I won't even...)

On Linux and other GNU-based systems, by contrast, pretty much all tools use the same syntax for their options:

  • two dashes for long versions
  • words are separated by dashes
  • abbreviations consist of a single letter

In a recklessly courageous move Java 9 changes all command line options to match these rules, thus breaking all scripts! Nah, just kidding... 😎 But JEP 293 established a guideline mirroring and adapting those rules and new options are expected to follow it. Old options might at some point be migrated towards the cleaner syntax but that's not part of Java 9. The JEP contains a lot of details and examples - give it a read.

A Mixed Bag Of Extensions And Updates

Java 9 ships with a lot of JEPs that extend or update existing functionality. Here they are, somewhat ordered by topic, some summarized, some in more detail.

Unicode

While Java itself can be written in UTF-16 (yes, your code can sport emojis), property files used to be limited to ISO-8859-1. Let's say you have a config.properties file like this one:

money = € / \u20AC

Then accessing this file with Java 8 yields:

money = â▯¬ / €

With JEP 226 those times are finally over and no more Unicode escapes are required. Running the same access code on Java 9 shows what we expected:

money = € / €

(The full example even has a 😎 but our code highlighter doesn't play well with that.)

Note that there are several ways to access property files and only the one via PropertyResourceBundle got updated. How exactly the encoding is determined and how that can be configured is documented in the API note of the JavaDoc. The defaults are sensible, though, and make the API "just work" for common cases:

try (InputStream propertyFile = new FileInputStream("config.properties")) {
    PropertyResourceBundle properties = new PropertyResourceBundle(propertyFile);
    properties.getKeys().asIterator().forEachRemaining(key -> {
        String value = properties.getString(key);
        System.out.println(key + " = " + value);
    });
} catch (IOException e) {
    e.printStackTrace();
}

You will find this code and a comparison to the Properties API in the demo. If you try to run it on Java 8 for comparison, you will find a nifty little API change Java 9 made for those poor developers who are still using the ancient Enumeration.

In other Unicode-related news, Java 9 supports Unicode 8.0. Yay! (JEP 227, JEP 267)

Graphics

TIFF images are now supported by the Image I/O Framework (in javax.imageio). The Java Advanced Imaging (JAI) project implemented readers and writers for the format, which are now standardized and moved into javax.imageio.plugins.tiff. (JEP 262)

Retina-style HiDPI screens pose unique challenges for desktop UIs. Java already dealt with them on Mac and now follows suit on Linux and Windows. With this "windows and GUI components should have an appropriate size based on the platform recommendations, text should remain crisp despite any default scaling indicated by the HiDPI settings, and icons and images should be smooth and preferably have details appropriate for the pixel density of the display." (JEP 263)

On Linux the Java desktop triumvirate (AWT, Swing, and JavaFX) can now use GTK 3. For the time being, the JVM will default to GTK 2 and only use GTK3 if indicated by the new system property jdk.gtk.version or "GTK 3 is required for interoperability, and this requirement can be detected sufficiently early". (JEP 283)

JavaFX used an outdated GStreamer version, which is updated to 1.4.4. This should improve stability and performance of replaying media with JavaFX. (JEP 257)

HarfBuzz is the new OpenType layout engine and displaces ICU, which is discontinued. (JEP 258)

Security

The SHA-3 hash algorithms SHA3-224, SHA3-256, SHA3-384, and SHA3-512 were implemented. They can be used via the MessageDigest API. (JEP 287)

When using SecureRandom (on any Java version) you either get a native implementation based on your operating system or a pure Java version. The latter "uses an older SHA1-based RNG implementation, which is not as strong as the algorithms used by approved DRBG [Deterministic Random Bit Generator] mechanisms." Since older but especially embedded systems rely on the Java variant, its security was boosted by implementing the DRBG mechanisms described in NIST 800-90Ar1. Alongside that SecureRandom's API was improved to allow passing parameters to DRGB and future algorithms (JEP 273):

Instantiation instantiation = DrbgParameters.instantiation(128, RESEED_ONLY, null);
SecureRandom random = SecureRandom.getInstance("DRBG", instantiation);

byte[] bytes = new byte[20];
random.nextBytes(bytes);

[caption id="attachment_142693" align="aligncenter" width="1024"]Published by Ali Bindawood under CC-BY-ND 2.0 Published by Ali Bindawood under CC-BY-ND 2.0[/caption]

New Java Virtual Machine Features

The machince doing all the work for us - I wonder, will rise up one day? It got some love in this release in the form of a couple of new features, so maybe we calmed it. If not, I, for one, welcome our new ~~insect~~ machine overlords.

Continue reading %Inside Java 9 – Part I%


by Nicolai Parlog via SitePoint

No comments:

Post a Comment