Category Archives: Java

Get rid of pom XML… almost

Introduction

POM files are XML formatted files that declaratively describe the build structure of a Java project to be built using Maven. Maintaining the POM XML files of large Java projects is many times cumbersome. XML is verbose and also the structure of the POM requires the maintenance of redundant information. The naming of the artifacts many times is redundant repeating some part of the name in the groupId and in the artifactId. The version of the project should appear in many files in case of a multi-module project. Some of the repetitions can be reduced using properties defined in the parent pom, but you still have to define the parent pom version in each module pom, because you refer to a POM by the artifact coordinates and not just referring to it as “the pom that is there in the parent directory”. The parameters of the dependencies and the plugins can be configured in the parent POM in the pluginManagement and dependency management but you still can not get rid of the list of the plugins and dependencies in each and every module POM though they are usually just the same.

You may argue with me because it is also the matter of taste, but for me, POM files in their XML format are just too redundant and hard to read. Maybe I am not meticulous enough but many times I miss some errors in my POM files and have a hard time to fix them.

There are some technologies to support other formats, but they are not widely used. One such approach to get rid of the XML is Poyglot Maven. However, if you look on that Github page at the very first example, which is Ruby format POM you can still see a lot of redundant information, repetitions. This is because Polyglot Maven plugs-into Maven itself and replaces only the XML format to something different but does not help on the redundancy of the POM structure itself.

In this article, I will describe an approach that I found much better than any other solution, where the POM files remain XML for the build process, thus there is no need for any new plugin or change of the build process, but these pom.xml files are generated using the Jamal macro language from the pom.xml.jam file and some extra macro files that are shared by the modules.

Jamal

The idea is to use a text-based macro language to generate the XML files from some source file that contains the same information is a reduced format. This is some kind of programming. The macro description is a program that outputs the verbose XML format. When the macro language is powerful enough the source code can be descriptive enough and not too verbose. My choice was Jamal. To be honest, one of the reasons to select Jamal was that it is a macro language that I developed almost 20 years ago using Perl and a half year ago I reimplemented it in Java.

The language itself is very simple. Text and macros are mixed together and the output is the text and the result of the macros. The macros start with the { character or any other string that is configured and end by the corresponding } character or by the string that was configured to be the ending string. Macros can be nested and there is fine control what order the nested macros should be evaluated. There are user-defined and built-in macros. One of the built-in macros is define that is used to define user-defined macros.

An example talks better. Let’s have a look at the following test.txt.jam file.

{@define GAV(_groupId,_artifactId,_version)=
    {#if |_groupId|<groupId>_groupId</groupId>}
    {#if |_artifactId|<artifactId>_artifactId</artifactId>}
    {#if |_version|<version>_version</version>}
}

{GAV :com.javax0.geci:javageci-parent:1.1.2-SNAPSHOT}

processing it with Jamal we will get


    <groupId>com.javax0.geci</groupId>
    <artifactId>javageci-parent</artifactId>
    <version>1.1.2-SNAPSHOT</version>

I deleted the empty lines manually for typesetting reasons though, but you get a general idea. GAV is defined using the built-in macro define. It has three arguments named _groupId,_artifactId and _version. When the macro is used the format argument names in the body of the macro are replaced with the actual values and replace the user-defined macro in the text. The text of the define built-in macro itself is an empty string. There is a special meaning when to use @ and when to use # in front of the built-in macros, but in this article, I cannot get into that level of detail.

The if macros also make it possible to omit groupId, artifactId or version, thus

{GAV :com.javax0.geci:javageci-parent:}

also works and will generate

    <groupId>com.javax0.geci</groupId>
    <artifactId>javageci-parent</artifactId>

If you feel that still there is a lot of redundancy in the definition of the macros: you are right. This is the simple approach defining GAV, but you can go to the extreme:

{#define GAV(_groupId,_artifactId,_version)=
    {@for z in (groupId,artifactId,version)=
        {#if |_z|<z>_z</z>}
    }
}{GAV :com.javax0.geci:javageci-parent:}

Be warned that this needs an insane level of understanding of macro evaluation order, but as an example, it shows the power. More information on Jamal https://github.com/verhas/jamal

Let’s get back to the original topic: how Jamal can be used to maintain POM files.

Cooking pom to jam

There can be many ways, which each may be just good. Here I describe the first approach I used for the Java::Geci project. I create a pom.jim file (jim stands for Jamal imported or included files). This contains the definitions of macros, like GAV, dependencies, dependency and many others. You can download this file from the Java::Geci source code repo: https://github.com/verhas/javageci The pom.jim file can be the same for all projects, there is no any project specific in it. There is also a version.jim file that contains the macro that defines at one single place the project version, the version of Java I use in the project and the groupId for the project. When I bump the release number from -SNAPSHOT to the next release or from the release to the next -SNAPSHOT this is the only place where I need to change it and the macro can be used to refer to the project version in the top level POM? but also in the module POMs referring to the parent.

In every directory, where there should a pom.xml file I create a pom.xml.jam file. This file imports the pom.jim file, so the macros defined there can be used in it. As an example the Java::Geci javageci-engine module pom.xml.jam file is the following:

{@import ../pom.jim}
{project |jar|
    {GAV ::javageci-engine:{VERSION}}
    {parent :javageci-parent}
    {name|javageci engine}
    {description|Javageci macro library execution engine}

    {@include ../plugins.jim}

    {dependencies#
        {@for MODULE in (api,tools,core)=
            {dependency :com.javax0.geci:javageci-MODULE:}}
        {@for MODULE in (api,engine)=
            {dependency :org.junit.jupiter:junit-jupiter-MODULE:}}
    }
}

I think that this is fairly readable, at least for me it is more readable than the original pom.xml was:

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>javageci-engine</artifactId>
    <version>1.1.1-SNAPSHOT</version>
    <parent>
        <groupId>com.javax0.geci</groupId>
        <artifactId>javageci-parent</artifactId>
        <version>1.1.1-SNAPSHOT</version>
    </parent>
    <name>javageci engine</name>
    <description>Javageci macro library execution engine</description>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.javax0.geci</groupId>
            <artifactId>javageci-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.javax0.geci</groupId>
            <artifactId>javageci-tools</artifactId>
        </dependency>
        <dependency>
            <groupId>com.javax0.geci</groupId>
            <artifactId>javageci-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
        </dependency>
    </dependencies>
</project>

To start Jamal I can use the Jamal Maven plugin. To do that the easiest way is to have a genpom.xml POM file in the root directory, with the content:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javax0.jamal</groupId>
    <artifactId>pom.xml_files</artifactId>
    <version>out_of_pom.xml.jam_files</version>
    <build>
        <plugins>
            <plugin>
                <groupId>com.javax0.jamal</groupId>
                <artifactId>jamal-maven-plugin</artifactId>
                <version>1.0.2</version>
                <executions>
                    <execution>
                        <id>execution</id>
                        <phase>clean</phase>
                        <goals>
                            <goal>jamal</goal>
                        </goals>
                        <configuration>
                            <transformFrom>\.jam$</transformFrom>
                            <transformTo></transformTo>
                            <filePattern>.*pom\.xml\.jam$</filePattern>
                            <exclude>target|\.iml$|\.java$|\.xml$</exclude>
                            <sourceDirectory>.</sourceDirectory>
                            <targetDirectory>.</targetDirectory>
                            <macroOpen>{</macroOpen>
                            <macroClose>}</macroClose>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Having this I can start Maven with the command line mvn -f genpom.xml clear. This not only creates all the POM files but also clears the previous compilation result of the project, which is probably a good idea when the POM file changes. It can also be executed when there is no pom.xml yet in the directory or when the file is not valid due to some bug you may have in the jam cooked POM file. Unfortunately, all recursivity has to end somewhere and it is not feasible, though possible to maintain the genpom.xml as a jam cooked POM file.

Summary

What I described is one approach to use a macro language as a source instead of raw editing the pom.xml file. The advantage is the shorter and simpler project definition. The disadvantage is the extra POM generation step, which is manual and not part of the build process. You also lose the possibility to use the Maven release plugin directly since that plugin modifies the POM file. I myself always had problems to use that plugin, but it is probably my error and not that of the plugin. Also, you have to learn a bit Jamal, but that may also be an advantage if you happen to like it. In short: you can give it a try if you fancy. Starting is easy since the tool (Jamal) is published in the central repo, the source and the documentation is on Github, thus all you need is to craft the genpom.xml file, cook some jam and start the plugin.

POM files are not the only source files that can be served with jam. I can easily imagine the use of Jamal macros in the product documentation. All you need is creating a documentationfile.md.jam file as a source file and modify the main POM to run Jamal during the build process converting the .md.jam to the resulting macro processed markdown document. You can also set up a separate POM just like we did in this article in case you want to keep the execution of the conversion strictly manual. You may even have java.jam files in case you want to have a preprocessor for your Java files, but I beg you not to do that. I do not want to burn in eternal flames in hell for giving you Jamal. It is not for that purpose.

There are many other possible uses of Jamal. It is a powerful macro language that is easy to embed into applications and also easy to extend with macros written in Java. Java::Geci also has a 1.0 version module that supports Jamal to ease code generation still lacking some built-in macros that are planned to make it possible to reach out to the Java code structure via reflections. I am also thinking about to develop some simple macros to read Java source files and to include into documentation. When I have some result in those I will write about.

If you have any idea what else this technology could be used for, do not hesitate to contact me.

Advertisements

var and language design

What is var in Java

The var predefined type introduced in Java 10 lets you declared local variables without specifying the type of the variable when you assign a value to the variable. When you assign a value to a variable the type of the expression already defines the type of the variable, thus there is no reason to type the type on the left side of the line again. It is especially good when you have some complex long types with a lot of generics, for example

HashMap<String,TreeMap<Integer,String> myMap = mapGenerator();

Generic types you could already inherit in prior Java versions but now you can simply type

var myMap = mapGenerator();

This is simpler, and most of the times more readable than the previous version. The aim of the var is mainly readability. It is important to understand that the variables declared this way will have a type and the introduction of this new predefined type (not a keyword) does not render Java to be a dynamic language. There are a few things that you can do this way that you could not before or you could do it only in a much more verbose way. For example, when you assign an instance of an anonymous class to a variable you can invoke the declared methods in the class through the var declared variables. For example:

var m = new Object{ void z(){} }
m.z();

you can invoke the method z() but the code

Object m = new Object{ void z(){} }
m.z();

does not compile. You can do that because anonymous classes actually have a name at their birth, they just lose it when the instance gets assigned to a variable declared to be the type of Object.

There is a little shady part of the var keyword. This way we violate the general rule to instantiate the concrete class but declare the variable to be the interface. This is a general abstraction rule that we usually follow in Java most of the times. When I create a method that returns a HashMap I usually declare the return value to be a Map. That is because HashMap is the implementation of the return value and as such is none of the business of the caller. What I declare in the return type is that I return something that implements the Map interface. The way I do it is my own duty. Similarly, we declare usually the fields in the classes to be of some interface type if possible. The same rule should also be followed by local variables. A few times it helped me a lot when I declared a local variable to be Set but the actual value was TreeSet and then typing the code I faced some error. Then I realized that I was using some of the features that are not Set but SortedSet. It helped me to realize that sorted-ness is important in the special case and that it will also be important for the caller and thus I had to change the return type of the method also to be SortedSet. Note that SortedSet in this example is still an interface and not the implementation class.

With the use of var we lose that and we gain a somewhat simpler source code. It is a trade-off as always. In case of the local variables the use of the variable is close in terms of source code lines to the declaration, therefore the developer can see in a glimpse what is what and what is happening, therefore the “bad” side of this tradeoff is acceptable. The same tradeoff in case of method return values or fields is not acceptable. The use of these class members can be in different classes, different modules. It is not only difficult but it may also be impossible to see all the uses of these values, therefore here we remain in the good old way: declare the type.

The future of var (just ideas)

There are cases when you cannot use var even for local variables. Many times we have the following coding pattern:

final var variable; // this does not work in Java 11
if ( some condition ) {
    variable = expression_1
    // do something here
} else {
    variable = expression_2
    // do something here
}

Here we can not use var because there is no expression assigned to the variable on the declaration itself. The compiler, however, could be extended. From now on what I talk about is not Java as it is now. It is what I imagine how it can be in some future version.

If the structure is simple and the “do something here” is empty, then the structure can be transformed into a ternary operator:

final var variable = some condition ? ( expression_1 ) : (expression_2)

In this case, we can use the var declaration even if we use an old version of Java, e.g.: Java 11. However, be careful!

var h = true ? 1L : 3.3;

What will be the actual type of the variable h in this example? Number? The ternary operator has complex and special type coercion rules, which usually do not cause any issue because the two expressions are close to each other. If we let the structure described above use a similar type coercion then the expressions are not that close to each other. As for now, the distance is far enough for Java not to allow the use of the var type definition. My personal opinion is that the var declaration should be extended sometime in the future to allow the above structure but only in the case when the two (or more in case of more complex structure) expressions have exactly the same type. Otherwise, we may end up having an expression that results in an int, another that results in a String and then what will the type of the variable be? Do not peek at the picture before answering!

(This great example was given by Nicolai Parlog.)

I can also imagine that in the future we will have something that is similar to Scala val, which is final var in Java 11. I do not like the var vs. val naming though. It is extremely sexy and geekish, but very easy to mistake one for the other. However, if we have a local variable declaration that starts with the final keyword then why do we need the var keyword after that?

Finally, I truly believe that var is a great tool in Java 11, but I also expect that it’s role will be extended in the future.

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.

 

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