Category Archives: Java

Implementing Basic REST APIs with JAX-RS

This is a guest article promoted by PACKT, the publisher I work with to get my books to the readers.

Learn how to implement basic REST APIs with JAX-RS in this article by Mario-Leander Reimer, a chief technologist for QAware GmbH and a senior Java developer and architect with several years of experience in designing complex and large-scale distributed system architectures.

This article will take a look at how to implement a REST resource using basic JAX-RS annotations. You’ll implement a REST API to get a list of books so that you’ll be able to create new books, get a book by ISBN, update books, and delete a book. The complete code for this book is also available at https://github.com/PacktPublishing/Building-RESTful-Web-Services-with-Java-EE-8.

Conceptual view of this section

You’ll create a basic project skeleton and prepare a simple class called BookResource and use this to implement the CRUD REST API for your books. First, you need to annotate your class using proper annotations. Use the @Path annotation to specify the path for your books API, which is "books" and make a @RequestScoped CDI bean.

Now, to implement your business logic, you can use another CDI bean. So, you need to get it injected into this one. This other CDI bean is called bookshelf, and you’ll use the CDI @Inject annotation to get a reference to your bookshelf. Next, implement a method to get hold of a list of all books.

What you see here is that you have a books() method, which is @GET annotated, and it produces MediaType.APPLICATION_JSON and returns a JAX-RS response. You can see that you construct a response of ok, which is HTTP 200; use bookshelf.findAll() as the body, which is a collection of books and then build the response. The BookResource.java file should look as follows:

@Path("books")
@RequestScoped
public class BookResource {

@Inject
private Bookshelf bookshelf;

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response books() {
return Response.ok(bookshelf.findAll()).build();
}

Next, implement a GET message to get a specific book. To do this, you have a @GET annotated method, but this time you have the @Path annotation with the "/{isbn}" parameter. To get hold of the parameter called isbn, use the @PathParam annotation to pass the value. Use bookshelf to find your book by ISBN and return the book found using the HTTP status code 200 that is, ok:

@GET
@Path("/{isbn}")
public Response get(@PathParam("isbn") String isbn) {
Book book = bookshelf.findByISBN(isbn);
return Response.ok(book).build();
}

In order to create something, it’s a convention to use HTTP POST as a method. You consume the application JSON and expect the JSON structure of a book. You call bookshelf.create with the book parameter and then use UriBuilder to construct the URI for the just-created book; this is also a convention. Return this URI using Response.created, which matches the HTTP status code 201, and call build() to build the final response:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(Book book) {
if (bookshelf.exists(book.getIsbn())) {
return Response.status(Response.Status.CONFLICT).build();
}

bookshelf.create(book);
URI location = UriBuilder.fromResource(BookResource.class)
.path("/{isbn}")
.resolveTemplate("isbn", book.getIsbn())
.build();
return Response.created(location).build();
}

You can implement the update method for an existing book. Again it’s a convention to use the HTTP method PUT. Update this by putting in a specific location. Use the @Path parameter with a value of "/{isbn}". Give a reference to this isbn here in the update() method parameter, and you have the JSON structure of your book ready. Use bookshelf.update to update the book and in the end, return the status code ok:

@PUT
@Path("/{isbn}")
public Response update(@PathParam("isbn") String isbn, Book book) {
bookshelf.update(isbn, book);
return Response.ok().build();
}

Finally, implement the delete message and use the HTTP method DELETE on the path of an identified ISBN. Using the @PathParam annotation here, call bookshelf.delete() and return ok if everything went well:

@DELETE
@Path("/{isbn}")
public Response delete(@PathParam("isbn") String isbn) {
bookshelf.delete(isbn);
return Response.ok().build();
}

This is the CRUD implementation for your book resource. Use a Docker container and the Payara Server micro edition to run everything. Copy your WAR file to the deployments directory and then you’re up and running:

FROM payara/micro:5-SNAPSHOT

COPY target/library-service.war /opt/payara/deployments

See if everything’s running on your REST client (Postman). First, get a list of books. As you can see here, this works as expected:

If you want to create a new book, issue the POST and create new book request, and you’ll see a status code of OK 200. Get the new book using GET new book; this is the book you just created, as shown in the following screenshot:

Update the book using Update new book, and you’ll get a status code of OK 200. You can get the updated book using GE new bookT. Get the updated title, as shown in the following screenshot:

Finally, you can delete the book. When you get the list of books, your newly created book is not a part of it anymore.

If you found this article interesting, you can explore Building RESTful Web Services with Java EE 8 to learn the fundamentals of Java EE 8 APIs to build effective web services. Building RESTful Web Services with Java EE 8 also guides you in leveraging the power of asynchronous APIs on the server and client side, and you will learn to use server-sent events (SSEs) for push communication.

 

Advertisements

Comparing Golang and Understanding Value Types BaselOne

Comparing Golang and Understanding Value Types BaselOne Video

I was invited again to deliver my talk comparing Go language with Java and to talk a bit about value types. This time it was in Basel at the BaselOne conference. This one day conference happens once a year in Basel at the MarkHalle. This is a kind of shopping mall close to the railway station. The place is not too posh so you will not feel uncomfortable walking around in the typical developer outfits. At the same time, there are a lot of food places and the conference organizers provided coupons valid for some food. There were three rooms for parallel talks. One of the rooms is actually a café and you can really buy coffee before the talk and later listen to the talk while sipping your mocha. The audience was composed mainly of local developers from within Switzerland. The organization of the conference is very much related to the Swiss Java Users’ Group. There was no official video recording of the conference but organizers welcomed my recording and gave me permission to publish the video, so here it goes.

I have edited the video I recorded during the conference where I presented Comparing Golang and Understanding Value Types. The video shows the slides and, just for the sake of completeness and to increase the enjoyment factor, my slender myself presenting in PIP.

I delivered the talk also in May in Vilnius and before that April, the same year in Mainz at W-JAX. Both of those times the talk was disturbed some external noise. This time we had nothing like that. I almost started to miss it. (not really)

Now that JAX also published the video

https://vimeo.com/jaxtv/review/288743607/ce57328338

You can compare the three, how different the same talk can be. (Seriously, I do not think it is interesting for anyone.) Here is the Vilnius conference video:

JEP 181 incompatibility, nesting classes / 2

JEP 181 is a nest based access control https://openjdk.java.net/jeps/181. It was introduced in Java 11 and it deliberately introduced an incompatibility with previous versions. This is a good example that being compatible with prior versions of Java is not a rule carved into stone but it rather is to keep the consistency and steady development of the language. In this article, I will look at the change through an example that I came across a few years ago and how Java 11 makes life easier and more consistent in this special case.

Java backward compatibility is limited to features and not to behavior

Original Situation

A few years ago when I wrote the ScriptBasic for Java interpreter that can be extended with Java methods, so that they are available just as if they were written in BASIC I created some unit tests. The unit test class contained some inner class that had some method in it available for the BASIC code. The inner class was static and private as it had nothing to do with any other classes except the test, however, the class and the methods were still accessible to the test code because they resided in the same class. To my dismay, the methods were not accessible via the BASIC programs. When I tried to call the methods through the BASIC interpreter, which itself was using reflective access I got IllegalAccessException.

To rectify the situation I created the following simple code after a few hours of debugging and learning:

package javax0;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflThrow {
    private class Nested {
        private void m(){
            System.out.println("m called");
        }
    }
    public static void main(String[] args)
            throws NoSuchMethodException,
            InvocationTargetException,
            IllegalAccessException {
        ReflThrow me = new ReflThrow();
        Nested n = me.new Nested();
        n.m();
        Method m = Nested.class.getDeclaredMethod("m");
        m.invoke(n);
    }
}

If you run this code with Java N where N < 11 then you get something similar to this:

m called
Exception in thread "main" java.lang.IllegalAccessException: class ReflThrow cannot access a member of class ReflThrow$Nested with modifiers "private"
    at java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:423)
    at java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:414)
...

It works, however, fine using Java 11 (and presumably it will also work fine with later versions of Java).

Explanation

Up to version 11 of Java the JVM did not handle inner and nested classes. All classes in the JVM are top-level classes. The Java compiler creates a specially named top-level class from the inner and nested classes. For example one of the Java compilers may create the class files ReflThrow.class and ReflThrow$Nested.class. Because they are top level classes for the JVM the code in the class ReflThrow cannot invoke the private method m() of Nested when they are two different top-level classes.

On the Java level, however, when these classes are created from a nested structure it is possible. To make it happen the compiler creates an extra synthetic method inside the class Nested that the code in ReflThrow can call and this method already inside Nested calls m().

The synthetic methods have the modifier SYNTHETIC so that the compiler later knows that other code should not “see” those methods. That way invoking the method m() works nicely.
On the other hand, when we try to call the method m() using its name and reflective access the route goes directly through the class boundaries without invoking any synthetic method, and because the method is private to the class it is in, the invocation throws the exception.

Java 11 changes this. The JEP 181 incorporated into the already released Java 11 introduces the notion nest. “Nests allow classes that are logically part of the same code entity, but which are compiled to distinct class files, to access each other’s private members without the need for compilers to insert accessibility-broadening bridge methods.” It simply means that there are classes which are nests and there are classes which belong to a nest. When the code is generated from Java then the top level class is the nesting class and the classes inside are nested. This structure on the JVM level leaves a lot of room for different language structures and does not put an octroi of a Java structure on the execution environment. The JVM is aimed to be polyglot and it is going to be even “more” polyglot with the introduction of the GraalVM in the future. The JVM using this structure simply sees that two classes are in the same nest, thus they can access each other private methods, fields and other members. This also means that there are no bridge methods with different access restrictions and that way reflection goes through exactly the same access boundaries as the normal Java call.

Summary / Takeaway

Java does not change overnight and is mostly backward compatible. Backward compatibility is, however, limited to features and not to behavior. The JEP181 did not, and it never actually intended to reproduce the not absolutely perfect IllegalAccessException throwing behavior of the reflective access to nested classes. This behavior was rather an implementation behavior/bug rather than a language feature and was in Java 11 fixed.

Format the code

PACKT recently published the book Mastering Java 9 that I co-authored. The author who started to write the book could not finish, and PACKT had to find people who agreed to write some of the chapters. I previously successfully finished Programming Java 9 by Example and PACKT asked me if I could help. Finally, we wrote the book with Dr. Edward Lavieri.

To my surprise, he used C# bracket placing in the book. That is, the { character is placed not on the end of the line but rather at the start of the next line.

if( myCondition )
{
  do something;
}

This is against the usual Java coding convention.

When I started programming C in 1984 I started to use this bracket placement. That time Internet was not reachable and there were no tools to share opinions in such a wide audience like now. It was also not clear how much formatting means when we are coding. What is more, it was not even clear how much readability is important.

Later I learned that the convention in case of C programming usually is to put the { character at the end of the line.

if( myCondition ){
  do something;
  }

In case of C, it is not always the case. Some programmer teams use the first bracket placement, while others use the later.

In case of Java, the C# style bracket placement is almost extinct. Perhaps it would be interesting to see a statistics over the sources available on GitHub to see how big percent of the Java code uses this or that.

Why is it interesting? Because

You should not use C# formatting when you program Java code!

There are exceptions as always. For example, the company you work for insists on the other coding style. In that case, the company made the bad decision and although it may be okay or even great working for this company, this is certainly a company smell. (See code smell.)

Why should not you use the other style?

Because of readability. Readability is subjective and still, in this case, I dare say that the Java style bracket placement is more readable. Hold your horses before ranting, I will explain.

Что было раньше, курица или яйцо?

For most of you, the above sentence is not readable. I can read it because I grew up in eastern Europe where learning Russian was mandatory. It is also readable for most of the Russian people. They can not only read it, but they can even understand it. For them, it is just as readable as the English sentence

What was sooner, the chicken or the egg?

for us.

Readablility depends on what we got used to. Java programmers got used to

                      {
  }

bracket placement. C# programmers use the other style. If we see a code that is formatted differently you may oversee some aspect of the code that you would not skip otherwise. The difference is subtle but still it is there. When you hire Java developers you are more likely to find good Java developers for a reasonable price who use and who are accustomed to the industry standard than one who is accustomed to the C# style.

You can find here and there some who are also fluent in C# as well and can read Cyrillic… ops… C# “characters” but it is less common than pure Java developers.

The bottom line is that the TCO of the code will be lower during the lifetime of code development and maintenance if you follow the industry standards. It is that simple.

P.S.: Buy the books!

New Regex Features in Java 9

I recently received my complimentary copy of the book “Java 9 Regular Expressions” from Anubhava Srivastava published by Packt. The book is a good tutorial and introduction to anyone who wants to learn what regular expressions are and start from scratch. Those who know how to use regex the book may still be interesting to reiterate the knowledge and to deepen into a more complex feature like zero-length assertions, backreferences, and alike.

In this article, I will focus on the regular expression features that are specific to Java 9 and were not available in earlier version of the JDK. There is not many, though.

Java 9 Regular Expression Module

The JDK in Java 9 is split up into modules. One could rightfully expect that there is a new module for the regular expression handling packages and classes. Actually, there is none. The module java.base is the default module on which all other modules depend on by default and thus the classes of the exported packages are always available in Java applications. The regular expression package java.util.regex is exported by this module. This makes the development a bit simpler: there is no need to explicitly ‘require’ a module if we want to use regular expressions in our code. It seems that regular expressions are so essential to Java that it got included in the base module.

Regular Expression Classes

The package java.util.regex contains the classes

  • MatchResult
  • Matcher
  • Pattern and
  • PatternSyntaxException

The only class that has changed API is Matcher.

Changes in class Matcher

The class Matcher adds five new methods. Four of those are overloaded versions of already existing methods. These are:

  • appendReplacement
  • appendTail
  • replaceAll
  • replaceFirst
  • results

The first four exists in earlier versions and there is only change in the types of the arguments (after all that is what overloading means).

appendReplacement/Tail

In case of appendReplacement and appendTail the only difference is that the argument can also be a StringBuilder and not only StringBuffer. Considering that StringBuilder introduced in Java 1.5 something like 13 years ago nobody should say that this is an inconsiderate act.

It is interesting though how the currently online version of the API JDK documents the behaviour of appendReplacement for StringBuilder argument. The older, StringBuffer argumented method explicitly documents that the replacement string may contain named references that will be replaced by the corresponding group. The StringBuilder argumented version misses this. The documentation seems like copy/paste and then edited. The text replaces “buffer” to “builder” and alike and the text documenting the named reference feature is deleted.

I tried the functionality using Java 9 build160 and the outcome is the same for these two method versions. This should not be a surprise since the source code of the two methods is the same, a simple copy/paste in the JDK with the exception of the argument type.

Seems that you can use

    @Test
    public void testAppendReplacement() {

        Pattern p = Pattern.compile("cat(?<plural>z?s?)");
        //Pattern p = Pattern.compile("cat(z?s?)");
        Matcher m = p.matcher("one catz two cats in the yard");
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            m.appendReplacement(sb, "dog${plural}");
            //m.appendReplacement(sb, "dog$001");
        }
        m.appendTail(sb);
        String result = sb.toString();
        assertEquals("one dogz two dogs in the yard", result);
    }

both the commented lines or the line above each. The documentation, however speaks only about the numbered references.

replaceAll/First

This is also an “old” method that replaces matched groups with some new strings. The only difference between the old version and the new is how the replacement string is provided. In the old version the string was given as a String calculated before the method was invoked. In the new version the string is provided as a Function<MatchResult,String>. This function is invoked for each match result and the replacement string can be calculated on the fly.

Knowing that the class Function was introduced only 3 years ago in Java 8 the new use of it in regular expressions may be a little slap-dash. Or, perhaps … may be we should see this as a hint that ten years from now, when the class Fuction will be 13 years old, we will still have Java 9?

Lets dig a bit deeper into these two methods. (Actually only to replaceAll because replaceFirst is the same except that it replaces only the first matched group.) I tried to create some not absolutely intricate examples when such a use could be valuable.

The first sample is from the JDK documentation:

    @Test
    public void demoReplaceAllFunction() {
        Pattern pattern = Pattern.compile("dog");
        Matcher matcher = pattern.matcher("zzzdogzzzdogzzz");
        String result = matcher.replaceAll(mr -> mr.group().toUpperCase());
        assertEquals("zzzDOGzzzDOGzzz", result);
    }

It is not too complex and shows the functionality. The use of a lambda expression is absolutely adequate. I can not imagine a simpler way to uppercase the constant string literal “dog”. Perhaps only writing “DOG”. Okay I am just kidding. But really this example is too simple. It is okay for the documentation where anything more complex would distract the reader from the functionality of the documented method. Really: do not expect less intricate examples in a JavaDoc. It describes how to use the API and not why the API was created an designed that way.

But here and now we will look at some more complex examples. We want to replace in a string the # characters with the numbers 1, 2, 3 and so on. The string contains numbered items and in case we insert a new one into the string we do not want to renumber manually. Sometimes we group two items, in which case we write ## and then we just want to skip a serial number for the next #. Since we have a unit test the code describes the functionality better than I can put it into words:

    @Test
    public void countSampleReplaceAllFunction() {
        AtomicInteger counter = new AtomicInteger(0);
        Pattern pattern = Pattern.compile("#+");
        Matcher matcher = pattern.matcher("# first item\n" +
                "# second item\n" +
                "## third and fourth\n" +
                "## item 5 and 6\n" +
                "# item 7");
        String result = matcher.replaceAll(mr -> "" + counter.addAndGet(mr.group().length()));
        assertEquals("1 first item\n" +
                "2 second item\n" +
                "4 third and fourth\n" +
                "6 item 5 and 6\n" +
                "7 item 7", result);
    }

The lambda expression passed to replaceAll gets the counter and calculates the next value. If we used one # then it increases it by 1 if we used two, then it adds two to the counter and so on. Because a lambda expression can not change the value of a variable in the surrounding environment (the variable has to be effectively final) the counter can not be an int or Integer variable. We need an object that holds an int value and can be changed. AtomicInteger is exactly that even if we do not use the atomic feature of it.

The next example goes even further and does some mathematical calculation. It replaces any floating point formatted number in the string to the sine value of it. That way it corrects our sentence since sin(pi) is not even close to pi, which can not be precisely expressed here. It is rather close to zero:

    @Test
    public void calculateSampleReplaceAllFunction() {
        Pattern pattern = Pattern.compile("\\d+(?:\\.\\d+)?(?:[Ee][+-]?\\d{1,2})?");
        Matcher matcher = pattern.matcher("The sin(pi) is 3.1415926");
        String result = matcher.replaceAll(mr -> "" + (Math.sin(Double.parseDouble(mr.group()))));
        assertEquals("The sin(pi) is 5.3589793170057245E-8", result);
    }

We will also play around a bit with this calculation for the demonstration of the last method in our list, which is a brand new one in the Matcher class.

Stream results()

The new method results() returns a stream of the matching results. To be more precise it returns a Stream of MatchResult objects. In the example below we use it to collect any floating point formatted number from the string and print their sine value comma separated:

    @Test
    public void resultsTest() {
        Pattern pattern = Pattern.compile("\\d+(?:\\.\\d+)?(?:[Ee][+-]?\\d{1,2})?");
        Matcher matcher = pattern.matcher("Pi is around 3.1415926 and not 3.2 even in Indiana");
        String result = String.join(",",
                matcher
                        .results()
                        .map(mr -> "" + (Math.sin(Double.parseDouble(mr.group()))))
                        .collect(Collectors.toList()));
        assertEquals("5.3589793170057245E-8,-0.058374143427580086", result);
    }

Summary

The new regular expression methods introduced in the Java 9 JDK are not essentially different from what was already available. They are neat and handy and in some situation , hey may ease programming. There is nothing that could have not been introduced in the earlier version. This is just the way of Java to make such changes to the JDK slow and well thought. After all that is why we love Java, don’t we?

The whole code copy paste from the IDE can be found and downloaded from the following gist

Hacking the IntegerCache in Java 9

Five years ago I published an article in Hungarian about how to alter the IntegerCahe in the JDK. Doing that is essentially hacking the Java run-time and there is no practical advantage unless while you develop the hacking code you get a better understanding how reflection works and how the Integer class is implemented.

The Integer class has a private nested class named IntegerCache that contains Integer objects for the int values -127 to 128. When the code has to box an int to Integer and the value is within this range then the run-time uses the cache instead of creating new Integer object. This is done for speed optimization reasons bearing in mind that the int values in programs are many times in this range (think about array indexing).

The side effect of this is that many times using the identity operator to compare two Integer objects may work so long as long the value is in the range. This is typically during unit test. In operational mode, when some of the values get bigger than 128 the code fails.

Hacking the IntegerCache using reflection may also lead to mysterious side effects and note that this is something that has its effect on the whole JVM. If a servlet redefines the small Integer cached values then all other servlets running in the same Tomcat under the same JVM will suffer.

There are other articles about it on the net from Lukas Eder

Add Some Entropy to Your JVM

and on the excellent blog site Sitepoint:

https://www.sitepoint.com/10-things-you-didnt-know-about-java/

Now that I started to play around with Java 9 early access version it came to my mind if I can do the same hacking with the new version of Java. Before starting that let’s refresh what we did with Java 8.

Lukas in his article displays a sample code, I copy here:

import java.lang.reflect.Field;
import java.util.Random;
 
public class Entropy {
  public static void main(String[] args) 
  throws Exception {
 
    // Extract the IntegerCache through reflection
    Class<?> clazz = Class.forName(
      "java.lang.Integer$IntegerCache");
    Field field = clazz.getDeclaredField("cache");
    field.setAccessible(true);
    Integer[] cache = (Integer[]) field.get(clazz);
 
    // Rewrite the Integer cache
    for (int i = 0; i < cache.length; i++) {
      cache[i] = new Integer(
        new Random().nextInt(cache.length));
    }
 
    // Prove randomness
    for (int i = 0; i < 10; i++) {
      System.out.println((Integer) i);
    }
  }
}

The code gets access to the IntegerCache via reflection and then fills the cache with random values. Naughty.

We can try to execute the same code in Java 9. Do not expect much fun though. Java 9 is more serious when somebody tries to violate it.

Exception in thread "main" java.lang.reflect.InaccessibleObjectException:
  Unable to make field static final java.lang.Integer[]
  java.lang.Integer$IntegerCache.cache
  accessible: module java.base does not "opens java.lang" to unnamed module @1bc6a36e

We get an exception that did not exist in Java 8. It says that object is not accessible because the module java.base, which is the part of the run-time of the JDK that is automatically imported by each Java program does not ‘opens’ (sic) the module to the unnamed module. It is thrown from the line where we try to set the field accessible.

The object we could easily access in Java 8 is not accessible any more, because the module system protects it. A code can only access fields, methods, and other things using reflection only if the class is in the same module, or if the module opens the package for reflective access for the world or for the module that needs the access. This is done in the module-info.java module definition file, like

module myModule {
    exports com.javax0.module.demo;
    opens com.javax0.module.demo;
}

The module java.base does not open itself for reflective access for us and especially not for the unnamed module, which is the code that we run. If we create a module for our code and name it then the error message will contain the name of that module.

Can we open the module programmatically? There is an addOpens method in the java.lang.reflect.Module module. Will it work?

Bad news for the hackers that it will not. It can only open a package in a module to another module if that package is already opened for the module calling this method. That way modules can pass on to other modules the right that they already have to access some packages in a reflective way but can not open things that are not open.

But the same time it is a good news. Java 9 is not so easily hackable like Java 8 was. At least this little hole is closed. It seems that Java starts to be professional grade and not to be a toy. Soon the time will come when we can migrate serious programs from RPG and COBOL to Java. (Sorry for the joke.)

UPDATE

After the article was republished on DZONE Peter Runge pointed out that the module system in this case still can be neglected using sun.misc.Unsafe class. Based on his suggestion the whole hack is here:

public class IntegerHack {

    public static void main(String[] args)
            throws Exception {
        // Extract the IntegerCache through reflection
        Class usf = Class.forName("sun.misc.Unsafe");
        Field unsafeField = usf.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true);
        sun.misc.Unsafe unsafe = (sun.misc.Unsafe)unsafeField.get(null);
        Class<?> clazz = Class.forName("java.lang.Integer$IntegerCache");
        Field field = clazz.getDeclaredField("cache");
        Integer[] cache = (Integer[])unsafe.getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field));
        // Rewrite the Integer cache
        for (int i = 0; i < cache.length; i++) {
            cache[i] = new Integer(
                    new Random().nextInt(cache.length));
        }

        // Prove randomness
        for (int i = 0; i < 10; i++) {
            System.out.println((Integer) i);
        }
    }
}

Final volatile

I was writing my book over the weekend and I was looking for some simple example that could demonstrate the real need of volatile modifier in multi-thread code. Years ago when I last time demonstrated the multi-thread capability Java was still 32-bit, or at least there was 32-bit Java available. On 32 bits you could concurrently increment long variables and because the lower and upper 32 bits were handled in different processor shift there was a chance that two threads garbled some way the non-volatile variable. Now with Java 9 this is not the case. Now Java is 64-bit and I had to demonstrate the need for a volatile on 64-bit before anyone comes up the stupid idea that it was only needed for 32-bit. (I could tell stories, but I try to keep it a professional blog. Not with much success, but still.)

I was searching stackoverflow and found this page that contains many meaningless, or less than usable answer (which clearly demonstrates that the topic is not simple) but it also contains a sample from Jed Wesley-Smith that inspired my demonstrating code for the book:

package packt.java9.by.example.thread;

public class VolatileDemonstration implements Runnable {
    private Object o = null;
    private static final Object NON_NULL = new Object();
    @Override
    public void run() {
        while( o == null );
        System.out.println("o is not null");
    }
    public static void main(String[] args)
                           throws InterruptedException {
        VolatileDemonstration me = new VolatileDemonstration();
        new Thread(me).start();
        Thread.sleep(1000);
        me.o = NON_NULL;
    }
}

This code will never finish, unless you convert the field o volatile. We also need the 1000ms sleep to allow the JIT to optimize the code of the method run() after which it never reads the variable o ever again. The JIT assumes intra-thread semantics and takes the liberty to optimize the code that way. (Java Language Specification 17.4.7)

But what happens if you have a field that you can not convert to volatile? What? Can’t you just write the keyword volatile in front of the type Object? Perhaps I was giving too much hint in the title of the article…

A final field can not be volatile. Of course: a final can not change, there is no point to re-read it from the main memory and waste CPU cycles for the synchronization of any change of it between the CPU caches. But that is not true.

Final variables can be changed once.

This is something that novice Java developers tend to forget. When an object is created any final field has the zero value. In case of an object this value is null. The field has to get its final value until the end of the initialization process, that is until the end of the execution of the constructor (any constructor). Look at the following code:

package packt.java9.by.example.thread;

public class VolatileDemonstration implements Runnable {
    private final Object o;
    private static final Object NON_NULL = new Object();
    @Override
    public void run() {
        while( o == null );
        System.out.println("o is not null");
    }

    public VolatileDemonstration() throws InterruptedException {
        new Thread(this).start();
        Thread.sleep(1000);
        this.o = NON_NULL;
    }
}

The constructor starts the new thread, sleeps and then sets the field that can not be volatile. What is the solution?

What solution? There is no solution! This is a demonstration code. Just don’t write code that does things like this: that is the solution. OK?

Takeaway

What can we learn from this? Not all of the followings can be directly implied from the above, but they are all related to the phenomenon. I could write a longer article leading to any of the followings but it would have only abused your patience.

Juniors

  • Final fields can be changed once. It is not true that they are not changing never (sic).
  • A thread may read the value of a final field once and it may not read it ever again. If the JVM runs for years the thread may keep the value in the thread context in some registry or CPU cache for years as long as it likes.
  • Never let this escape from the constructor.
  • Among other more trivial things the “never let this escape from the constructor” also means not to pass it as argument to a method that can be overridden or not under the control of the programmer, who is responsible for the current class.
  • Write well behaving code or else you will suffer the slings and arrows of your outrageous program.

Seniors

  • See the takeaways for juniors and teach them.
  • You have a nice brain twister code for education.
  • Java is not a perfect language allowing such constructs. But do not tell juniors. When they realize it they are already seniors and then it is just too late.
  • The solution is a liquid mixture in which the minor component is uniformly distributed within the major component.