Jekyll2023-11-02T14:25:08+00:00https://www.albinhasani.net/feed.xmlAlbi’s BlogJust my thoughts on the matter.Albin HasaniHelpful NPEs and where to find them2020-10-11T00:00:00+00:002020-10-11T00:00:00+00:00https://www.albinhasani.net/helpful-npes<p>What drives Java developers crazy and goes away when given developers a strong brew of coffee? NullPointerExceptions.</p>
<!--more-->
<p>How many times was your code confident to call that method on the object? Only to find the JVM crush its hopes by blabbering a lot of console language, crush your perfect solution to pieces, and leave only a witness statement as its final output: NullPointerException.</p>
<p>This construct has always puzzled developers.</p>
<p><img src="/assets/images/what_is_npe.png" alt="what-is-npe" /></p>
<p>Tony Hoare, went as far as to call the introduction of the null reference his <a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/" target="_blank">billion dollar mistake</a>, publicly apologizing for it. He is probably the only dude alive who could get away with it, given his contributions in Computer Science and the quicksort algorithm.</p>
<p>Null itself is not the problem. Having an empty value in your domain is not a disaster and may be a clear representation of your business example. What is wrong is how you’re allowed to dangerously access this reference without a proper null check. That is totally unsafe and has been the cause of so many developers’ tears and pain.</p>
<p>Following Tony Hoare here, <em>A programming language designer should be responsible for the mistakes made by programmers using the language. It is a serious activity; not one that should be given to programmers with 9 months experience with assembly; they should have a strong scientific basis, a good deal of ingenuity and invention and control of detail, and a clear objective that the programs written by people using the language would be correct. free of obvious errors and free of syntactical traps.</em></p>
<p>Designing programs is hard. Designing languages that make you able to write these programs in a safe way is harder.</p>
<p>Optionals have already been providing a hand in dealing with the null references, by having a representation for an absence of value: <code class="language-plaintext highlighter-rouge">Optional.EMPTY</code>. Kotlin aims to be null-safe by design. It allows explicit nullable types by adding <code class="language-plaintext highlighter-rouge">?</code> at the end of type declaration, and only safe calls to these references by typing: <code class="language-plaintext highlighter-rouge">?.</code>. If you insist, it allows some explicit <code class="language-plaintext highlighter-rouge">!!</code> referencing which could still throw a NPE, but that’s on you.</p>
<p>This post does not teach you how to avoid NPEs altogether, it focuses on the moment that it happens. Java has a strong focus, perhaps more than any other language, on backward compatibility. It would hardly risk a system written in an older version of Java to not work on the latest version. I wouldn’t bet on Java to lose that focus anytime soon. So null references are here to stay. How can we make our lives easier with them?</p>
<h2 id="where-we-stand">Where we stand</h2>
<p>You hate it. No matter how much experience you have under your belt, you always fail to the same mistake. It’s like that bad dream that keeps repeating. NullPointerException is the monster.</p>
<p>Even though Java has included Optionals as a language feature, and they’ve taken a lot of ground, you still haven’t seen the last of this monster.</p>
<p>Actually, we are about to see one right now.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span> <span class="n">notANullReference</span> <span class="o">=</span> <span class="s">"hi there"</span><span class="o">;</span>
<span class="nc">String</span> <span class="n">aNullReference</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="n">printLength</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">notANullReference</span><span class="o">);</span>
<span class="n">printLength</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">aNullReference</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Consumer</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">printLength</span> <span class="o">=</span> <span class="n">input</span> <span class="o">-></span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Length of string %s is %d"</span><span class="o">.</span><span class="na">formatted</span><span class="o">(</span><span class="n">input</span><span class="o">,</span> <span class="n">input</span><span class="o">.</span><span class="na">length</span><span class="o">()));</span>
</code></pre></div></div>
<p>It does not take long to understand that a call to <code class="language-plaintext highlighter-rouge">.length()</code> on the null reference will throw a NPE.</p>
<p>Running this code will output the following info in the stacktrace:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">lambda</span><span class="n">$static</span><span class="err">$</span><span class="mi">0</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">21</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">12</span><span class="o">)</span>
</code></pre></div></div>
<p>It states there is a NPE in our App class and it lets us know about the line that it threw the error in what method. Beyond that, understanding the cause of this message is poor.</p>
<p>I am not saying that is entirely the opposite of helpful, but it could have said something more.</p>
<h2 id="java-14-saves-the-day">Java 14 saves the day</h2>
<p>Make a wish for a new Java feature and there will be a JEP for it.</p>
<p>Our hero has a number and a name: JEP <a href="https://openjdk.java.net/jeps/358" target="_blank">358</a>: Helpful NullPointerExceptions.</p>
<p>This is one of the goodies that landed with JDK 14 earlier in March this year.</p>
<p>To make a case why we might need it, let’s add another domain to the equation and do something extra with it.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">firstPerson</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="s">"Albi"</span><span class="o">,</span> <span class="mi">26</span><span class="o">);</span>
<span class="kt">var</span> <span class="n">secondPerson</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="kc">null</span><span class="o">,</span> <span class="mi">100</span><span class="o">);</span>
<span class="n">printNameLength</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">firstPerson</span><span class="o">);</span>
<span class="n">printNameLength</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">secondPerson</span><span class="o">);</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="nc">Consumer</span><span class="o"><</span><span class="nc">Person</span><span class="o">></span> <span class="n">printNameLength</span> <span class="o">=</span> <span class="n">person</span> <span class="o">-></span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">printf</span><span class="o">(</span><span class="s">"Length of name for person %s is %s"</span><span class="o">,</span> <span class="n">person</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="n">person</span><span class="o">.</span><span class="na">name</span><span class="o">.</span><span class="na">length</span><span class="o">());</span>
<span class="n">record</span> <span class="nf">Person</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>
<p>What we got is a an object reference <code class="language-plaintext highlighter-rouge">Person</code>, which also contains a reference to its <code class="language-plaintext highlighter-rouge">name</code> field.</p>
<p>As we know, because of our null reference, this program is likely set for failure.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">lambda</span><span class="n">$static</span><span class="err">$</span><span class="mi">1</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">29</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">19</span><span class="o">)</span>
</code></pre></div></div>
<p>This message is telling us in which method and line the incident happened.</p>
<p>Let’s misuse this code and add another null, this time by setting a complete reference to null.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Person</span> <span class="n">thirdPerson</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="n">printNameLength</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">thirdPerson</span><span class="o">);</span>
</code></pre></div></div>
<p>Again let’s run this piece of code.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">lambda</span><span class="n">$static</span><span class="err">$</span><span class="mi">1</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">29</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">23</span><span class="o">)</span>
</code></pre></div></div>
<p>Besides following with some logging and debugging, which could get complex in a short time, we do not have a way to find which one of the references in the object caused it just by looking at the message.</p>
<p>Our goal is to get to something else, the faulty operation. These two NPE messages are almost identical, and don’t offer much in that direction apart from the line where they happened.</p>
<p>That is not so.. <em>helpful</em>.</p>
<p><img src="/assets/images/dark_npe.jpg" alt="dark-npe" /></p>
<p>Getting close to the point, you could make use of what this JEP has in store to explore an alternate universe where NPEs are helpful.</p>
<p>Running the same program with a special flag: <code class="language-plaintext highlighter-rouge">-XX:+ShowCodeDetailsInExceptionMessages</code> would shed some light on this investigation.</p>
<p>The first run:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span><span class="o">:</span>
<span class="nc">Cannot</span> <span class="n">invoke</span> <span class="s">"String.length()"</span> <span class="n">because</span> <span class="s">"person.name"</span> <span class="n">is</span> <span class="kc">null</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">lambda</span><span class="n">$static</span><span class="err">$</span><span class="mi">1</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">29</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">19</span><span class="o">)</span>
</code></pre></div></div>
<p>It is there. This indeed helpful message makes it loud that <code class="language-plaintext highlighter-rouge">name</code> field is null, therefore the JVM cannot call <code class="language-plaintext highlighter-rouge">String.length()</code> on it. A real eye-opener.</p>
<p>The second run:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Exception</span> <span class="n">in</span> <span class="n">thread</span> <span class="s">"main"</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">NullPointerException</span><span class="o">:</span>
<span class="nc">Cannot</span> <span class="n">read</span> <span class="n">field</span> <span class="s">"name"</span> <span class="n">because</span> <span class="s">"person"</span> <span class="n">is</span> <span class="kc">null</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">lambda</span><span class="n">$static</span><span class="err">$</span><span class="mi">1</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">29</span><span class="o">)</span>
<span class="n">at</span> <span class="n">com</span><span class="o">.</span><span class="na">albi</span><span class="o">.</span><span class="na">helpful</span><span class="o">.</span><span class="na">npe</span><span class="o">.</span><span class="na">App</span><span class="o">.</span><span class="na">main</span><span class="o">(</span><span class="nc">App</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">23</span><span class="o">)</span>
</code></pre></div></div>
<p>This sets them apart. The second case is another story because the whole reference is <code class="language-plaintext highlighter-rouge">null</code>, and it is this faulty segment that caused it. There was no way we could have known without debugging.</p>
<p>Making it so easy, the developers can focus on actually fixing the NPE, rather than starting a quest to find the reference that caused it. In most cases, this feature will serve it for us. Going back to the statement from Hoare, the Java language designers take it seriously to offer the best programming experience to developers, if not for reversing decisions of the past which could not be abandoned due to the backward-compatibility promise, instead offering a bag of improvements such as this one.</p>
<p>Only writing this article I did learn that this feature has become a default on JDK 15, and you don’t need the <code class="language-plaintext highlighter-rouge">-XX:+ShowCodeDetailsInExceptionMessages</code> flag anymore. As a matter of fact, Java is moving so fast even someone like me, who is a usual twitter citizen, missed the news.</p>
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr">Helpful NullPointerException (JEP 358) will be set by default in JDK 15.<a href="https://t.co/r8wdTvq59X">https://t.co/r8wdTvq59X</a><a href="https://t.co/kmYk5enRUj">https://t.co/kmYk5enRUj</a> <a href="https://t.co/5lV8DymKpJ">pic.twitter.com/5lV8DymKpJ</a></p>— David Delabassée (@delabassee) <a href="https://twitter.com/delabassee/status/1276024020392128514?ref_src=twsrc%5Etfw">June 25, 2020</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>P.S. Source Code on <a href="https://github.com/albihasani94/helpful-NPE" target="_blank">Github</a></p>Albin HasaniWhat drives Java developers crazy and goes away when given developers a strong brew of coffee? NullPointerExceptions.Helidon SE, another breed of speedy2020-09-22T00:00:00+00:002020-09-22T00:00:00+00:00https://www.albinhasani.net/helidon-se-x<p>In this follow-up to the <a href="/helidon-mp">Helidon MP</a> post, I’m going to explore the other Helidon sibling: Helidon SE.</p>
<!--more-->
<p>As the java lightweight frameworks progress, taking a look around it seems to be a rich community of choices where the three most attractive to me seem Helidon, Micronaut, and Quarkus.</p>
<p>Helidon comes in two flavors:</p>
<ul>
<li>Helidon MP which stands for the Microprofile implementation (I found myself digging the MicroProfile flavor, that must be one of the perks of being a die-hard Java EE fan)</li>
<li>Helidon SE is the non-blocking reactive way of building things (hence the reason for this post)</li>
</ul>
<p>Helidon MP is more similar to Quarkus in terms of developer experience, while Micronaut has its own thing; more like the approach Spring Boot takes.</p>
<p>Where does Helidon SE fit in all of this?</p>
<p>Helidon SE is a microframework that embraces the latest Java SE features: reactive streams, asynchronous and functional programming, and fluent-style APIs.</p>
<p>To dig more into this, I’m going to build a project and tinker around with its web server, which is built on top of <a href="https://netty.io" target="_blank">Netty</a>.</p>
<h2 id="creating-the-project">Creating the project</h2>
<p>We’re going to use the maven archetype of helidon-quickstart for setting things up.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn <span class="nt">-U</span> archetype:generate <span class="nt">-DinteractiveMode</span><span class="o">=</span><span class="nb">false</span> <span class="se">\</span>
<span class="nt">-DarchetypeGroupId</span><span class="o">=</span>io.helidon.archetypes <span class="se">\</span>
<span class="nt">-DarchetypeArtifactId</span><span class="o">=</span>helidon-quickstart-se <span class="se">\</span>
<span class="nt">-DarchetypeVersion</span><span class="o">=</span>2.0.2 <span class="se">\</span>
<span class="nt">-DgroupId</span><span class="o">=</span>com.albi <span class="se">\</span>
<span class="nt">-DartifactId</span><span class="o">=</span>helidon-se <span class="se">\</span>
<span class="nt">-Dpackage</span><span class="o">=</span>com.albi.helidon.se
</code></pre></div></div>
<h3 id="exploring-the-structure">Exploring the structure</h3>
<p>The generated project contains the following directory structure.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>tree <span class="nb">.</span>
<span class="nb">.</span>
├── Dockerfile
├── Dockerfile.jlink
├── Dockerfile.native
├── README.md
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── albi
│ │ └── helidon
│ │ └── se
│ │ ├── GreetService.java
│ │ ├── Main.java
│ │ └── package-info.java
│ └── resources
│ ├── META-INF
│ │ └── native-image
│ │ └── reflect-config.json
│ ├── application.yaml
│ └── logging.properties
└── <span class="nb">test</span>
└── java
└── com
└── albi
└── helidon
└── se
└── MainTest.java
</code></pre></div></div>
<p>Besides the application logic classes which we will dive in a bit, it’s good to know that there are provided deployment files for docker images and specific deployments with jlink and GraalVM profiles.</p>
<h3 id="build">Build</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package
</code></pre></div></div>
<h3 id="serve">Serve</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java <span class="nt">-jar</span> target/helidon-se.java
</code></pre></div></div>
<h3 id="perform-the-first-request">Perform the first request</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/greet
<span class="o">{</span>
<span class="s2">"message"</span>:<span class="s2">"Hello World!"</span>
<span class="o">}</span>
</code></pre></div></div>
<h2 id="dissecting-the-main-class">Dissecting the Main class</h2>
<p>One of the things that catch the eye in the project structure is the <code class="language-plaintext highlighter-rouge">Main</code> class. This class is the application starting point and contains the methods to configure and start the web server.</p>
<p>Exploring the main class, you get access to setting up components such as: config, routing, health checks, and logging.</p>
<p>The logging part aside, I have noticed the following flow of setting things up:</p>
<h3 id="1-create-the-config">1. Create the config</h3>
<p>Creating the config is straightforward.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Config</span> <span class="n">config</span> <span class="o">=</span> <span class="nc">Config</span><span class="o">.</span><span class="na">create</span><span class="o">();</span>
</code></pre></div></div>
<p>By default this bare statement will pick up <code class="language-plaintext highlighter-rouge">application.yaml</code> from the classpath.</p>
<p>Its default configuration seems minimal:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">app</span><span class="pi">:</span>
<span class="na">greeting</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Hello"</span>
<span class="na">server</span><span class="pi">:</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">8080</span>
<span class="na">host</span><span class="pi">:</span> <span class="s">0.0.0.0</span>
</code></pre></div></div>
<p>The greeting variable is already defined and ready for the application code to make use of it.</p>
<p>This value would be grabbed by the system properties if it was set, and again the system property would have been overriden if an environment variable had been set.</p>
<p>You can create different configuration sources and use them instead by specifying tighter control employing the config builder.</p>
<h3 id="2-build-routing">2. Build routing</h3>
<p>Let’s move on to building a routing configuration.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">static</span> <span class="nc">Routing</span> <span class="nf">createRouting</span><span class="o">(</span><span class="nc">Config</span> <span class="n">config</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">MetricsSupport</span> <span class="n">metrics</span> <span class="o">=</span> <span class="nc">MetricsSupport</span><span class="o">.</span><span class="na">create</span><span class="o">();</span>
<span class="nc">GreetService</span> <span class="n">greetService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">GreetService</span><span class="o">(</span><span class="n">config</span><span class="o">);</span>
<span class="nc">HealthSupport</span> <span class="n">health</span> <span class="o">=</span> <span class="nc">HealthSupport</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="o">.</span><span class="na">addLiveness</span><span class="o">(</span><span class="nc">HealthChecks</span><span class="o">.</span><span class="na">healthChecks</span><span class="o">())</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="k">return</span> <span class="nc">Routing</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">health</span><span class="o">)</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="n">metrics</span><span class="o">)</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/greet"</span><span class="o">,</span> <span class="n">greetService</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Here, using provided support for <code class="language-plaintext highlighter-rouge">metrics</code> and <code class="language-plaintext highlighter-rouge">health</code>, we register these services at their respective routes: <code class="language-plaintext highlighter-rouge">/metrics</code> and <code class="language-plaintext highlighter-rouge">/health</code>. The next route is our own, providing the <code class="language-plaintext highlighter-rouge">greetService</code>.</p>
<p>Note that we pass the existing <code class="language-plaintext highlighter-rouge">config</code> that we created to our service, in order to make it available for the routing component.</p>
<h3 id="3-build-the-web-server">3. Build the web server</h3>
<p>We got what we need to build the web server.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">WebServer</span> <span class="n">server</span> <span class="o">=</span> <span class="nc">WebServer</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">createRouting</span><span class="o">(</span><span class="n">config</span><span class="o">))</span>
<span class="o">.</span><span class="na">config</span><span class="o">(</span><span class="n">config</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"server"</span><span class="o">))</span>
<span class="o">.</span><span class="na">addMediaSupport</span><span class="o">(</span><span class="nc">JsonpSupport</span><span class="o">.</span><span class="na">create</span><span class="o">())</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<p>Again, note that also the web server makes use of the config, based on <code class="language-plaintext highlighter-rouge">application.yaml</code>, to retrieve the server configuration.</p>
<p>Here, we add the routing we created as an argument to the builder method of WebServer. Also, we add support for JSONP.</p>
<h3 id="4-start-the-web-server">4. Start the web server</h3>
<p>It seems like we’re good to go.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">()</span>
<span class="o">.</span><span class="na">thenAccept</span><span class="o">(</span><span class="n">ws</span> <span class="o">-></span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span>
<span class="s">"WEB server is up! http://localhost:"</span> <span class="o">+</span> <span class="n">ws</span><span class="o">.</span><span class="na">port</span><span class="o">()</span> <span class="o">+</span> <span class="s">"/greet"</span><span class="o">);</span>
<span class="n">ws</span><span class="o">.</span><span class="na">whenShutdown</span><span class="o">().</span><span class="na">thenRun</span><span class="o">(()</span>
<span class="o">-></span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"WEB server is DOWN. Good bye!"</span><span class="o">));</span>
<span class="o">})</span>
<span class="o">.</span><span class="na">exceptionally</span><span class="o">(</span><span class="n">t</span> <span class="o">-></span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">err</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Startup failed: "</span> <span class="o">+</span> <span class="n">t</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
<span class="n">t</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">(</span><span class="nc">System</span><span class="o">.</span><span class="na">err</span><span class="o">);</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">});</span>
</code></pre></div></div>
<p>Here, an attempt is made to start the server and we provide handlers to the outcome of this action. These handlers are passed as lambda functions to the respective results of success and error: <code class="language-plaintext highlighter-rouge">thenAccept</code> and <code class="language-plaintext highlighter-rouge">exceptionally</code>.</p>
<h2 id="adding-another-service">Adding another service</h2>
<p>Up to this point, we have explored out-of-the-box capabilities that Helidon SE offers, and have seen a fraction of its programming model.</p>
<p>It’s natural to add another service to this package so we see how it responds to our needs.</p>
<p>Now, the building block of adding another service is implementing the <code class="language-plaintext highlighter-rouge">Service</code> interface, located in the <code class="language-plaintext highlighter-rouge">io.helidon.webserver</code> namespace.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MovieService</span> <span class="kd">implements</span> <span class="nc">Service</span> <span class="o">{</span> <span class="o">}</span>
</code></pre></div></div>
<p>This is a functional interface, with a single abstract method, called <code class="language-plaintext highlighter-rouge">update</code>.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@FunctionalInterface</span>
<span class="kd">public</span> <span class="kd">interface</span> <span class="nc">Service</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">update</span><span class="o">(</span><span class="nc">Rules</span> <span class="n">var1</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This offers the possibility of adding a one line imlpementation of a service, if fit.</p>
<p>For example, adding a new route would be as easy as:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">return</span> <span class="nc">Routing</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="c1">//...</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/greet"</span><span class="o">,</span> <span class="n">greetService</span><span class="o">)</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/inline"</span><span class="o">,</span> <span class="n">rules</span> <span class="o">-></span> <span class="n">rules</span><span class="o">.</span><span class="na">get</span><span class="o">((</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">)</span> <span class="o">-></span> <span class="n">response</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="s">"Hello world"</span><span class="o">)))</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<p>Performing a GET request on this route will return the requested message.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/inline
Hello world
</code></pre></div></div>
<p>This is not the case for services with some more specialized application logic, and rich processing needs, but it is good to know that you can write code in this model for simple things.</p>
<p>A better-suited implementation for most cases would be the continuation of the <code class="language-plaintext highlighter-rouge">MovieService</code> class.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">update</span><span class="o">(</span><span class="nc">Routing</span><span class="o">.</span><span class="na">Rules</span> <span class="n">rules</span><span class="o">)</span> <span class="o">{</span>
<span class="n">rules</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/list"</span><span class="o">,</span> <span class="k">this</span><span class="o">.</span><span class="na">getListHandler</span><span class="o">())</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/test"</span><span class="o">,</span> <span class="k">this</span><span class="o">.</span><span class="na">getTestHandler</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The second argument to the <code class="language-plaintext highlighter-rouge">get</code> method is a <code class="language-plaintext highlighter-rouge">Handler</code> interface implementation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="nc">Handler</span> <span class="nf">getListHandler</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">)</span> <span class="o">-></span> <span class="n">response</span><span class="o">.</span><span class="na">send</span><span class="o">(</span>
<span class="no">JSON</span><span class="o">.</span><span class="na">createArrayBuilder</span><span class="o">(</span>
<span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Batman"</span><span class="o">,</span> <span class="s">"Man of Steel"</span><span class="o">,</span> <span class="s">"Shrek"</span><span class="o">))</span>
<span class="o">.</span><span class="na">build</span><span class="o">()</span>
<span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Let’s set this service up:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">MovieService</span> <span class="n">movieService</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MovieService</span><span class="o">();</span>
<span class="k">return</span> <span class="nc">Routing</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="c1">//...</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/movies"</span><span class="o">,</span> <span class="n">movieService</span><span class="o">)</span>
<span class="o">.</span><span class="na">build</span><span class="o">()</span>
</code></pre></div></div>
<p>Quick testing follows.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/test
<span class="o">{</span><span class="s2">"message"</span>:<span class="s2">"test"</span><span class="o">}</span>
</code></pre></div></div>
<p>For a more serious movie-goers experience, test the endpoint containing the list of movies.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list
<span class="o">[</span><span class="s2">"Batman"</span>,<span class="s2">"Man of Steel"</span>,<span class="s2">"Shrek"</span><span class="o">]</span>
</code></pre></div></div>
<p>In this example, services proved to be an effective way of of organizing route configuration code and adding multiple methods for a route in a single point of access, the service implementation class.</p>
<h3 id="revisiting-the-inline-service">Revisiting the inline service</h3>
<p>In the example above, of writing an inline service for the routing builder, you can swap service registration with specific handler for method.</p>
<p>For example, <code class="language-plaintext highlighter-rouge">register</code> would become <code class="language-plaintext highlighter-rouge">get</code> and the Service implementation would become a Handler implementation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">return</span> <span class="nc">Routing</span><span class="o">.</span><span class="na">builder</span><span class="o">()</span>
<span class="c1">//...</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/greet"</span><span class="o">,</span> <span class="n">greetService</span><span class="o">)</span>
<span class="o">.</span><span class="na">register</span><span class="o">(</span><span class="s">"/movies"</span><span class="o">,</span> <span class="n">movieService</span><span class="o">)</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/inline"</span><span class="o">,</span> <span class="o">(</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">)</span> <span class="o">-></span> <span class="n">response</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="s">"Hello world"</span><span class="o">))</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<p>This is a little bit more convinient, regarding the inline route configuration experience.</p>
<h2 id="a-potential-downside">A potential downside</h2>
<p>Our code example seems like a move away from the simplicity of automatic JSON transformations that other libraries like Spring REST or JAX-RS provide. This is due to the fact that we have added support for JSONP, which requires the converters such as <code class="language-plaintext highlighter-rouge">JsonObject</code> and <code class="language-plaintext highlighter-rouge">JsonArray</code>.</p>
<p>After digging a bit, it seems that this issue is resolved after Helidon added support for Jackson. To add this feature into the project, we’d have to include this module in our maven pom file.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>io.helidon.media<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>helidon-media-jackson<span class="nt"></artifactId></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>Remember when we declared JsonP support in the web server creation? We’d have to change that now to JacksonSupport.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">WebServer</span> <span class="n">server</span> <span class="o">=</span> <span class="nc">WebServer</span><span class="o">.</span><span class="na">builder</span><span class="o">(</span><span class="n">createRouting</span><span class="o">(</span><span class="n">config</span><span class="o">))</span>
<span class="o">.</span><span class="na">config</span><span class="o">(</span><span class="n">config</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"server"</span><span class="o">))</span>
<span class="o">.</span><span class="na">addMediaSupport</span><span class="o">(</span><span class="nc">JacksonSupport</span><span class="o">.</span><span class="na">create</span><span class="o">())</span>
<span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>
<p>That’s supposed to be enough for us to remove the Jsonp wrappers from our Movie service class.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="nc">Handler</span> <span class="nf">getListHandler</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="o">(</span><span class="n">request</span><span class="o">,</span> <span class="n">response</span><span class="o">)</span> <span class="o">-></span> <span class="n">response</span><span class="o">.</span><span class="na">send</span><span class="o">(</span><span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Batman"</span><span class="o">,</span> <span class="s">"Man of Steel"</span><span class="o">,</span> <span class="s">"Shrek"</span><span class="o">));</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Let’s check if the issue is resolved.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list
<span class="o">[</span><span class="s2">"Batman"</span>,<span class="s2">"Man of Steel"</span>,<span class="s2">"Shrek"</span><span class="o">]</span>
</code></pre></div></div>
<p>It was simple as that. This brings the data transformation on par with the other players’ simplicity, keeping the functional lightweight touch that Helidon adds.</p>
<p>To make it more json-object-y like, we would create a Movie class, which would make a great record, one Jackson fully supports them.</p>
<p>After that the repose would be like:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list
<span class="o">[</span>
<span class="o">{</span>
<span class="s2">"title"</span>: <span class="s2">"The Dark Knight"</span>,
<span class="s2">"year"</span>: 2006
<span class="o">}</span>,
<span class="o">{</span>
<span class="s2">"title"</span>: <span class="s2">"Man of Steel"</span>,
<span class="s2">"year"</span>: 2011
<span class="o">}</span>,
<span class="o">{</span>
<span class="s2">"title"</span>: <span class="s2">"Shrek"</span>,
<span class="s2">"year"</span>: 2003
<span class="o">}</span>
<span class="o">]</span>
</code></pre></div></div>
<h2 id="error-handling">Error Handling</h2>
<p>What happens if the movies are not available? Let’s say the database is down and you cannot get your movies data (oh no), how do you let the consumer of your API know about it?</p>
<p>I’m gonna add a flawed request for this purpose.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rules</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/list"</span><span class="o">,</span> <span class="k">this</span><span class="o">.</span><span class="na">getListHandler</span><span class="o">())</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/list/flawed"</span><span class="o">,</span> <span class="k">this</span><span class="o">::</span><span class="n">getFlawedList</span><span class="o">)</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/test"</span><span class="o">,</span> <span class="k">this</span><span class="o">.</span><span class="na">getTestHandler</span><span class="o">());</span>
</code></pre></div></div>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kt">void</span> <span class="nf">getFlawedList</span><span class="o">(</span><span class="nc">ServerRequest</span> <span class="n">request</span><span class="o">,</span> <span class="nc">ServerResponse</span> <span class="n">response</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">UnsupportedOperationException</span><span class="o">(</span><span class="s">"Sorry movies are closed"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Let’s take the server for a spin and see what hapens.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list/flawed
value cannot be null!
</code></pre></div></div>
<p>This message hardly helps anyone understand what has happened, beyond the fact that something has made our server angry.</p>
<p>Checking the logs, this comes down to the fact that the response cannot be null. Simply adding a message to the exception, and re-performing the GET request, you would get the following response:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list/flawed
Sorry movies are closed
</code></pre></div></div>
<p>This is a more readable message, automatically transformed from the thrown exception to the json response, but the logs still pop up an important warning:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mf">2020.09</span><span class="o">.</span><span class="mi">22</span> <span class="mo">01</span><span class="o">:</span><span class="mo">04</span><span class="o">:</span><span class="mi">44</span> <span class="no">WARNING</span> <span class="n">io</span><span class="o">.</span><span class="na">helidon</span><span class="o">.</span><span class="na">webserver</span><span class="o">.</span><span class="na">RequestRouting</span> <span class="nc">Thread</span><span class="o">[</span><span class="n">nioEventLoopGroup</span><span class="o">-</span><span class="mi">3</span><span class="o">-</span><span class="mi">1</span><span class="o">,</span><span class="mi">10</span><span class="o">,</span><span class="n">main</span><span class="o">]:</span> <span class="nc">Default</span> <span class="n">error</span> <span class="nl">handler:</span> <span class="nc">Unhandled</span> <span class="n">exception</span> <span class="n">encountered</span><span class="o">.</span>
<span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">concurrent</span><span class="o">.</span><span class="na">ExecutionException</span><span class="o">:</span> <span class="nc">Unhandled</span> <span class="err">'</span><span class="n">cause</span><span class="err">'</span> <span class="n">of</span> <span class="k">this</span> <span class="n">exception</span> <span class="n">encountered</span><span class="o">.</span>
</code></pre></div></div>
<p>This lets us know that there no handler for this exception that has occurred. Going back to the pattern that Helidon follows, we’re going to extend our method with a failure handler.</p>
<p>To do that, I will set up a method that has the original purpose to supply a CompleteableFuture, but in this case it will fail.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="nc">CompletableFuture</span><span class="o"><</span><span class="nc">List</span><span class="o"><</span><span class="nc">Movie</span><span class="o">>></span> <span class="nf">getFlawedList</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nc">CompletableFuture</span><span class="o">.</span><span class="na">failedFuture</span><span class="o">(</span><span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="s">"Sorry movies are closed"</span><span class="o">));</span>
<span class="o">}</span>
</code></pre></div></div>
<p>And I am going to make sense of this exception.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">private</span> <span class="kt">void</span> <span class="nf">getFlawedListHandler</span><span class="o">(</span><span class="nc">ServerRequest</span> <span class="n">request</span><span class="o">,</span> <span class="nc">ServerResponse</span> <span class="n">response</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">getFlawedList</span><span class="o">()</span>
<span class="o">.</span><span class="na">thenAccept</span><span class="o">(</span><span class="nl">response:</span><span class="o">:</span><span class="n">send</span><span class="o">)</span>
<span class="o">.</span><span class="na">exceptionally</span><span class="o">(</span><span class="n">error</span> <span class="o">-></span> <span class="o">{</span>
<span class="n">response</span><span class="o">.</span><span class="na">status</span><span class="o">(</span><span class="nc">Http</span><span class="o">.</span><span class="na">Status</span><span class="o">.</span><span class="na">NOT_FOUND_404</span><span class="o">);</span>
<span class="n">response</span><span class="o">.</span><span class="na">send</span><span class="o">(</span>
<span class="k">new</span> <span class="nf">MovieNotFound</span><span class="o">(</span><span class="s">"Could not get movies"</span><span class="o">,</span> <span class="nc">LocalDateTime</span><span class="o">.</span><span class="na">now</span><span class="o">().</span><span class="na">toString</span><span class="o">())</span>
<span class="o">);</span>
<span class="k">return</span> <span class="kc">null</span><span class="o">;</span>
<span class="o">});</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Then update the rules with this route.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rules</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/list"</span><span class="o">,</span> <span class="k">this</span><span class="o">::</span><span class="n">getListHandler</span><span class="o">)</span>
<span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"/list/flawed"</span><span class="o">,</span> <span class="k">this</span><span class="o">::</span><span class="n">getFlawedListHandler</span><span class="o">)</span>
</code></pre></div></div>
<p>If the completeableFuture is successful, this will trigger the <code class="language-plaintext highlighter-rouge">thenAccept</code> block and perform that action, in this case directly send the response. In case an exception occurs on the way, the <code class="language-plaintext highlighter-rouge">exceptionally</code> block will catch it and make something out of it. What we do here is set a custom response status code, and return send a custom error message with the response.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>curl <span class="nt">-X</span> GET http://localhost:8080/movies/list/flawed
<span class="o">{</span>
<span class="s2">"message"</span>: <span class="s2">"Could not get movies"</span>,
<span class="s2">"incidentTime"</span>: <span class="s2">"2020-09-22T21:43:51.347416"</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">thenAccept</code> block could be expanded further to set response status based on the data returned by the completeableFuture, such as <code class="language-plaintext highlighter-rouge">NOT_FOUND</code> in case of empty list or perform other mappings.</p>
<h2 id="what-to-take-out-of-it">What to take out of it</h2>
<p>In this post I’ve taken a quick look to the web server component of Helidon SE. It offers a nice way of setting routes and services up.</p>
<p>If one were to explore other included components such as metrics and health, could do so by accessing the <code class="language-plaintext highlighter-rouge">/metrics</code> and <code class="language-plaintext highlighter-rouge">/health</code> endpoints.</p>
<p>I did not include examples for reactive db client support. That seems like the approach Spring Data takes with r2dbc. As far as I know, reactive mongodb client is supported, and traditional jdbc drivers are supported inside a wrapper.</p>
<p>The Helidon SE flavor it is indeed a move away from the Helidon MP flavor. It is even more micro than that, and takes an event-driven approach. In my opinion, it’s a viable option for doing simple things fast, once you get used a little bit to its programming model.</p>
<p>If you take a look at the bigger scheme of things, there are odds that Helidon SE will co-exist with Micronaut framework in the future. What makes me believe this is Graeme Rocher, the creator of Micronaut joining <a href="https://twitter.com/graemerocher/status/1278770836996886528" target="_blank">Oracle</a>, and statements like <a href="https://twitter.com/graemerocher/status/1286398505922297856" target="_blank">this</a>. The future is exciting.</p>
<p><em>Source code is on <a href="https://github.com/albihasani94/helidon-se">Github</a></em></p>Albin HasaniIn this follow-up to the Helidon MP post, I’m going to explore the other Helidon sibling: Helidon SE.Helidon MP, child of Java EE and the Cloud2020-06-10T00:00:00+00:002020-06-10T00:00:00+00:00https://www.albinhasani.net/helidon-mp<p>What is Helidon? Turning to etymology, Helidon comes from Greece and it means the <em>swallow</em> bird in English.</p>
<!--more-->
<p>According to the Cambridge Dictionary, <a href="https://dictionary.cambridge.org/dictionary/english/swallow" target="_blank">swallow</a> is a small bird with pointed wings and a tail with two points that flies quickly and catches insects to eat as it flies.</p>
<p><img src="/assets/images/swallow_noun.jpg" alt="helidon-bird" /></p>
<p>Oracle nailed it getting the coolest name for a tech framework. You’ve most likely seen this kind of bird at least once, and of course, it is dallëndyshe in Albanian.</p>
<p>Let’s head to the motivation behind this framework and the purpose it holds, as it takes flight.</p>
<p>Now as it is common with birds, there are many families. And Helidon comes in two shapes, Helidon SE and Helidon MP.</p>
<p>Helidon SE embraces the latest Java SE features: reactive streams, asynchronous and functional programming, and fluent-style APIs. At the same time, Helidon MP provides an implementation of the MicroProfile specification. This is the child of Java EE and the cloud.</p>
<p>Helidon SE seems to be the coolest of the siblings, but both look like a step in the right direction to me.</p>
<p>With this post, I am going to give a try to the Helidon MP. I am going to start with the Helidon v2, which requires Maven 3.6.1+ and JDK 11 or newer.</p>
<h2 id="preparing-the-ground">Preparing the Ground</h2>
<p>There is a proper way to start with it, by using a maven archetype.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn archetype:generate <span class="nt">-DinteractiveMode</span><span class="o">=</span><span class="nb">false</span> <span class="se">\</span>
<span class="nt">-DarchetypeGroupId</span><span class="o">=</span>io.helidon.archetypes <span class="se">\</span>
<span class="nt">-DarchetypeArtifactId</span><span class="o">=</span>helidon-quickstart-mp <span class="se">\</span>
<span class="nt">-DarchetypeVersion</span><span class="o">=</span>2.0.0-RC1 <span class="se">\</span>
<span class="nt">-DgroupId</span><span class="o">=</span>com.albi <span class="se">\</span>
<span class="nt">-DartifactId</span><span class="o">=</span>helidon-mp <span class="se">\</span>
<span class="nt">-Dpackage</span><span class="o">=</span>com.albi.helidon.mp
</code></pre></div></div>
<p>By navigating to the project, we see that the directory has the following structure:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">.</span>
├── Dockerfile
├── Dockerfile.jlink
├── Dockerfile.native
├── README.md
├── app.yaml
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── albi
│ │ └── helidon
│ │ └── mp
│ │ ├── GreetResource.java
│ │ ├── GreetingProvider.java
│ │ ├── ReactiveService.java
│ │ └── package-info.java
│ └── resources
│ ├── META-INF
│ │ ├── beans.xml
│ │ └── microprofile-config.properties
│ └── logging.properties
└── <span class="nb">test</span>
├── java
│ └── com
│ └── albi
│ └── helidon
│ └── mp
│ └── MainTest.java
└── resources
└── META-INF
└── microprofile-config.properties
</code></pre></div></div>
<p>That’s neat. And there is some code for us. We will look at it shortly.</p>
<p>We build the application:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package
</code></pre></div></div>
<p>As the build tool fetches the dependencies, runs some tests, we will be set.</p>
<h2 id="lets-run-fly">Let’s <del>run</del> fly</h2>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java <span class="nt">-jar</span> target/helidon-mp.jar
</code></pre></div></div>
<p>Well, that was.. like pretty fast. Let’s see what we got here.</p>
<p>Either via curl or Postman (or <a href="https://insomnia.rest/" target="_blank">Insomnia</a>):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -X GET http://localhost:8080/greet
</code></pre></div></div>
<p>The response is on point:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"message": "Hello World!"
}
</code></pre></div></div>
<p>Try another one</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -X GET http://localhost:8080/greet/Helidon
</code></pre></div></div>
<p>Response</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"message": "Hello Helidon!"
}
</code></pre></div></div>
<p>GET requests are easy. We all know what’s tricky. PUT requests. Make the computer listen from your input.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -X PUT -H "Content-Type: application/json" -d \
'{"greeting" : "Aloha"}' http://localhost:8080/greet/greeting
</code></pre></div></div>
<p>This request has no response body. It could return the updated greeting in my opinion.</p>
<p>Now we’ve changed the greeting. Let’s greet someone cool, like <a href="https://en.wikipedia.org/wiki/Stitch_(Disney)" target="_blank">Stitch</a>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -X GET http://localhost:8080/greet/Stitch
</code></pre></div></div>
<p>Response</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"message": "Aloha Stitch!"
}
</code></pre></div></div>
<p>The way it works just of the box is impressive. No hand-written dependencies, no setup, and no application server!</p>
<p>Let’s see what we had there to start with in more detail.</p>
<h2 id="show-me-the-code">Show me the code</h2>
<p>The bits of application logic provided to us free of charge or any pain are in the following source files.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>── mp
├── GreetResource.java
├── GreetingProvider.java
└── ReactiveService.java
</code></pre></div></div>
<p>We’re going to see the main picture without focusing too much on the methods.</p>
<p>First goes the GreetResource:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Path</span><span class="o">(</span><span class="s">"/greet"</span><span class="o">)</span>
<span class="nd">@RequestScoped</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">GreetResource</span> <span class="o">{</span>
<span class="nd">@Inject</span>
<span class="nc">GreetingProvider</span> <span class="n">greetingProvider</span><span class="o">;</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"/{name}"</span><span class="o">)</span>
<span class="nd">@GET</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">JsonObject</span> <span class="nf">getMessage</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">"name"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">createResponse</span><span class="o">(</span><span class="n">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// add other paths and methods</span>
</code></pre></div></div>
<p>This is a JAX-RS application. Java EE is dead. Long live Jakarta EE!</p>
<p>Then comes the GreetingProvider:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@ApplicationScoped</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">GreetingProvider</span> <span class="o">{</span>
<span class="kd">private</span> <span class="kd">final</span> <span class="nc">AtomicReference</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">message</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AtomicReference</span><span class="o"><>();</span>
<span class="nd">@Inject</span>
<span class="kd">public</span> <span class="nf">GreetingProvider</span><span class="o">(</span><span class="nd">@ConfigProperty</span><span class="o">(</span><span class="n">name</span> <span class="o">=</span> <span class="s">"app.greeting"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">message</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// getter and setter</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This is a CDI bean. It acts as a provider for the GreetResource, in which it has been injected. The <code class="language-plaintext highlighter-rouge">@ConfigProperty</code> annotation injects an application property into the source code.
This feature is part of the <a href="https://www.tomitribe.com/blog/an-overview-of-microprofile-configuration/" target="_blank">MicroProfile Configuration</a> API.</p>
<h2 id="checking-the-gears">Checking the gears</h2>
<p>Taking a look for a minute at the <code class="language-plaintext highlighter-rouge">resources</code> folder reveals some configuration properties.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>── resources
├── META-INF
│ ├── beans.xml
│ └── microprofile-config.properties
└── logging.properties
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">beans.xml</code> belongs to the CDI specification and is used to enable CDI services. By default, annotated beans are considered for dependency injection.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bean-discovery-mode="annotated"
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">microprofile-config.properties</code> can hold application properties and microprofile server properties, e.g. port.</p>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Application properties. This is the default greeting
</span><span class="py">app.greeting</span><span class="p">=</span><span class="s">Hello</span>
<span class="c"># Microprofile server properties
</span><span class="py">server.port</span><span class="p">=</span><span class="s">8080</span>
</code></pre></div></div>
<p>And the logging configuration can be tuned in <code class="language-plaintext highlighter-rouge">logging.properties</code>, as the name suggests.</p>
<h2 id="inspecting-over-the-nest">Inspecting over the nest</h2>
<p>If we take a look at the <code class="language-plaintext highlighter-rouge">target</code> directory, where our build is created, we’re in for interesting stuff.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">du</span> <span class="nt">-sh</span> target/<span class="k">*</span>
28K target/classes
0B target/generated-sources
0B target/generated-test-sources
12K target/helidon-mp.jar
18M target/libs
4.0K target/maven-archiver
16K target/maven-status
12K target/surefire-reports
8.0K target/test-classes
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">jar</code> where our application logic resides is only <code class="language-plaintext highlighter-rouge">12 KBytes</code>. That’s crazy, even beyond java standards.</p>
<p>The actual reason for that is that application dependencies lie in the <code class="language-plaintext highlighter-rouge">libs</code> folder. This is a very intuitive decision.</p>
<p>Build-wise, it allows docker builds to be faster by only doing a rebuild of your application rather than having to build runtime dependencies into the jar, hence the cloud-native part.</p>
<p>Secondly, but no less important, there is a clear separation between the business logic and the libraries, as it should be.</p>
<h2 id="adding-datasource-to-the-mix">Adding DataSource to the mix</h2>
<p>Add dependencies.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>com.h2database<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>h2<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.4.199<span class="nt"></version></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>io.helidon.integrations.cdi<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>helidon-integrations-cdi-datasource-hikaricp<span class="nt"></artifactId></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>Add db connection properties.</p>
<div class="language-properties highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">javax.sql.DataSource.test.dataSourceClassName</span><span class="p">=</span><span class="s">org.h2.jdbcx.JdbcDataSource</span>
<span class="py">javax.sql.DataSource.test.dataSource.url</span><span class="p">=</span><span class="s">jdbc:h2:mem:test</span>
<span class="py">javax.sql.DataSource.test.dataSource.user</span><span class="p">=</span><span class="s">sa</span>
<span class="py">javax.sql.DataSource.test.dataSource.password</span><span class="p">=</span>
</code></pre></div></div>
<p>Interacting with the db is straightforward.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Path</span><span class="o">(</span><span class="s">"/ds"</span><span class="o">)</span>
<span class="nd">@ApplicationScoped</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DataSourceExample</span> <span class="o">{</span>
<span class="nd">@Inject</span>
<span class="nd">@Named</span><span class="o">(</span><span class="s">"test"</span><span class="o">)</span>
<span class="kd">private</span> <span class="nc">DataSource</span> <span class="n">testDataSource</span><span class="o">;</span>
<span class="nd">@GET</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"tables"</span><span class="o">)</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="s">"text/plain"</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getTableNames</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">SQLException</span> <span class="o">{</span>
<span class="nc">StringBuilder</span> <span class="n">sb</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">();</span>
<span class="k">try</span> <span class="o">(</span><span class="nc">Connection</span> <span class="n">connection</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">testDataSource</span><span class="o">.</span><span class="na">getConnection</span><span class="o">();</span>
<span class="nc">PreparedStatement</span> <span class="n">ps</span> <span class="o">=</span>
<span class="n">connection</span><span class="o">.</span><span class="na">prepareStatement</span><span class="o">(</span><span class="s">" SELECT TABLE_NAME"</span>
<span class="o">+</span> <span class="s">" FROM INFORMATION_SCHEMA.TABLES "</span>
<span class="o">+</span> <span class="s">"ORDER BY TABLE_NAME ASC"</span><span class="o">);</span>
<span class="nc">ResultSet</span> <span class="n">rs</span> <span class="o">=</span> <span class="n">ps</span><span class="o">.</span><span class="na">executeQuery</span><span class="o">())</span> <span class="o">{</span>
<span class="k">while</span> <span class="o">(</span><span class="n">rs</span><span class="o">.</span><span class="na">next</span><span class="o">())</span> <span class="o">{</span>
<span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">rs</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="mi">1</span><span class="o">)).</span><span class="na">append</span><span class="o">(</span><span class="s">"\n"</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">return</span> <span class="n">sb</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Reaching the endpoint.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET http://localhost:8080/ds/tables
</code></pre></div></div>
<p>This will fetch and display table names for the information schema in H2 database.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CATALOGS
COLLATIONS
COLUMNS
...
USERS
VIEWS
</code></pre></div></div>
<h2 id="adding-persistence">Adding persistence</h2>
<p>I have added persistence to my demo application, but it is nothing more than this <a href="https://medium.com/helidon/helidon-and-jpa-da20492f5395" target="_blank">post</a> I came across. I recommend reading it if you want to take a look at JPA integration.</p>
<p>Now what I want to put an emphasis on is that even after adding datasource and jpa integration to my application, the jar size is impressively small.</p>
<p>There is a bump on the application jar of only from 12KB to 20KB. As expected, the <code class="language-plaintext highlighter-rouge">libs</code> folder has gotten bigger, from 18MB to 31MB.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">du</span> <span class="nt">-sh</span> target/helidon-mp.jar target/libs/
20K target/helidon-mp.jar
31M target/libs/
</code></pre></div></div>
<h2 id="openapi">OpenAPI</h2>
<p>Helidon flies smoothly together with the MicroProfile OpenAPI specification. It provides an implementation to this specification, which is much appreciated.</p>
<p>Naturally, you would want to add these dependencies on your <code class="language-plaintext highlighter-rouge">pom.xml</code>. In this quickstart, these seem to be pulled from the <code class="language-plaintext highlighter-rouge">helidon-microprofile</code> artifact.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.eclipse.microprofile.openapi<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>microprofile-openapi-api<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.1.2<span class="nt"></version></span>
<span class="nt"></dependency></span>
<span class="nt"><dependency></span>
<span class="nt"><groupId></span>io.helidon.microprofile.openapi<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>helidon-microprofile-openapi<span class="nt"></artifactId></span>
<span class="nt"><version></span>2.0.0-RC1<span class="nt"></version></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>Let’s write some API documentation.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GET</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">"withSalutation/{salutation}"</span><span class="o">)</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="s">"text/plain"</span><span class="o">)</span>
<span class="nd">@Operation</span><span class="o">(</span><span class="n">summary</span> <span class="o">=</span> <span class="s">"Returns a greeting"</span><span class="o">,</span> <span class="n">description</span> <span class="o">=</span> <span class="s">"Returns a greeting for the given salutation"</span><span class="o">)</span>
<span class="nd">@APIResponse</span><span class="o">(</span><span class="n">description</span> <span class="o">=</span> <span class="s">"Text containing the greeting"</span><span class="o">,</span>
<span class="n">content</span> <span class="o">=</span> <span class="nd">@Content</span><span class="o">(</span><span class="n">mediaType</span> <span class="o">=</span> <span class="nc">MediaType</span><span class="o">.</span><span class="na">TEXT_PLAIN</span><span class="o">,</span> <span class="n">schema</span> <span class="o">=</span> <span class="nd">@Schema</span><span class="o">(</span><span class="n">implementation</span> <span class="o">=</span> <span class="nc">Greeting</span><span class="o">.</span><span class="na">class</span><span class="o">)))</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">getResponse</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">"salutation"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">salutation</span><span class="o">)</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">greetingService</span><span class="o">.</span><span class="na">findBySalutation</span><span class="o">(</span><span class="n">salutation</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>With the <code class="language-plaintext highlighter-rouge">@Operation</code> and <code class="language-plaintext highlighter-rouge">@APIResponse</code> we have just documented this method.</p>
<p>Now, when the application starts, we can reach the <code class="language-plaintext highlighter-rouge">/openapi</code> endpoint and the application will serve us an <code class="language-plaintext highlighter-rouge">openapi.yaml</code> file with this API’s OpenAPI specification.</p>
<p>We can import this file to our API development tool and it will create the endpoints for testing.</p>
<p>To make things a little bit more user friendly, we can add a touch of Swagger UI.</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><dependency></span>
<span class="nt"><groupId></span>org.microprofile-ext.openapi-ext<span class="nt"></groupId></span>
<span class="nt"><artifactId></span>openapi-ui<span class="nt"></artifactId></span>
<span class="nt"><version></span>1.1.4<span class="nt"></version></span>
<span class="nt"><scope></span>runtime<span class="nt"></scope></span>
<span class="nt"></dependency></span>
</code></pre></div></div>
<p>On our browser, by navigating to <code class="language-plaintext highlighter-rouge">http://localhost:8080/openapi-ui</code> a familiar taste welcomes us.</p>
<p><img src="/assets/images/openapi-ui.png" alt="openapi-ui" /></p>
<h2 id="sailing-with-docker">Sailing with Docker</h2>
<p>To explore a bit of the cloud native side of Helidon, we would start with <code class="language-plaintext highlighter-rouge">docker</code>.</p>
<p>The quickstart provides a <code class="language-plaintext highlighter-rouge">Dockerfile</code> to make things smoother. What is there for us to do?</p>
<p>Build the image.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker build <span class="nt">-t</span> helidon-mp <span class="nb">.</span>
</code></pre></div></div>
<p>I seemed to never get this command working. To get it right, I had to take some notes on static weaving and one of the Helidon creators on Slack pointed me to a solution.
The problem is that, when configuring the JPA integration, we enabled static weaving.</p>
<p>Heading to EclipseLink <a href="https://www.eclipse.org/eclipselink/documentation/2.7/concepts/app_dev005.htm#CCHJEDFH" target="_blank">documentation</a>: “Weaving is a technique of manipulating the byte-code of compiled Java classes. The EclipseLink JPA persistence provider uses weaving to enhance both JPA entities and Plain Old Java Object (POJO) classes for such things as lazy loading, change tracking, fetch groups, and internal optimizations.”</p>
<p>So, weaving can be done dynamically at runtime, or statically at build time. Helidon does not support dynamic weaving, as it tends to embrace the lightweight option between the two. This is obviously a performance-wise decision.</p>
<h3 id="what-does-this-have-to-do-with-the-docker-build">What does this have to do with the docker build?</h3>
<p>If we see carefully the <code class="language-plaintext highlighter-rouge">Dockerfile</code>, there are two <code class="language-plaintext highlighter-rouge">mvn</code> invocations in the build.</p>
<div class="language-Dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Create a first layer to cache the "Maven World" in the local repository.</span>
<span class="c"># Incremental docker builds will always resume after that, unless you update</span>
<span class="c"># the pom</span>
<span class="k">ADD</span><span class="s"> pom.xml .</span>
<span class="k">RUN </span>mvn package <span class="nt">-DskipTests</span>
<span class="c"># Do the Maven build!</span>
<span class="c"># Incremental docker builds will resume here when you change sources</span>
<span class="k">ADD</span><span class="s"> src src</span>
<span class="k">RUN </span>mvn package <span class="nt">-DskipTests</span>
</code></pre></div></div>
<p>The first invocation pulls the dependencies layer separately from the second invocation which builds the application layer.
For the first invocation, there is no build. No build means no target folder output. When the eclipselink plugin runs, it attempts to perform weaving on the classes produced by mvn command. Since there is no target folder, this fails and I would get this message:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>ERROR] Failed to execute goal
com.ethlo.persistence.tools:eclipselink-maven-plugin:2.7.5.1:weave
<span class="o">(</span>weave<span class="o">)</span> on project helidon-mp:
Source directory /helidon/target/classes does not exist -> <span class="o">[</span>Help 1]
</code></pre></div></div>
<p>Luckily, there is a flag to prevent the plugin from running in the first command.</p>
<div class="language-Dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">RUN </span>mvn package <span class="nt">-DskipTests</span> <span class="nt">-Declipselink</span>.weave.skip<span class="o">=</span><span class="nb">true</span>
</code></pre></div></div>
<p>This fixed the build for me. To prevent it from happening to new users, I would suggest either adding the option beforehand in the quickstart-archetype’s Dockerfile or document the necessity of its usage in the JPA section in the documentation. That’s up for discussion.</p>
<h4 id="sail">Sail</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run <span class="nt">--rm</span> <span class="nt">-p</span> 8080:8080 helidon-mp:latest
</code></pre></div></div>
<h4 id="voila">Voila</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2020.06.09 20:36:13 INFO io.helidon.microprofile.server.ServerCdiExtension
Thread[main,5,main]: Server started on http://localhost:8080
<span class="o">(</span>and all other host addresses<span class="o">)</span> <span class="k">in </span>4619 milliseconds <span class="o">(</span>since JVM startup<span class="o">)</span><span class="nb">.</span>
</code></pre></div></div>
<p>For some reason, the docker image starts up even faster than my local installation. Only <code class="language-plaintext highlighter-rouge">4619 ms</code>, and that’s for an application with JAX-RS, CDI, JPA, OpenAPI, Config, Health, and Metrics.</p>
<p>Let’s do a change in the code and rebuild the image to see how the building process changes. I am changing the default message to something more classy.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@GET</span>
<span class="nd">@Produces</span><span class="o">(</span><span class="nc">MediaType</span><span class="o">.</span><span class="na">APPLICATION_JSON</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">JsonObject</span> <span class="nf">getDefaultMessage</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="nf">createResponse</span><span class="o">(</span><span class="s">"Monde"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Now I’m doing a rebuild of the docker image.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker build <span class="nt">-t</span> helidon-mp <span class="nb">.</span>
</code></pre></div></div>
<p>And test it</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET http://localhost:8080/greet
<span class="o">{</span><span class="s2">"message"</span>:<span class="s2">"Hello Monde!"</span><span class="o">}</span>
</code></pre></div></div>
<p>The rebuild process is seamless and it is pretty fast.</p>
<p>Alternatively, we could use <a href="https://github.com/GoogleContainerTools/jib" target="_blank">Jib</a>. That is not the point of this post but I have included an example of that in the source code.</p>
<h2 id="stepping-the-game-up-with-jlink">Stepping the game up with jlink</h2>
<p>Introduced with Java 9, jlink is a tool to assemble and optimize a set of modules and their dependencies into a custom runtime image.</p>
<p>This means creating slimmed down Java Runtimes who provide only the modules of JDK that we know our application might use at some point.</p>
<p>Helidon already ships with its own <code class="language-plaintext highlighter-rouge">helidon-maven-plugin</code> which makes it effortless to create runtime images with jlink.</p>
<p>There is already a profile for us.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package <span class="nt">-Pjlink-image</span>
</code></pre></div></div>
<p>The output looks neat.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>INFO] Java Runtime Image helidon-mp completed <span class="k">in </span>45.1 seconds
<span class="o">[</span>INFO]
<span class="o">[</span>INFO] initial size: 312.7M <span class="o">(</span>279.6 JDK + 33.1 application<span class="o">)</span>
<span class="o">[</span>INFO] image size: 150.7M <span class="o">(</span> 46.5 JDK + 33.1 application + 71.1 CDS<span class="o">)</span>
<span class="o">[</span>INFO] reduction: 51.8%
</code></pre></div></div>
<p>There is runtime reduction from <code class="language-plaintext highlighter-rouge">312.7MB</code> to <code class="language-plaintext highlighter-rouge">150.7MB</code>, only half of it.</p>
<p>The output is the <code class="language-plaintext highlighter-rouge">target/helidon-mp</code> directory which contains both the JDK image and the application with its dependencies.</p>
<p>To start the application</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./target/helidon-mp/bin/start
</code></pre></div></div>
<p>To make the most out of jlink size-reduction, we would create a docker image with the custom runtime image.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker build <span class="nt">-t</span> helidon-mp-jlink <span class="nt">-f</span> Dockerfile.jlink <span class="nb">.</span>
</code></pre></div></div>
<p>On a side note, startup time inside the docker container is also reduced to <code class="language-plaintext highlighter-rouge">3694 ms</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2020.06.10 00:54:10 INFO io.helidon.microprofile.server.ServerCdiExtension
Thread[main,5,main]: Server started on http://localhost:8080
<span class="o">(</span>and all other host addresses<span class="o">)</span> <span class="k">in </span>3694 milliseconds <span class="o">(</span>since JVM startup<span class="o">)</span><span class="nb">.</span>
</code></pre></div></div>
<h2 id="last-but-not-least-graalvm">Last but not least, GraalVM</h2>
<p>The tricky part here is getting GraalVM to work in MacOS Catalina. I cannot document that process, but I can tell you that a subsequent number of keystrokes made it work. This is a known <a href="https://www.graalvm.org/docs/release-notes/known-issues/" target="_blank">issue</a> due to application allowance policy in MacOS 10.15.</p>
<p>After installing GraalVM, and installing <code class="language-plaintext highlighter-rouge">native-image</code>.</p>
<p>Be ready to get your machine fried.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package <span class="nt">-Pnative-image</span>
</code></pre></div></div>
<p>My machine became so hot I had to open my window to give it air support.</p>
<p>After subsequent runs, I still could not get the graalvm build to work. Reading the logs, this was partly due to H2 driver incompatibility from either side, GraalVM or H2. So, work has still to be done in that direction.</p>
<p>To get a taste of GraalVM, I would start to strip down some application features. After removing <code class="language-plaintext highlighter-rouge">datasource</code> and <code class="language-plaintext highlighter-rouge">jpa</code> integration in a separate <a href="https://github.com/albihasani94/helidon-mp-playground/tree/native-image" target="_blank">branch</a>, I was able to get it going.</p>
<p>That doesn’t look so good for production, but the GraalVM support for Helidon MP is still a work in progress so I would expect better interoperability by the end of the year. Helidon SE should fully support GraalVM native images.</p>
<p>Only later I learned that this is known and the <a href="https://github.com/oracle/helidon/issues/716" target="_blank">roadmap</a> for native images with Helidon MP does not yet support <a href="https://github.com/oracle/helidon/issues/1293" target="_blank">JPA and JTA</a> at this time.</p>
<p>The build produces a single executable file, and that’s all you need to run.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>./target/helidon-mp
2020.06.10 12:25:33 INFO io.helidon.microprofile.server.ServerCdiExtension
Thread[main,5,main]: Server started on http://localhost:8080
<span class="o">(</span>and all other host addresses<span class="o">)</span> <span class="k">in </span>68 milliseconds <span class="o">(</span>since JVM startup<span class="o">)</span><span class="nb">.</span>
</code></pre></div></div>
<p>That happened in around <code class="language-plaintext highlighter-rouge">0.06s</code>. The whole application startup. That’s beyond any expectation I had. GraalVM is so fast it is ridiculous.</p>
<p>Let’s see if GraalVM is fooling with us.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-X</span> GET http://localhost:8080/greet/GraalVM
<span class="o">{</span><span class="s2">"message"</span>:<span class="s2">"Hello GraalVM!"</span><span class="o">}</span>
</code></pre></div></div>
<p>It’s unfortunate that I had to miss datasource and jpa integration in my demo, but I don’t have any doubts on whether a full MicroProfile application will work in the future with GraalVM. We’ve got a glimpse into that future and it looks so promising.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In this first part of Helidon series (there has to be at least one another part, Helidon SE), I would take away some considerations.</p>
<p>The architecture of Helidon MP must be a result of some right decisions design-wise. The application jar remained very small during the whole series of changes and I think it’s a good thing to separate application logic from dependencies.</p>
<p>The docker and jlink integration make for some enjoyable image creating process, and you reap the benefits of smaller images and faster startup times.</p>
<p>And oh my, GraalVM is so fast.</p>
<p>This is the first time I’ve taken a serious look at MicroProfile, and it brings back some Java EE memories without having to use an application server at all. I think that developer experience is good with Helidon, the community is very welcoming, and there is a mindset for the lightweight approach and performance that goes into each decision.</p>
<p>The code is out <a href="https://github.com/albihasani94/helidon-mp-playground" target="_blank">there</a>.</p>
<p>On a personal note, it feels refreshing to get to write after such a long time. Since the last time I did Earth has seen a global disease outbreak, the quarantine, <a href="https://www.theguardian.com/world/2020/apr/27/pentagon-releases-three-ufo-videos-taken-by-us-navy-pilots" target="_blank">UFOs</a> were confirmed by the US government, there were massive protests in USA, and they burnt down an <a href="https://twitter.com/officialmcafee/status/1266324846826397699" target="_blank">Arby’s</a>. We have to come together as humans, be kind, and this too shall pass.</p>Albin HasaniWhat is Helidon? Turning to etymology, Helidon comes from Greece and it means the swallow bird in English.Making Space for Pattern Matching2020-02-09T00:00:00+00:002020-02-09T00:00:00+00:00https://www.albinhasani.net/making-space-for-pattern-matching<p>As a Java Developer, the risk of getting used to ceremony is a serious thing. Some people are actively involved in putting this risk into sleep.</p>
<!--more-->
<p>A common theme around Java is its verbosity. More than it takes more lines to model a behaviour, it takes more effort to read this model and translate it into the real-life process that we want to describe.</p>
<p>One of the cases where this becomes a hassle is the classic <code class="language-plaintext highlighter-rouge">instanceof</code> process.</p>
<p>Let’s say we have a shape.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Shape</span> <span class="o">{</span> <span class="o">}</span>
</code></pre></div></div>
<p>And we have three descendants of this class.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Circle</span> <span class="kd">extends</span> <span class="nc">Shape</span> <span class="o">{</span> <span class="o">}</span>
<span class="kd">class</span> <span class="nc">Triangle</span> <span class="kd">extends</span> <span class="nc">Shape</span> <span class="o">{</span> <span class="o">}</span>
<span class="kd">class</span> <span class="nc">Rectangle</span> <span class="kd">extends</span> <span class="nc">Shape</span> <span class="o">{</span> <span class="o">}</span>
</code></pre></div></div>
<p>Let’s put into each shape a distinctive method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">sayIamACircle</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I am a circle"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">sayIamATriangle</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I am a triangle"</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">sayIamARectangle</span><span class="o">()</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"I am a rectangle"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Then we go on to construct three instances of these shapes in our main method.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Shape</span> <span class="n">rectangle</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Rectangle</span><span class="o">();</span>
<span class="nc">Shape</span> <span class="n">circle</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Circle</span><span class="o">();</span>
<span class="nc">Shape</span> <span class="n">triangle</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Triangle</span><span class="o">();</span>
</code></pre></div></div>
<p>Nothing interesting here.</p>
<h2 id="speaking-shapes">Speaking Shapes</h2>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sayYourShape</span><span class="o">(</span><span class="n">triangle</span><span class="o">);</span>
<span class="kt">void</span> <span class="nf">sayYourShape</span><span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span> <span class="o">}</span>
</code></pre></div></div>
<h3 id="what-we-have-to-do">What we have to do</h3>
<blockquote>
<p>Test if an object is a representative of a class</p>
</blockquote>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">sayYourShape</span><span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">shape</span> <span class="k">instanceof</span> <span class="nc">Triangle</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="and-then">And then?</h3>
<blockquote>
<p>Cast the object into a reference of this class</p>
</blockquote>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">sayYourShape</span><span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">shape</span> <span class="k">instanceof</span> <span class="nc">Triangle</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Triangle</span> <span class="n">triangle</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Triangle</span><span class="o">)</span> <span class="n">shape</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="and-theen">And theen?</h3>
<blockquote>
<p>Play with the new reference</p>
</blockquote>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">sayYourShape</span><span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">shape</span> <span class="k">instanceof</span> <span class="nc">Triangle</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Triangle</span> <span class="n">triangle</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Triangle</span><span class="o">)</span> <span class="n">shape</span><span class="o">;</span>
<span class="n">triangle</span><span class="o">.</span><span class="na">sayIamATriangle</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<h3 id="and-theeen">And theeen?</h3>
<blockquote>
<p>No and then. No and theen.. No and theeen…</p>
</blockquote>
<p><img src="https://media.giphy.com/media/bzaEWi1Z1xzby/giphy.gif" alt="No and then!" /></p>
<p>It is already too much to handle. You have the object, then you test if it is an instance of a class, then even with this information you have to cast the object into the exact reference you know this object is an instance of. This never made too much sense, or at least wasn’t fun to write.</p>
<p>Other languages, and more recently C#, have added a pattern matching feature. This feature, built in the language, paves the way to cleaner control flow statements.</p>
<p>Let’s go back to our speaking circles.</p>
<h2 id="look-whos-speaking">Look who’s speaking</h2>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">sayYourShapeImproved</span><span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">shape</span> <span class="k">instanceof</span> <span class="nc">Triangle</span> <span class="n">triangle</span><span class="o">)</span> <span class="o">{</span>
<span class="n">triangle</span><span class="o">.</span><span class="na">sayIamATriangle</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The ceremony. Gone. Puff. Let that sink in for a moment.</p>
<p>This code is immediately improved and speaks for itself. It’s more like a sentence, than magic.</p>
<h3 id="no-and-then">No and then</h3>
<p>You test if shape is an instance of a particular shape, then directly assign this to that shape reference. You are free to use this variable that way you want it according to its reference.</p>
<p>This enables cleaner designs and saves some casting on the writer’s side, and some processing on the reader’s side.</p>
<h2 id="supercharging-pattern-matching">Supercharging Pattern Matching</h2>
<p>Pattern matching, a specification of <a href="http://openjdk.java.net/jeps/305" target="_blank">JEP 305</a>, is pretty impressive. It shows us the way to better control flow in if and switch statements. If you liked the apéritif, you sure gonna like the entrée.</p>
<p>This feature is complete with deconstruction patterns and records, which will provide built-in deconstructors, in conjunction with sealed types.</p>
<p>You will write similar code to this.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sealed</span> <span class="kd">interface</span> <span class="nc">Shape</span> <span class="n">permits</span> <span class="nc">Circle</span><span class="o">,</span> <span class="nc">Triangle</span><span class="o">,</span> <span class="nc">Rectangle</span> <span class="o">{</span> <span class="o">}</span>
<span class="n">record</span> <span class="nf">Triangle</span> <span class="o">(</span><span class="kt">int</span> <span class="n">base</span><span class="o">,</span> <span class="kt">int</span> <span class="n">height</span><span class="o">)</span> <span class="kd">implements</span> <span class="nc">Rectangle</span><span class="o">;</span>
<span class="kt">int</span> <span class="nf">area</span> <span class="o">(</span><span class="nc">Shape</span> <span class="n">shape</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">shape</span> <span class="k">instanceof</span> <span class="nf">Triangle</span><span class="o">(</span><span class="kt">int</span> <span class="n">base</span><span class="o">,</span> <span class="kt">int</span> <span class="n">height</span><span class="o">))</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">base</span><span class="o">*</span><span class="n">height</span><span class="o">/</span><span class="mi">2</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This could be a very likely Java code in the future, mixing sealed interfaces, records, and pattern matching.</p>
<h2 id="source-code">Source Code</h2>
<p>Source code can be found on <a href="https://github.com/albihasani94/java9-plus/tree/master/src/main/java/com/jdk/java14/patternmatching" target="_blank">Github</a></p>
<h2 id="conclusion">Conclusion</h2>
<p>I decided to go with an experimental feature, and that doesn’t mean what you have read here will totally disappear in a drawer. Some things might change, while the main course of action you have seen here will be likely the same when JDK 15 comes out, or these features make into the final release, hopefully the Java 17 LTS but that is only my assumption.</p>
<p>This construct will allow nicer hierarchy checks and the deconstruction patterns will eliminate much of the getter code in order to use the variables of an instance directly.</p>Albin HasaniAs a Java Developer, the risk of getting used to ceremony is a serious thing. Some people are actively involved in putting this risk into sleep.Tirana JUG - Coming Clean on Records2020-01-21T00:00:00+00:002020-01-21T00:00:00+00:00https://www.albinhasani.net/jan-jug-tirana-records<p>Get beyond the “verbose” classes of Java as we know it, to a future which has a special place for data aggregates in Java.</p>
<!--more-->
<h3 id="abstract">Abstract</h3>
<p>Do you ever get bored of writing classes that look like behemoths just to store your data?<br />
Do you not even have the slightest dislike about the IDE generated boilerplate?<br />
Do you not wish there was a simpler way to do this?</p>
<p>If your answer is yes, join me at tonight’s meetup at <a href="https://www.meetup.com/Java-User-Group-Tirana/events/267691374/" target="_blank">JUG Tirana</a>.</p>
<p>It’s ok if you think Java is too verbose. Even us, Java developers at heart, do that sometimes.<br />
And the IDE generated boilerplate for all these classes? Ooof.</p>
<p>In this talk I am going to explore records as a compact construct for data holders in java.<br />
I will make sure my data is quick to write, easy to read.</p>
<p>Coming to a JDK near you in Java 14.</p>
<h3 id="the-talk">The talk</h3>
<ul>
<li>GIFs</li>
<li>Java</li>
</ul>
<h3 id="source-code">Source Code</h3>
<p>Source code on <a href="https://github.com/albihasani94/coming-clean-on-records" target="_blank">Github</a>.</p>
<h3 id="slides">Slides</h3>
<p>Slides on <a href="https://www.slideshare.net/AlbinHasani/coming-clean-on-records-at-tirana-jug" target="_blank">Slideshare</a>.</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/key/kecpeO4ysib5eF" width="510" height="420" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen=""> </iframe>
<div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/AlbinHasani/coming-clean-on-records-at-tirana-jug" title="Coming Clean on Records at Tirana JUG" target="_blank">Coming Clean on Records at Tirana JUG</a> </strong> from <strong><a href="//www.slideshare.net/AlbinHasani" target="_blank">Albin Hasani</a></strong> </div>Albin HasaniGet beyond the “verbose” classes of Java as we know it, to a future which has a special place for data aggregates in Java.Coming Clean on Records2019-12-30T00:00:00+00:002019-12-30T00:00:00+00:00https://www.albinhasani.net/coming-clean-on-records<p>Java will have records, and it will have them soon! Yayy! Now, what does that mean and how on earth did we need these?</p>
<!--more-->
<h2 id="person-begins">Person Begins</h2>
<p>Let’s say you want to have objects of a Person type compounded by a person’s name and age. We love objects! We would immediately rush over to the favorite IDE, write the fields and let the ide generate a bunch of other stuff for us. The result is more or less the same as I got.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="nn">play.with.records</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="o">{</span>
<span class="kd">private</span> <span class="nc">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">private</span> <span class="kt">int</span> <span class="n">age</span><span class="o">;</span>
<span class="c1">// no-arg constructor</span>
<span class="c1">// arg constructor</span>
<span class="c1">// getters and setters</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="nc">Object</span> <span class="n">o</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">o</span><span class="o">)</span>
<span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="k">if</span> <span class="o">(</span><span class="n">o</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">o</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span>
<span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
<span class="nc">Person</span> <span class="n">person</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Person</span><span class="o">)</span> <span class="n">o</span><span class="o">;</span>
<span class="k">return</span> <span class="n">age</span> <span class="o">==</span> <span class="n">person</span><span class="o">.</span><span class="na">age</span> <span class="o">&&</span>
<span class="nc">Objects</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">name</span><span class="o">,</span> <span class="n">person</span><span class="o">.</span><span class="na">name</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="na">hashCode</span><span class="o">();</span>
<span class="n">result</span> <span class="o">=</span> <span class="mi">31</span> <span class="o">*</span> <span class="n">result</span> <span class="o">+</span> <span class="n">age</span><span class="o">;</span>
<span class="k">return</span> <span class="n">result</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="s">"Person{name='"</span> <span class="o">+</span> <span class="n">name</span> <span class="o">+</span> <span class="s">", age="</span> <span class="o">+</span> <span class="n">age</span> <span class="o">+</span> <span class="sc">'}'</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>That’s a whopping 56 lines of code, for just an object with only two properties. That stuff makes you not want to sleep at night. Scary.</p>
<p>In order to keep the semantics consistent, I have created an object of this type and fed it to the consumer.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Person class in any java version</span>
<span class="nc">Person</span> <span class="n">first</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span><span class="s">"Albi"</span><span class="o">,</span> <span class="mi">25</span><span class="o">);</span>
<span class="nc">Consumer</span><span class="o"><</span><span class="nc">Person</span><span class="o">></span> <span class="n">c1</span> <span class="o">=</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">;</span>
<span class="n">c1</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">first</span><span class="o">);</span>
</code></pre></div></div>
<p>The result I got is pretty straightforward:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Person<span class="o">{</span><span class="nv">name</span><span class="o">=</span><span class="s1">'Albi, age=25}
</span></code></pre></div></div>
<p>Now, is there anything on earth you can do about all that <em>overhead</em> and what is more important, make this type more reader friendly?</p>
<h2 id="the-dark-pair">The Dark Pair</h2>
<p>I have often come across the necessity of a structure that is a bit broader than a single element, but more lightweight than a full-fledged class. My colleague at the time was a Python developer and he was scratching his head and coming to me <em>“Why cannot Java have Tuples? It makes life easier. We have them in Python.”</em></p>
<p>To my surprise, there is something that provides this functionality in Java(almost) called Pair.</p>
<p>It has a constructor as follows:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Pair</span><span class="err"></span><span class="o">(</span><span class="no">K</span> <span class="n">key</span><span class="o">,</span> <span class="no">V</span> <span class="n">value</span><span class="o">)</span>
</code></pre></div></div>
<p>With this class, you can create Pairs with keys on one type and values of another type.</p>
<p>I am going to test my code using this construct.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Pair JavaFX prior to java 11</span>
<span class="nc">Pair</span><span class="o"><</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Integer</span><span class="o">></span> <span class="n">nameAgePair</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Pair</span><span class="o"><>(</span><span class="s">"Albi"</span><span class="o">,</span> <span class="mi">25</span><span class="o">);</span>
<span class="nc">Consumer</span><span class="o"><</span><span class="nc">Pair</span><span class="o">></span> <span class="n">c2</span> <span class="o">=</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">;</span>
<span class="n">c2</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">nameAgePair</span><span class="o">);</span>
<span class="c1">// Albi=25</span>
</code></pre></div></div>
<p>Up to this point, we have decided to live in a utopia and use Pair just as we use any Java type any other day. What’s the drawback about this is that Pair lives in a world of its own, the JavaFX <a href="https://docs.oracle.com/javase/8/javafx/api/javafx/util/Pair.html">package</a>. And with the removal of the JavaFX module from JDK 11, that is far from an ideal solution.</p>
<h2 id="the-record-rises">The Record Rises</h2>
<blockquote>
<p>Enhance the Java programming language with records. Records provide a compact syntax for declaring classes which are transparent holders for shallowly immutable data.</p>
</blockquote>
<p>You could think of them as data stores. You want to store data, and you want it now. Records are for you then.</p>
<p>By writing records, you immediately take care of the need for the likes of constructors, getters and setters, equals(), and hashCode().</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">PersonRecord</span> <span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">){</span>
<span class="o">}</span>
<span class="nc">PersonRecord</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PersonRecord</span><span class="o">(</span><span class="s">"Albi"</span><span class="o">,</span> <span class="mi">25</span><span class="o">);</span>
<span class="nc">Consumer</span><span class="o"><</span><span class="nc">PersonRecord</span><span class="o">></span> <span class="n">c3</span> <span class="o">=</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">;</span>
<span class="n">c3</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>
<span class="c1">// PersonRecord[name=Albi, age=25]</span>
</code></pre></div></div>
<h2 id="records-are-classes">Records are classes</h2>
<p>They can have almost all the things classes can have.</p>
<h3 id="methods">Methods</h3>
<p>As we have slightly demonstrated, records immediately get you equals, hashCode and toString for free, but you can add more as you like.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">PersonRecord</span> <span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span><span class="kt">int</span> <span class="n">age</span><span class="o">){</span>
<span class="kt">boolean</span> <span class="nf">isWise</span> <span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">age</span> <span class="o">></span> <span class="mi">80</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="nc">PersonRecord</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PersonRecord</span><span class="o">(</span><span class="s">"Albi"</span><span class="o">,</span> <span class="mi">25</span><span class="o">);</span>
<span class="nc">PersonRecord</span> <span class="n">wisePerson</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PersonRecord</span><span class="o">(</span><span class="s">"Clint Eastwood"</span><span class="o">,</span> <span class="mi">95</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">printf</span><span class="o">(</span><span class="s">"Is %s wise? %s%n"</span><span class="o">,</span> <span class="n">person</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="n">person</span><span class="o">.</span><span class="na">isWise</span><span class="o">()</span> <span class="o">?</span> <span class="s">"yes"</span> <span class="o">:</span> <span class="s">"no"</span><span class="o">);</span>
<span class="c1">// Is Albi wise? no</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">printf</span><span class="o">(</span><span class="s">"Is %s wise? %s%n"</span><span class="o">,</span> <span class="n">wisePerson</span><span class="o">.</span><span class="na">name</span><span class="o">,</span> <span class="n">wisePerson</span><span class="o">.</span><span class="na">isWise</span><span class="o">()</span> <span class="o">?</span> <span class="s">"yes"</span> <span class="o">:</span> <span class="s">"no"</span><span class="o">);</span>
<span class="c1">// Is Clint Eastwood wise? yes</span>
</code></pre></div></div>
<h3 id="constructors">Constructors</h3>
<p>Let’s say we needed a finer control over the definition of the record. We can add the good ol’ boy, the constructor.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">PersonRecord</span> <span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span><span class="kt">int</span> <span class="n">age</span><span class="o">){</span>
<span class="kd">public</span> <span class="nf">PersonRecord</span><span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span> <span class="kt">int</span> <span class="n">age</span><span class="o">){</span>
<span class="k">if</span> <span class="o">(</span><span class="n">age</span> <span class="o">></span> <span class="mi">120</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span><span class="s">"Sorry, age(%d) is too high"</span><span class="o">.</span><span class="na">formatted</span><span class="o">(</span><span class="n">age</span><span class="o">));</span>
<span class="o">}</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="k">this</span><span class="o">.</span><span class="na">age</span> <span class="o">=</span> <span class="n">age</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">try</span> <span class="o">{</span>
<span class="nc">PersonRecord</span> <span class="n">reallyTooOldWoman</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PersonRecord</span><span class="o">(</span><span class="s">"Victoria"</span><span class="o">,</span> <span class="mi">135</span><span class="o">);</span>
<span class="n">c3</span><span class="o">.</span><span class="na">accept</span><span class="o">(</span><span class="n">reallyTooOldWoman</span><span class="o">);</span>
<span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">IllegalArgumentException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="no">LOGGER</span><span class="o">.</span><span class="na">log</span><span class="o">(</span><span class="nc">Level</span><span class="o">.</span><span class="na">INFO</span><span class="o">,</span> <span class="s">"Exception caught: {0}"</span><span class="o">,</span> <span class="n">e</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The output in my console says:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Dec 30, 2019 8:27:07 PM play.with.records.Main main
INFO: Exception caught: Sorry, age<span class="o">(</span>135<span class="o">)</span> is too high
</code></pre></div></div>
<p>What you can slightly dislike about this code is that it adds some of the boilerplate we removed in the first place. Lucky for you and me, there is another alternative to declaring this constructor in a record.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">PersonRecord</span> <span class="o">(</span><span class="nc">String</span> <span class="n">name</span><span class="o">,</span><span class="kt">int</span> <span class="n">age</span><span class="o">){</span>
<span class="kd">public</span> <span class="nc">PersonRecord</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">age</span> <span class="o">></span> <span class="mi">120</span><span class="o">)</span> <span class="o">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span><span class="s">"Sorry, age(%d) is too high"</span><span class="o">.</span><span class="na">formatted</span><span class="o">(</span><span class="n">age</span><span class="o">));</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Checking the output.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Dec 30, 2019 8:45:24 PM play.with.records.Main main
INFO: Exception caught: Sorry, age<span class="o">(</span>135<span class="o">)</span> is too high
</code></pre></div></div>
<p>Neat!</p>
<p>The constructor asks only for what’s explicit, and it fills in the implicit stuff automatically. Sorry, Zen of Python, <em>Implicit is better than explicit.</em> (in this case)</p>
<h2 id="real-life-scenarios">Real-Life Scenarios</h2>
<p>Say you want to take a List and return both its minimum and maximum element at once. You are right when you say you are lazy to write a big class just for these two values.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o"><</span><span class="nc">Integer</span><span class="o">></span> <span class="n">numbers</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">,</span> <span class="mi">10</span><span class="o">,</span> <span class="mi">9</span><span class="o">,</span> <span class="mi">8</span><span class="o">,</span> <span class="mi">7</span><span class="o">,</span> <span class="mi">6</span><span class="o">,</span> <span class="mi">5</span><span class="o">);</span>
</code></pre></div></div>
<p>You really <strong>don’t</strong> want to write a heavyweight class. The answer is in records.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nc">MinMax</span><span class="o"><</span><span class="no">T</span><span class="o">>(</span><span class="no">T</span> <span class="n">min</span><span class="o">,</span> <span class="no">T</span> <span class="n">max</span><span class="o">){</span>
<span class="o">}</span>
<span class="nc">MinMax</span> <span class="n">minMaxOfNumbers</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MinMax</span><span class="o">(</span><span class="n">numbers</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">mapToInt</span><span class="o">(</span><span class="n">x</span><span class="o">-></span><span class="n">x</span><span class="o">).</span><span class="na">min</span><span class="o">().</span><span class="na">getAsInt</span><span class="o">(),</span> <span class="n">numbers</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">mapToInt</span><span class="o">(</span><span class="n">x</span><span class="o">-></span><span class="n">x</span><span class="o">).</span><span class="na">max</span><span class="o">().</span><span class="na">getAsInt</span><span class="o">());</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Min and max of numbers: "</span> <span class="o">+</span> <span class="n">minMaxOfNumbers</span><span class="o">);</span>
<span class="c1">// MinMax[min=1, max=10]</span>
</code></pre></div></div>
<p>Notice that we wrote a generic type of MinMax. Let’s add some people to the mix.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o"><</span><span class="nc">PersonRecord</span><span class="o">></span> <span class="n">personRecords</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="n">person</span><span class="o">,</span> <span class="n">wisePerson</span><span class="o">,</span> <span class="k">new</span> <span class="nc">PersonRecord</span><span class="o">(</span><span class="s">"Toddler"</span><span class="o">,</span> <span class="mi">4</span><span class="o">));</span>
<span class="nc">MinMax</span> <span class="n">minMaxOfPersonsByAge</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MinMax</span><span class="o">(</span><span class="n">personRecords</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">min</span><span class="o">(</span><span class="nc">Comparator</span><span class="o">.</span><span class="na">comparing</span><span class="o">(</span><span class="nl">PersonRecord:</span><span class="o">:</span><span class="n">age</span><span class="o">)).</span><span class="na">get</span><span class="o">(),</span>
<span class="n">personRecords</span><span class="o">.</span><span class="na">stream</span><span class="o">().</span><span class="na">max</span><span class="o">(</span><span class="nc">Comparator</span><span class="o">.</span><span class="na">comparing</span><span class="o">(</span><span class="nl">PersonRecord:</span><span class="o">:</span><span class="n">age</span><span class="o">)).</span><span class="na">get</span><span class="o">());</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Min and max of persons by age: "</span> <span class="o">+</span> <span class="n">minMaxOfPersonsByAge</span><span class="o">);</span>
<span class="c1">// MinMax[min=PersonRecord[name=Toddler, age=4], max=PersonRecord[name=Clint Eastwood, age=95]]</span>
</code></pre></div></div>
<p>The clear advantage we have in our hands compared to doing this with a Pair-like structure is that we have this variable named. And in this case, <em>MinMax</em> tells us almost all there is about this pair. To quote(ahem), the <a href="https://www.python.org/dev/peps/pep-0020/#id3" target="_blank">Zen of Python</a>, “Explicit is better than implicit.”</p>
<h2 id="source-code-and-commands">Source code and Commands</h2>
<p>The demos I have illustrated in this post are on <a href="https://github.com/albihasani94/play.with.records" target="_blank">Github</a>.</p>
<p>You would need to add the <code class="language-plaintext highlighter-rouge">--enable-preview</code> flag to enable the usage of records. They are a preview feature as of Java 14.</p>
<p>The IDE support for records is almost inexistent until now, and I’ve coded my way through a lot of red underlines and warnings.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>javac <span class="nt">--enable-preview</span> <span class="nt">--release</span> 14 <span class="nt">--module-path</span> mods <span class="nt">-d</span> classes <span class="se">\</span>
<span class="nt">--module-source-path</span> src <span class="si">$(</span>find src <span class="nt">-name</span> <span class="s2">"*.java"</span><span class="si">)</span>
jar <span class="nt">--create</span> <span class="nt">--file</span><span class="o">=</span>mods/play.with.records.jar <span class="se">\</span>
<span class="nt">--main-class</span><span class="o">=</span>play.with.records.Main <span class="nt">-C</span> classes/play.with.records <span class="nb">.</span>
java <span class="nt">--enable-preview</span> <span class="nt">--module-path</span> mods <span class="nt">--module</span> play.with.records
</code></pre></div></div>
<h2 id="to-sum-up">To Sum Up</h2>
<p>Records are very convenient data stores in Java. They are ideal for DTOs and classes without much business logic, just the data. They remove the need for IDE generated boilerplate and make reading code more appealing than reading classes for the use case that we have demonstrated. It’s nice to know that even if you want to add some computation methods into the record, you can just do it. You can also add a lightweight constructor into them, which is syntactic sugar, but still very nice.</p>
<h2 id="ps">P.S.</h2>
<p>Dear reader, please don’t be this guy.</p>
<p><img src="/assets/images/records-denis.png" alt="records-denis" /></p>
<p>Yeah, C# had it first, Kotlin is in the future. Yes. If you want to use C#, use C#. If you want to use Kotlin, use Kotlin. Just because something works for you and your team doesn’t mean something else won’t work for someone else.</p>
<p>That’s the joy of programming. The possibilities are endless to make something right. You get to choose, just choose wisely.</p>Albin HasaniJava will have records, and it will have them soon! Yayy! Now, what does that mean and how on earth did we need these?A walk through Devoxx Belgium2019-12-06T00:00:00+00:002019-12-06T00:00:00+00:00https://www.albinhasani.net/walk-through-devoxx-belgium<p>A little more than three weeks ago I was in Devoxx Belgium. It had it all. The core Java talks, the bytecode wonders, the soft skills, a look at the future, and Venkat.</p>
<!--more-->
<p>This is the second conference of my journey in the Java community. The first one being last year in Voxxed Athens. I have it as a personal goal to go to at least one major conference each year. With a mediterranean edition in Athens and probably the most major one of Europe in Belgium taken off the list, the next year will be an interesting choice.</p>
<p>Briefly I am going to share a few interesting bits and pieces.</p>
<h2 id="qualities-of-a-highly-effective-architect">Qualities of a Highly Effective Architect</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/QeKheNfO3Yg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>This is probably my favorite talk of the conference. Not technical on the surface, only pure behavior-driven talk. You listen to this talk and you find yourself in most of the situations Venkat so sincerely describes with bits of humor too.</p>
<p>TL;DR Software is made by people. We are responsible for much more than we can imagine. We have a deep impact on the organizations we work for, far beyond the reach of our code. Be humble, respect people, and fight every day to make working better and easier for each one around you, and you will be happy to see the results.</p>
<p>Venkat has stopped by some points I think one should try to learn:</p>
<ul>
<li>Be a mentor, not a tormentor</li>
<li>Criticize ideas, not people</li>
<li>Guide, don’t dictate</li>
<li>Focus on the outcome, not the process</li>
<li>Learn to unlearn</li>
<li>Lead by example</li>
<li>Write code (seriously!)</li>
<li>Practice collective ownership (it’s not you, it’s we)</li>
</ul>
<h2 id="evolving-a-pragmatic-clean-architecture---a-craftsmans-guide">Evolving a Pragmatic, Clean Architecture - A Craftsman’s Guide</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/KOqIUNUq2Gg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>Victor Rentea does some fine talk going through an evolving design for enterprise applications.</p>
<p>Half-jokingly he shares some philosophy:</p>
<blockquote>
<p>The Codebase is a garden.</p>
<p>Not a construction.</p>
<p>Code is organic.</p>
<p>It needs continuous care.</p>
</blockquote>
<p>I’d like to call that the Zen of Victor.</p>
<p>The takeaway message of this talk is also interesting: <strong>Put passion in all that you do</strong>.</p>
<h2 id="bolcom-and-the-accelerated-legacy-challenge">Bol.com and the Accelerated Legacy Challenge</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/iQ6ThO1-Rn4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>This talk has my most favorite metaphor of the conference lol.</p>
<p>Legacy code == The picture of Dorian Gray</p>
<p>Raul Leal is so dramatic telling a story of how legacy comes to haunt you.</p>
<p>The talk goes on to mention the history of Bol.com and how they’ve grown up and handle change.</p>
<h2 id="agile-is-still-a-dirty-word">Agile is STILL a Dirty Word!</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/rUXQmY8f2Ow" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>This talk by James Birnie who works for Codurance, holds his own experience through many of the Agile fallacies.</p>
<p>Anti-agile organizational smells you may have come across yourself, agile goals and principles, and Conway’s law make for a very effective talk.</p>
<h2 id="designing-functional-and-fluent-api-example-of-the-visitor-pattern">Designing functional and fluent API: example of the Visitor Pattern</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/gq23w9nycBs" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>José Paumard goes deep in this technical talk. He explains this pattern in so much detail.</p>
<p>Why the visitor pattern?</p>
<p>He explains:</p>
<blockquote>
<p>Because it is tough to implement.</p>
<p>So if you can implement it, then you can implement anything.</p>
</blockquote>
<p>A Stuart Marks reference also made the talk:</p>
<blockquote>
<p>If you have a problem to solve, and you use the Visitor pattern, then you have two problems: the original problem and the Visitor pattern.</p>
</blockquote>
<p>Frankly, I agree.</p>
<h2 id="what-lies-beneath">What Lies Beneath</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/5AFgNuGwLos" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>I enjoyed this session so much. Like the previous talk, it goes on a deep level and it makes you wonder.</p>
<p>I learned that so much goes into a simple division operation in Java. I’m not gonna spoil the talk..</p>
<h2 id="ask-the-java-architect">Ask the Java Architect</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/qKeMB7OoGJk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>The “Ask the Architect” series is a favorite of mine. Unfortunately, this one missed Mark Reinhold.</p>
<p>Brian Goetz, Stuart Marks, and Ron Pressler answered questions and it’s really nice to see where Java is going in hands of these people.</p>
<p>I personally asked two questions (after the talk, ofc) to Stuart Marks and God he knew his stuff.</p>
<h2 id="java-language-futures-late-2019-edition">Java Language Futures: Late 2019 Edition</h2>
<iframe width="480" height="270" src="https://www.youtube-nocookie.com/embed/J6fegDQPgps" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
<p>I’m still waiting to try out the new features I saw in this talk.</p>
<p>Java is 25 years old, and now it is not going to die anytime soon.</p>
<p>Record and Pattern Matching are very interesting additions to the language and I can’t wait to get my hands on them.</p>
<h2 id="summing-up">Summing Up</h2>
<p>This Devoxx edition was great. Being at a conference is very nice and knowing how much there is to learn(and unlearn) is amazing.</p>Albin HasaniA little more than three weeks ago I was in Devoxx Belgium. It had it all. The core Java talks, the bytecode wonders, the soft skills, a look at the future, and Venkat.Let there be var2019-11-03T00:00:00+00:002019-11-03T00:00:00+00:00https://www.albinhasani.net/let-there-be-var<p><em>This is old news.</em></p>
<p>I have heard this excerpt at a talk by Brian Goetz and you can’t blame him. From the time var was introduced to the language, it was dreaded and loved, feared and embraced.. and the world with var is not that bad after all.</p>
<h2 id="local-variable-type-inference">Local Variable Type Inference</h2>
<p>To understand the roots of this feature, one ought to have to have heard about <a href="https://openjdk.java.net/projects/amber/" target="_blank"><em>Project Amber</em>.</a> This nice gem-y name project is all about introducing new language features to keep Java modern and more attractive to developers. <em>(Java you have always been good, it’s just that these improvements will do no bad either).</em></p>
<p>Local-Variable type inference is part of this project under the umbrella of <a href="https://openjdk.java.net/jeps/286" target="_blank">JEP 286</a>.</p>
<p>Did this invention happen in Java? Not by a long shot. Java’s evil twin brother (C#) has had var for more than a decade now, and other languages in the JVM ecosystem like Scala, Groovy and Kotlin already support a form of local-variable type inference.</p>
<h2 id="the-ceremony">The Ceremony</h2>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="s">"https://www.albinhasani.net/"</span><span class="o">);</span>
<span class="nc">URLConnection</span> <span class="n">conn</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="na">openConnection</span><span class="o">();</span>
<span class="nc">BufferedReader</span> <span class="n">reader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">()));</span>
<span class="nc">String</span> <span class="n">inputLine</span><span class="o">;</span>
<span class="k">while</span> <span class="o">((</span><span class="n">inputLine</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">inputLine</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Running this code will output the contents of the HTML file at the homepage of this blog.</p>
<p>What’s wrong? Nothing. This code just is not fun to write.</p>
<h2 id="how-do-we-make-it-fun-to-write">How do we make it fun to write?</h2>
<p>Let’s take a look at this.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="s">"https://www.albinhasani.net/"</span><span class="o">);</span>
<span class="kt">var</span> <span class="n">conn</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="na">openConnection</span><span class="o">();</span>
<span class="kt">var</span> <span class="n">reader</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">()));</span>
<span class="nc">String</span> <span class="n">inputLine</span><span class="o">;</span>
<span class="k">while</span> <span class="o">((</span><span class="n">inputLine</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">readLine</span><span class="o">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">inputLine</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>
<p>This immediately removes some clutter from the program. It needs strong emphasis to be put on the variable naming though.</p>
<p>However a bad name it may be, everyone could guess that a <code class="language-plaintext highlighter-rouge">BufferedReader magicMaker</code> is a BufferedReader, but one would need <code class="language-plaintext highlighter-rouge">var reader</code> explicitly named to guess what this variable may be about without looking at the right side of the assignment.</p>
<p>Don’t get me wrong, I am a strong advocate of good naming in all cases, this case only needs some extra attention.</p>
<p><img src="/assets/images/how-dare-you-stand-where-he-stood.jpg" alt="how dare you?" /></p>
<h2 id="living-with-var">Living with var</h2>
<p>Local-Variable Type inference, as the name suggests, can only be used for local variables in methods, not fields or method return types.</p>
<p>It has been around for some time in Java in some kind. You could write code like this with the addition of streams.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">longestTitle</span> <span class="o">=</span> <span class="n">books</span><span class="o">.</span><span class="na">stream</span><span class="o">()</span>
<span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">b</span> <span class="o">-></span> <span class="n">b</span><span class="o">.</span><span class="na">getTitle</span><span class="o">())</span>
<span class="o">.</span><span class="na">mapToInt</span><span class="o">(</span><span class="nl">String:</span><span class="o">:</span><span class="n">length</span><span class="o">)</span>
<span class="o">.</span><span class="na">max</span><span class="o">()</span>
<span class="o">.</span><span class="na">orElse</span><span class="o">(</span><span class="mi">0</span><span class="o">);</span>
</code></pre></div></div>
<p>In this block of code, we didn’t have to:</p>
<ul>
<li>declare any intermediate type like Stream<Book> or IntStream</Book></li>
<li>declare the type of lambda variable b</li>
</ul>
<p>Local Variable Type Inference pushes this one step further with the local types.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">path</span> <span class="o">=</span> <span class="nc">Paths</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">fileName</span><span class="o">);</span>
<span class="kt">var</span> <span class="n">bytes</span> <span class="o">=</span> <span class="nc">Files</span><span class="o">.</span><span class="na">readAllBytes</span><span class="o">(</span><span class="n">path</span><span class="o">);</span>
<span class="kt">var</span> <span class="n">list</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><</span><span class="nc">String</span><span class="o">>();</span>
</code></pre></div></div>
<p>The var identifier is not a keyword which means that its usages as a field, method, or package name will not be affected. Code that uses var as a class or interface name will be affected. As if anyone did that already (Looking at you caveman working on Java).</p>
<h2 id="benefits">Benefits</h2>
<ul>
<li>Write less to mean more</li>
<li>Very handy in case of complex types such as these involving generics</li>
</ul>
<h2 id="caveats">Caveats</h2>
<p>Not any major caveats to be aware of, despite the obvious one:</p>
<ul>
<li>choose careful naming, nobody would know the type of <code class="language-plaintext highlighter-rouge">var a = b.getNext()</code></li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>While not a paradigm shift among the Java language, this change is a sign that the language is now progressing at a fast pace.</p>
<p>Local-Variable Type Inference continues to remove some boilerplate from the process of writing code, making the language more attractive to developers.</p>
<p>Codebases will benefit, code will be written quicker, managers will be happy to show off about their companies living in the future.</p>Albin HasaniBeing late to the game with var in Java? No problem.As a matter of JEP2019-10-28T00:00:00+00:002019-10-28T00:00:00+00:00https://www.albinhasani.net/as-a-matter-of-jep<p>The improvements and additions to the Java language come as a result of the JDK Enhancement Proposal process.</p>
<!--more-->
<p>The summary of this process is found on the OpenJDK project and interestingly enough the very first <a href="https://openjdk.java.net/jeps/1" target="_blank">proposal</a> describes the process.</p>
<p>In the summary section, it states:</p>
<blockquote>
<p><em>This document defines a process for collecting, reviewing, sorting, and recording the results of proposals for enhancements to the JDK and for related efforts, such as process and infrastructure improvements.</em></p>
</blockquote>
<p>An enhancement is singled out as:</p>
<blockquote>
<p><em>An enhancement is an effort to design and implement a nontrivial change to the JDK code base or to do some other kind of work whose goals, progress, and result are worth communicating broadly.</em></p>
</blockquote>
<p>While that is the very first proposal, the very very first one is actually <a href="http://openjdk.java.net/jeps/0" target="_blank">JEP Zero</a>. Who would’ve thought? This one contains an index to all the known JEPs.</p>
<p>A JDK Enhancement Proposal must include a <strong>summary</strong> and a <strong>description</strong>. It could also include <strong>goals</strong>, <strong>non-goals</strong>, <strong>success metrics</strong>, and <strong>motivation</strong> if applicable. All these are part of none other than the following <a href="https://openjdk.java.net/jeps/2" target="_blank">JEP 2</a>.</p>
<p>In my opinion, this process is very transparent to anyone interested in learning more about Java internal development and staying in the know about what’s about to come to the language.</p>
<p>You’ve unlocked Gandalf!</p>
<p><img src="/assets/images/you-shall-not-pass.jpg" alt="Gendulf" /></p>Albin HasaniThe improvements and additions to the Java language come as a result of the JDK Enhancement Proposal process.Static Factory Collection Methods2019-10-23T00:00:00+00:002019-10-23T00:00:00+00:00https://www.albinhasani.net/static-factory-colletion-methods<p>In this post, I have written about some improvements to collections. I think these methods would provide a great starting spot for Java Developers looking to find what lurks beyond Java 8.</p>
<!--more-->
<p>It seems ages since Java 9 was released because Oracle and the Community have been delivering one major version of Java on a six-month schedule.</p>
<p>There couldn’t be a better time to step in the future of Java and save Java 8 from the risk of becoming our “Windows XP” in the not-so-far future. There is no reason not to as Java versions have often taken a strong stance towards backward-compatibility while delivering rock-solid enhancements.</p>
<p>These improvements have been covered by others, most masterfully from the likes of Sander Mak, Nicolai Parlog, and Miro Cupak. This post is going to be my take on it.</p>
<h2 id="listof-setof-and-a-little-taste-of-mapof">List.of(), Set.of(), and a little taste of Map.of()</h2>
<p>This feature is part of <a href="https://openjdk.java.net/jeps/269" target="_blank">JEP 269</a>: Convenience Factory Methods for Collections.</p>
<p>I am going to single out its goal:</p>
<blockquote>
<p>Provide static factory methods on the collection interfaces that will create compact, unmodifiable collection instances.</p>
</blockquote>
<p>This goal is concise and we would need to see how we dealt with collection creation in prior versions of Java to better understand the simplicity aimed for.</p>
<p>If you are more interested in the JEP process, you can read this short explanatory <a href="/as-a-matter-of-jep">post</a>.</p>
<h3 id="the-ceremony">The Ceremony</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">animals</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o"><>();</span>
<span class="n">animals</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Dog"</span><span class="o">);</span>
<span class="n">animals</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Lemur"</span><span class="o">);</span>
<span class="n">animals</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Duck"</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">animals</span><span class="o">);</span>
<span class="c1">// [Dog, Lemur, Duck]</span>
</code></pre></div></div>
<p>This is classic Java you have learned in school. Create a list of Strings. Add the items one by one. Drum roll. Credits.</p>
<p>It would be perfect in a reality where developers are paid for lines of code. (@cc me in a confrontation with your boss if your company practices this). For this post, I am just moving on to alternatives to the approach above.</p>
<h3 id="the-post-ceremony">The Post-Ceremony</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Set</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">animals</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashSet</span><span class="o"><>(</span><span class="nc">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span><span class="s">"Dog"</span><span class="o">,</span> <span class="s">"Lemur"</span><span class="o">,</span> <span class="s">"Duck"</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">animals</span><span class="o">);</span>
<span class="c1">// [Duck, Dog, Lemur]</span>
</code></pre></div></div>
<p>Now, this is what evolution does for you. People got lazy writing all that ceremony and decided there is a shorter way of doing it. The problem with this approach is that a method outside the Set or List interface needs to be called. That method resides in the Arrays class. Added to that, you have to create a List before getting a result of the Set.</p>
<h3 id="the-hack">The Hack</h3>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="nc">Set</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">animals</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">HashSet</span><span class="o"><>(){{</span><span class="n">add</span><span class="o">(</span><span class="s">"Dog"</span><span class="o">);</span> <span class="n">add</span><span class="o">(</span><span class="s">"Lemur"</span><span class="o">);</span> <span class="n">add</span><span class="o">(</span><span class="s">"Duck"</span><span class="o">);}};</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">animals</span><span class="o">);</span>
<span class="c1">// [Duck, Dog, Lemur]</span></code></pre></figure>
<p>Don’t try this at home! This is what a Java geek would come up with. It makes me laugh, yet it works. This instantiation makes use of the instance-initializer construct of an anonymous inner class.</p>
<p>On the top, we have been clever enough to write this genius code.</p>
<p>Under the covers, we have created an instance of a class which extends HashSet in the outer braces, then we provided an instance initialization block in the inner braces.</p>
<p>This is considered an anti-pattern according to <a href="https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/" target="_blank">some</a>, including myself. The instance initialized using this code will hold a hidden reference to the surrounding class, making memory leaks more likely.</p>
<h3 id="java-9-to-the-rescue">Java 9 to the Rescue!</h3>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">List</span><span class="o"><</span><span class="nc">String</span><span class="o">></span> <span class="n">animals</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Dog"</span><span class="o">,</span> <span class="s">"Lemur"</span><span class="o">,</span> <span class="s">"Duck"</span><span class="o">);</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">animals</span><span class="o">);</span>
<span class="c1">// [Dog, Lemur, Duck]</span>
</code></pre></div></div>
<p>Not only this works, but it is also simple for the user of the language. That’s clean, concise, and it just does what it is implying. A list of these types will be created. No ceremony. Everyone who expected a great party should go home.</p>
<p>What’s the catch? Let’s just add another animal to the list.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">animals</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Elephant"</span><span class="o">);</span>
<span class="o">|</span> <span class="nc">Exception</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">UnsupportedOperationException</span>
<span class="o">|</span> <span class="n">at</span> <span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">uoe</span> <span class="o">(</span><span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">71</span><span class="o">)</span>
<span class="o">|</span> <span class="n">at</span> <span class="nc">ImmutableCollections</span><span class="n">$AbstractImmutableCollection</span><span class="o">.</span><span class="na">add</span> <span class="o">(</span><span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">java</span><span class="o">:</span><span class="mi">75</span><span class="o">)</span>
<span class="o">|</span> <span class="n">at</span> <span class="o">(</span><span class="err">#</span><span class="mi">12</span><span class="o">:</span><span class="mi">1</span><span class="o">)</span>
</code></pre></div></div>
<p>That must be quite a big elephant so that it couldn’t fit in our list. The returned list, as we will see, is not a simple ArrayList.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">animals</span><span class="o">.</span><span class="na">getClass</span><span class="o">());</span>
<span class="c1">// class java.util.ImmutableCollections$ListN</span>
</code></pre></div></div>
<p>These factory methods are designed for small, fixed-size collections. The reason we got the exception in the first place is that these static factory methods return immutable collections. An immutable collection, as an immutable object, is an object whose state cannot be changed after it is constructed.</p>
<h3 id="the-benefits">The benefits</h3>
<ul>
<li>They are thread-safe after construction</li>
<li>Because they don’t need to support mutation, they can consume much less memory than mutable counterparts</li>
<li>A go-to choice for collections that are initialized from known values and that never change</li>
</ul>
<h3 id="the-api">The API</h3>
<h4 id="listof">List.of</h4>
<p>With Java 9, the most convenient way to create immutable lists is through this factory method.
What’s more interesting lies under the API for this method.</p>
<p>Let’s try a couple of use cases with this method. For these scenarios, I’m going to run the jshell <a href="https://docs.oracle.com/javase/9/jshell/introduction-jshell.htm" target="_blank">tool</a> which came with Java 9.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jshell> List<Integer> singleElementList <span class="o">=</span> List.of<span class="o">(</span>1<span class="o">)</span><span class="p">;</span>
singleElementList <span class="o">==></span> <span class="o">[</span>1]
jshell> singleElementList.getClass<span class="o">()</span>
<span class="nv">$2</span> <span class="o">==></span> class java.util.ImmutableCollections<span class="nv">$List12</span>
jshell> List<Integer> twoElementsList <span class="o">=</span> List.of<span class="o">(</span>1, 2<span class="o">)</span><span class="p">;</span>
twoElementsList <span class="o">==></span> <span class="o">[</span>1, 2]
jshell> twoElementsList.getClass<span class="o">()</span>
<span class="nv">$4</span> <span class="o">==></span> class java.util.ImmutableCollections<span class="nv">$List12</span>
</code></pre></div></div>
<p>Nothing weird to notice yet. Let’s try another one.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jshell> List<Integer> mustBeABiggerList <span class="o">=</span> List.of<span class="o">(</span>1, 2, 3<span class="o">)</span><span class="p">;</span>
mustBeABiggerList <span class="o">==></span> <span class="o">[</span>1, 2, 3]
jshell> mustBeABiggerList.getClass<span class="o">()</span>
<span class="nv">$6</span> <span class="o">==></span> class java.util.ImmutableCollections<span class="nv">$ListN</span>
</code></pre></div></div>
<p>What happened? Changing the number of elements a list would contain resulted in a different kind of list type. From <code class="language-plaintext highlighter-rouge">ImmutableCollections$List12</code> for the two first objects and <code class="language-plaintext highlighter-rouge">ImmutableCollections$ListN</code> for the third object.</p>
<p>The reason for this change is that the writers of this API have intended to improve the performance of collections when their number is known.</p>
<p>Digging a little on this API, you would find not only 2, but 12 implementations of the <code class="language-plaintext highlighter-rouge">List.of</code> method. That’s right!</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">();</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">,</span> <span class="no">E6</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">,</span> <span class="no">E6</span><span class="o">,</span> <span class="no">E7</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">,</span> <span class="no">E6</span><span class="o">,</span> <span class="no">E7</span><span class="o">,</span> <span class="no">E8</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">,</span> <span class="no">E6</span><span class="o">,</span> <span class="no">E7</span><span class="o">,</span> <span class="no">E8</span><span class="o">,</span> <span class="no">E9</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">,</span> <span class="no">E3</span><span class="o">,</span> <span class="no">E4</span><span class="o">,</span> <span class="no">E5</span><span class="o">,</span> <span class="no">E6</span><span class="o">,</span> <span class="no">E7</span><span class="o">,</span> <span class="no">E8</span><span class="o">,</span> <span class="no">E9</span><span class="o">,</span> <span class="no">E10</span><span class="o">);</span>
<span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E</span><span class="o">...</span> <span class="n">elements</span><span class="o">);</span>
</code></pre></div></div>
<p>What’s the fuss all about? For each number of elements up to 10, the API provides a specific option to the developer. These options have private implementations hidden behind the <code class="language-plaintext highlighter-rouge">of</code> method and they return more space-efficient collections than their mutable counterparts.</p>
<ul>
<li>The empty arguments <code class="language-plaintext highlighter-rouge">List.of()</code> would return an empty list</li>
<li>The implementations with one <code class="language-plaintext highlighter-rouge">List.of(E1)</code> or two <code class="language-plaintext highlighter-rouge">List.of(E1, E2)</code> elements such as would return an instance of <code class="language-plaintext highlighter-rouge">ImmutableCollections.List12</code></li>
<li>The other implementations <code class="language-plaintext highlighter-rouge">List.of(E1, E2.. E10)</code> would return an instance of <code class="language-plaintext highlighter-rouge">ImmutableCollections.ListN</code></li>
</ul>
<p>The <code class="language-plaintext highlighter-rouge">List.of(E... elements)</code> serves as a last resort; it takes several arguments in the form of varargs and would be used in any other case. The reason this option is saved for the last is that it is less efficient. A vararg is implemented in Java as an array passed to the method. Therefore, the instantiation and garbage collection of an array would be performance costly compared to the overloaded methods with a fixed-size number of arguments.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">static</span> <span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nc">List</span><span class="o"><</span><span class="no">E</span><span class="o">></span> <span class="nf">of</span><span class="o">(</span><span class="no">E</span><span class="o">...</span> <span class="n">elements</span><span class="o">)</span> <span class="o">{</span>
<span class="k">switch</span> <span class="o">(</span><span class="n">elements</span><span class="o">.</span><span class="na">length</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// implicit null check of elements</span>
<span class="k">case</span> <span class="mi">0</span><span class="o">:</span>
<span class="k">return</span> <span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">emptyList</span><span class="o">();</span>
<span class="k">case</span> <span class="mi">1</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">List12</span><span class="o"><>(</span><span class="n">elements</span><span class="o">[</span><span class="mi">0</span><span class="o">]);</span>
<span class="k">case</span> <span class="mi">2</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">List12</span><span class="o"><>(</span><span class="n">elements</span><span class="o">[</span><span class="mi">0</span><span class="o">],</span> <span class="n">elements</span><span class="o">[</span><span class="mi">1</span><span class="o">]);</span>
<span class="k">default</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nc">ImmutableCollections</span><span class="o">.</span><span class="na">ListN</span><span class="o"><>(</span><span class="n">elements</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The devil is in the details!</p>
<h4 id="setof">Set.of</h4>
<p>Pretty much the same as the API for <code class="language-plaintext highlighter-rouge">List.of</code>.
The only change is that the data structure worked on is Set.
Unlike a list, a set is an unordered collection and does not allow duplicates.</p>
<p>The API would become streamlined as:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">();</span>
<span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">E1</span><span class="o">);</span>
<span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">);</span>
<span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">E1</span><span class="o">,</span> <span class="no">E2</span><span class="o">..</span> <span class="no">E10</span><span class="o">);</span>
<span class="nc">Set</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">E</span><span class="o">...</span> <span class="n">elements</span><span class="o">);</span>
</code></pre></div></div>
<p>Subsequent calls of <code class="language-plaintext highlighter-rouge">Set.of()</code> on a sequence of elements would return a Set with a different iteration order each time.</p>
<p>The same benefits and caveats that apply to immutable lists apply to the immutable sets created through this factory method.</p>
<h4 id="mapof">Map.of</h4>
<p>Similarly, the Map interface provides a static factory method to create immutable maps.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jshell> Map<String, Integer> wordToNumber <span class="o">=</span> Map.of<span class="o">(</span><span class="s2">"one"</span>, 1, <span class="s2">"two"</span>, 2, <span class="s2">"three"</span>, 3<span class="o">)</span><span class="p">;</span>
wordToNumber <span class="o">==></span> <span class="o">{</span><span class="nv">two</span><span class="o">=</span>2, <span class="nv">one</span><span class="o">=</span>1, <span class="nv">three</span><span class="o">=</span>3<span class="o">}</span>
jshell> wordToNumber.getClass<span class="o">()</span>
<span class="nv">$2</span> <span class="o">==></span> class java.util.ImmutableCollections<span class="nv">$MapN</span>
</code></pre></div></div>
<p>The analogous API of Map would be</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Map</span><span class="o">.</span><span class="na">of</span><span class="o">();</span>
<span class="nc">Map</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">K1</span><span class="o">,</span> <span class="no">V1</span><span class="o">);</span>
<span class="nc">Map</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">K1</span><span class="o">,</span> <span class="no">V1</span><span class="o">,</span> <span class="no">K2</span><span class="o">,</span> <span class="no">V2</span><span class="o">);</span>
<span class="nc">Map</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="no">K1</span><span class="o">,</span> <span class="no">V1</span><span class="o">,</span> <span class="no">K2</span><span class="o">,</span> <span class="no">V2</span><span class="o">..</span> <span class="no">K10</span><span class="o">,</span> <span class="no">V10</span><span class="o">);</span>
<span class="nc">Map</span><span class="o">.</span><span class="na">ofEntries</span><span class="o">(</span><span class="nc">Entry</span><span class="o">(</span><span class="no">K1</span><span class="o">,</span> <span class="no">V1</span><span class="o">)...</span> <span class="n">entries</span><span class="o">);</span>
</code></pre></div></div>
<h3 id="caveats-to-be-aware-of">Caveats to be aware of</h3>
<ul>
<li>An attempt to modify the collection would result in an <code class="language-plaintext highlighter-rouge">UnsupportedOperationException</code></li>
<li>However, if the objects the collection holds are mutable the collection is not effectively immutable, e.g. <code class="language-plaintext highlighter-rouge">List<List<String>> effectivelyMutable;</code>.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>We just took a look at the new factory methods that came with the improved Collections API in Java 9. These methods have provided a convenient way to create immutable lists and sets.</p>
<p>As a writer of this article, I am impressed with the effort that goes into maintaining and growing the Java language. The JEPs are a good starting point to follow along with the birth of new features in years to come.</p>
<p>I hope to have achieved your understanding of these methods. There is a big noise out there, I would like to be part of a signal.</p>
<p>You can find all the code of this article as jshell interpretable commands <a href="https://gist.github.com/albihasani94/2448fed86f1df71fbfdddc2d0b0b4138" target="_blank">here</a>.</p>
<p><em>P.S. Don’t support me</em></p>Albin HasaniIn this post, I have written about some improvements to collections. I think these methods would provide a great starting spot for Java Developers looking to find what lurks beyond Java 8.