Supporting Java 8

Learn how you can provide Java 8 support.

Although we are on Java 13, there are a lot of production installations running with Java 8. As a professional, I developed Java 8 code many times, even these days, and I have to be happy that this is not Java 6. On the other hand, as an open-source developer, I have the liberty to develop Java code using Java 11, 12, or even 13 if that pleases me. And it does.

On the other hand, though, I want my code to be used. Developing a tool like License3j or Java::Geci, which are kind of libraries releasing Java 11-compatible bytecode, cuts off all the Java-8-based applications that may use these libraries.

Handling Repeated Code Automatically

Learn how to deal with repeated Java code automatically!

In this article, I will describe how you can use the Java::Geci generator Repeated to overcome the Java language shortage that generics cannot be primitive. The example is a suggested extension of the Apache Commons Lang library.

When you copy-paste code, you do something wrong. At least that is the perception. You have to create your code structure in a more generalized way so that you can use different parameters instead of similar code many times.

Java Hexadecimal Floating Point Literal

I was developing a new functionality into Java::Geci to make it less prone to code reformatting. The current release of the code will overwrite an otherwise identical code if it was reformatted. It is annoying since it is fairly easy to press the reformatting key shortcut and many projects even require that developers set their editor to automatically format the code upon save. In those cases, Java::Geci cannot be used because as soon as the code is reformatted, the generator thinks that the code it generates is not the same as the one already in the source file, updates it, and signals the change of the code failing the unit tests.

The solution I was crafting compares the Java source files — first, converting them to a list of lexical elements. That way, you can even reformat the code inserting new lines, spaces, etc., so long as long the code remains the same. To do that, I needed a simplified lexical analyzer for Java. Writing a lexical analyzer is not a big deal, I created several for different reasons since I first read the Dragon Book in 1987. The only thing I really needed is the precise definition of what are the string, character, number literals, the keywords, and so on. In short, what is the definition of the Java language on the lexical level and how is it processed. Fortunately, there is a precise definition for that, the Java Language Specification, which is not only precise but also readable and has examples. So, I started to read the corresponding chapters.

Reflection Selector Expression

Java::Geci is a code generator that runs during unit test time. If the generated code fits the actual version of the source code, then the test does not fail. If there is a need for any modification, then the tests modify the source code and fail. For example, there is a new field that needs a setter and getter. Then, the accessor generator will generate the new setter and getter and then it fails. If there is no new field, then the generated code is just the one that is already there — no reason to touch the source code: The test that started the generator finishes successfully.

Because Java::Geci generators run as tests, which is at run-time, and because they need access to the Java code structures for which they generate code, Java reflection is key for these generators.