<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[HybridITSolutions - Medium]]></title>
        <description><![CDATA[All about software development outsourcing: technology, business and people - Medium]]></description>
        <link>https://medium.com/hybriditsolutions?source=rss----af2270351fe4---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>HybridITSolutions - Medium</title>
            <link>https://medium.com/hybriditsolutions?source=rss----af2270351fe4---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 20:46:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/hybriditsolutions" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[What’s new in Java 14]]></title>
            <link>https://medium.com/hybriditsolutions/whats-new-in-java-14-24b990f40be1?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/24b990f40be1</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java-14]]></category>
            <category><![CDATA[openjdk]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Mon, 23 Mar 2020 14:37:22 GMT</pubDate>
            <atom:updated>2020-03-23T14:37:22.226Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uiOfJi1Ytkei5NoBBE22rA.png" /></figure><p>JDK 14 reached <a href="https://openjdk.java.net/projects/jdk8/milestones#General_Availability">General Availability</a> on 17 March 2020. JDK 14 is a feature release of Java, and the plan is that it will receive security updates in April and July before being superseded by JDK 15.</p><p>It can be downloaded from the official Oracle page (commercial version) or from the open JDK page: <a href="https://jdk.java.net/14/">https://jdk.java.net/14/</a> . Other vendors should also release their distributions in the next couple of days.</p><p>In this article, we will go through the changes that are coming with this version of Java.</p><p>Note that as of 21 of March IntelliJ idea still does not have production ready support for java 14 features so if you want to use them in your Intellj without getting any warnings, you will need to use early access builds. Eclipse released new version supporting Java 14 on 20th of March, but that release still does not support all features (like pattern matching for <em>instance of</em>)</p><h4><a href="https://openjdk.java.net/jeps/358"><strong>Helpful NullPointerExceptions</strong></a><strong> </strong>(Standard)</h4><p>Probably one of the features of Java 14 that will help developers the most in their day to day work. By an analysis of the bytecode instructions of a program, in the future, the JVM should be able to show precisely which variable results in a zero value.</p><p>Example message looks like this:</p><pre>Exception in thread &quot;main&quot; java.lang.NullPointerException: <br>        Cannot assign field &quot;lika&quot; because &quot;krajina&quot; is null<br>    at Demo.main(Demo.java:8)</pre><p>If the more complex statement City city = evropa.krajina.lika.gracac throws an NPE, the message would dissect the statement and pinpoint the cause by showing the full access path which led up to the null:</p><pre>Exception in thread &quot;main&quot; java.lang.NullPointerException: <br>        Cannot read field &quot;lika&quot; because &quot;evropa.krajina&quot; is null<br>    at Demo.main(Demo.java:12)<br></pre><h4><a href="https://openjdk.java.net/jeps/363">Remove the Concurrent Mark Sweep (CMS) Garbage Collector</a>(Standard)</h4><p>One of the most popular Garbage Collectors is finally being removed after being deprecated in Java 9.</p><p>This is something to have in mind if you are migrating from Java 8, or you have been ignoring deprecation warnings until now.</p><p>Successors to CMS have arisen including ZGC and Shenandoah. Until this version, ZGC was available only for Linux. With version 14 and jeps 364 and 365, ZGC should be available on Mac and Windows also.</p><h4><a href="https://openjdk.java.net/jeps/361">Switch Expressions (Standard)</a></h4><p>Switch expressions were first introduced in Java 12, got improvements in Java 13 as well as in Java 14 where it became a standard feature.</p><p>Switch expressions as we saw them in Java 13 are still supported:</p><pre>String numberOfDays = switch (month) {<br>            case 2:<br>                yield &quot;28&quot;;<br>            case 4, 6, 9, 11:<br>                yield &quot;30&quot;;<br>            case 1, 3, 5, 7, 8, 10, 12:<br>                yield &quot;31&quot;;<br>            default: throw new RuntimeException(&quot;Invalid month&quot;);        <br>};</pre><p>Additionally, now we can write code using a new syntax that uses the -&gt; operator instead of the colon. Using this operator eliminates the need for using yield, it is implicit. Still, if you want to have a code block for some case, you still need to use yield:</p><pre>String numberOfDays = switch (month) {<br>    case 2 -&gt;  &quot;28&quot;;<br>    case 4, 6, 9, 11 -&gt; &quot;30&quot;;<br>    case 1, 3, 5, 7, 8, 10, 12 -&gt; &quot;31&quot;<br>    default -&gt; {<br>        System.<em>out</em>.println(&quot;Invalid month&quot;);<br>        yield &quot;0&quot;;<br>    }<br>};</pre><h4>Other smaller standard updates:</h4><ul><li><a href="https://openjdk.java.net/jeps/345">NUMA-Aware Memory Allocation for G1</a>(Standard)<br>Improve G1 performance on large machines by implementing NUMA-aware memory allocation.</li><li><a href="https://openjdk.java.net/jeps/349">JFR Event Streaming</a>(Standard)<br>Expose JDK Flight Recorder data for continuous monitoring.</li><li><a href="https://openjdk.java.net/jeps/352">Non-Volatile Mapped Byte Buffers</a>(Standard)<br>Add new JDK-specific file mapping modes so that the FileChannel API can be used to create MappedByteBuffer instances that refer to non-volatile memory.</li><li><a href="https://openjdk.java.net/jeps/364">ZGC on macOS</a><br>Port the ZGC garbage collector to macOS.</li><li><a href="https://openjdk.java.net/jeps/365">ZGC on Windows</a><br>Port the ZGC garbage collector to Windows.</li><li><a href="https://openjdk.java.net/jeps/366">Deprecate the ParallelScavenge + SerialOld GC Combination</a></li><li><a href="https://openjdk.java.net/jeps/367">Remove the Pack200 Tools and API</a></li></ul><h4><strong>Preview and incubator features:</strong></h4><p>Preview and incubator features are prone to changes (as we saw with the evolution of switch expressions from Java 12 until becoming standard in Java 14). Also, they are not enabled by default, so we will not go into great detail investigating them.</p><p>In case you haven’t read previous articles difference between preview and incubator features is that preview features are almost complete language features ready to try out while incubating features are distributed in their own module prefixed with JDK.incubator and when incubating process is finished they will be moved to proper JDK module. A more detailed explanation of differences between preview, incubator and experimental features you can find <a href="https://4comprehension.com/preview-experimental-and-incubating-features-in-java/">here</a>.</p><p><a href="https://openjdk.java.net/jeps/305"><strong>Pattern Matching for instance of (Preview)</strong></a></p><p>The goal of this feature is to eliminate the need for casting when doing <em>instance of.<br></em>Before we needed to cast an object after we determined it belongs to some type using <em>instance of</em>:</p><pre>if (obj instanceof String) {<br>    String s = (String) obj;<br>    // use s<br>}</pre><p>Now with a small addition to instance of we can immediately start using that object, without need for explicit casting</p><pre>if (obj instanceof String s) {<br>    // can use s here<br>} else {<br>    // can&#39;t use s here<br>}</pre><p><a href="https://openjdk.java.net/jeps/359"><strong>Records (Preview)</strong></a></p><p>Records provide a compact syntax for declaring classes which are transparent holders for shallowly immutable data. Read more at <a href="https://dzone.com/articles/a-first-look-at-records-in-java-14">https://dzone.com/articles/a-first-look-at-records-in-java-14</a></p><p><a href="https://openjdk.java.net/jeps/368"><strong>Text Blocks (Second Preview)</strong></a></p><p>A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired. Read more at <a href="https://www.baeldung.com/java-text-blocks">https://www.baeldung.com/java-text-blocks</a></p><p><a href="https://openjdk.java.net/jeps/343"><strong>Packaging Tool (Incubator)</strong></a></p><p>Simple packaging tool, based on the JavaFX javapackager tool, that:</p><ul><li>Supports native packaging formats to give end users a natural installation experience. These formats include msi and exe on Windows, pkg and dmg on macOS, and deb and rpm on Linux.</li><li>Allows launch-time parameters to be specified at packaging time.</li><li>Can be invoked directly, from the command line, or programmatically, via the ToolProvider API.</li></ul><p><a href="https://openjdk.java.net/jeps/370"><strong>Foreign-Memory Access API (Incubator)</strong></a></p><p>API that allows Java programs to safely and efficiently access foreign memory outside of the Java heap (like native memory, persistent memory, managed heap memory, etc.).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24b990f40be1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/whats-new-in-java-14-24b990f40be1">What’s new in Java 14</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What’s new in Java 13]]></title>
            <link>https://medium.com/hybriditsolutions/whats-new-in-java-13-7637a66e1e20?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/7637a66e1e20</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java-13]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Tue, 28 Jan 2020 15:48:59 GMT</pubDate>
            <atom:updated>2020-01-29T10:28:31.209Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DKWs7Vo7ChflEUKhdVWPcw.png" /></figure><p>In this article, we will cover changes that came with Java version 13.</p><p><a href="https://openjdk.java.net/jeps/350"><strong>Dynamic CDS Archives</strong></a><strong><br></strong>This feature enhances the Application Class Data sharing which was introduced in Java 10. The idea behind this feature is to improve startup performance by creating class-data archive that JVM can reuse. <br>Read more at <a href="https://blog.codefx.org/java/application-class-data-sharing/">https://blog.codefx.org/java/application-class-data-sharing/</a></p><p><a href="https://openjdk.java.net/jeps/351"><strong>ZGC: Uncommit Unused Memory</strong></a><strong><br></strong>The <a href="https://openjdk.java.net/jeps/333">JEP 333: Z Garbage Collector</a> is introduced in Java 11, it provides a short pause times when cleaning up heap memory. However, it didn’t return unused heap memory to the operating system, even when that memory has been unused for a long time.</p><p>This JEP enhanced the ZGC by returning unused heap memory to the operating system.</p><p><a href="https://openjdk.java.net/jeps/353"><strong>Reimplement the Legacy Socket API</strong></a><strong><br></strong>The old default implementation of Socket API (PlainSocketImpl) dates back to java 1.0 and is really hard to debug and maintain. In Java 13 it is replaced with NioSocketImpl. If for some reason we need still to use PlainSocketImpl we can do it by passing -Djdk.net.usePlainSocketImpl to JVM.</p><p><a href="https://openjdk.java.net/jeps/354"><strong>Switch Expressions (Preview)</strong></a><strong><br></strong>Switch expressions were introduced in Java 12 as a preview feature. <br><em>(</em><strong><em>Preview feature</em></strong><em> is a new concept introduced in Java 12. A preview language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent.)<br></em>The impermanent nature of preview features can be seen through changes that came with Java 13. With Java 12 we could use <strong><em>break</em></strong> to return value from a switch expression. Now, break is no longer compiled and we should use <strong><em>yield.<br></em></strong>Java 12:</p><pre>String numberOfDays = switch (month) {<br>            case 2:<br>                break &quot;28&quot;;<br>            case 4, 6, 9, 11:<br>                break &quot;30&quot;;<br>            default:<br>                break &quot;31&quot;;<br>        };</pre><p>Java 13:</p><pre>String numberOfDays = switch (month) {<br>            case 2:<br>                yield &quot;28&quot;;<br>            case 4, 6, 9, 11:<br>                yield &quot;30&quot;;<br>            default:<br>                yield &quot;31&quot;;<br>        };</pre><p>Note: switch expressions is <strong>still a preview feature </strong>and they can change more in the following versions.</p><p><a href="https://openjdk.java.net/jeps/355"><strong>Text Blocks (Preview)</strong></a></p><p>This feature gives us a possibility to instantiate String as a text block. <br>Text blocks are surrounded with ””” (triple quotation marks).</p><p>The old way of writing text blocks:</p><pre>String jsonExample =&quot;{\n&quot; +<br>                        \&quot;region\&quot;:\&quot;lika\&quot;<br>                    &quot;}\n&quot;;</pre><p>The new way of writing text blocks:</p><pre>String jsonExample = &quot;&quot;&quot;<br>                      {<br>                        &quot;region&quot;:&quot;lika&quot;<br>                      }<br>                     &quot;&quot;&quot;;</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7637a66e1e20" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/whats-new-in-java-13-7637a66e1e20">What’s new in Java 13</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[After Java 8: Part 5 — Java 12]]></title>
            <link>https://medium.com/hybriditsolutions/after-java-8-part-5-java-12-aca181d69276?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/aca181d69276</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[openjdk]]></category>
            <category><![CDATA[java12]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Mon, 13 Jan 2020 12:40:58 GMT</pubDate>
            <atom:updated>2020-01-13T13:56:07.599Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CtDiHyKhIcb18E5WH9r9yw.png" /></figure><h3>After Java 8: Part 5 — Java 12</h3><p>In the <a href="https://medium.com/hybriditsolutions/after-java-8-part-4-java-11-44313341eb37">previous article</a>, we covered changes in Java 11. In this article, we will discuss changes in the language that came with version 12.</p><h3>API Updates</h3><h4><strong>New String Methods in preparation for raw strings</strong></h4><ul><li><strong><em>String::indent</em></strong></li></ul><pre><strong>public </strong><a href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/String.html"><strong>String</strong></a><strong> indent​(int n)</strong></pre><pre>Adjusts the indentation of each line of this string based on the value of n, and normalizes line termination characters.</pre><pre><strong>Parameters:</strong>n - number of leading <a href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Character.html#isWhitespace(int)">white space characters</a> to add or remove<br><strong>Returns:</strong>string with indentation adjusted and line endings normalized</pre><ul><li><strong><em>String::transform</em></strong></li></ul><pre><strong>public &lt;R&gt; R transform​(</strong><a href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/function/Function.html"><strong>Function</strong></a><strong>&lt;? super </strong><a href="https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/String.html"><strong>String</strong></a><strong>,​? extends R&gt; f) </strong></pre><pre>This method allows the application of a function to this string. The function should expect a single String argument and produce an R result.<br>Any exception thrown by f() will be propagated to the caller.</pre><pre><strong>Type Parameters:</strong>R - class of the result<br><strong>Parameters:</strong>f - functional interface to a apply<br><strong>Returns:</strong>the result of applying the function to this string</pre><h4><strong>Compact Number Format</strong></h4><pre>NumberFormat shortNF = NumberFormat.getCompactNumberInstance()`<br>String short = shortNF.format(2000);<br>System.out.println(short) <br>// prints 2k</pre><p>Locale and decimals are configurable of course. Also, it is possible to create a custom compact number pattern.</p><h4><strong>The Teeing Collector</strong></h4><p>In short, Teeing Collector is a Collector that merges the results of two other collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.</p><pre>Stream&lt;Integer&gt; numbers = Stream.of(1,2,3,4,5);<br>long avarage = numbers.collect(<br>	Collectors.teeing(<br>		Collectors.summingInt(Integer::valueOf), <br>		Collectors.counting(), <br>		(sum, count) -&gt; sum/count<br>		)<br>	);<br>//avarage ==&gt; 3</pre><h4><strong>Files::mismatch</strong></h4><p>Checks if two files are the same. <br>Files.mismatch(Path.of(&quot;/file1&quot;), Path.of(&quot;/file1&quot;))<br>This method returns -1 if files are identical. Otherwise, it returns the position of first mismatching byte, or the size of the smaller file (in bytes) when the files are different sizes and every byte of the smaller file is identical to the corresponding byte of the larger file.</p><h3>Switch Expressions</h3><p>Switch expressions are the first “preview feature” in Java. <br><strong>Preview feature</strong> is a new concept introduced in Java 12. A preview language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent. It is similar to incubator modules. The difference is that incubator modules are referring to new APIs while, as already stated, preview features refer to a new language or VM features.<br>Enable incubator modules flag: --add-modules jdk.incubator.httpclient<br>Enable preview features flag: --enable-preview <br>In IntelliJ this can be done on: file/project structure/project language level and preferences/.../java compiler/additional command line parameters</p><p>Read more at <a href="https://blog.codefx.org/java/switch-expressions/">https://blog.codefx.org/java/switch-expressions/</a><br>Note that, as stated, preview features are yet impermanent and can change.</p><h3>Java Micro-benchmarking Harness JMH</h3><p>It measures execution time for small code pieces. It can be used to compare alternatives or to prevent performance regressions.</p><p>Advantages of JMH compared to ancient System.currentTimeMillis approach:</p><ul><li>JMH Handles JVM warm-up</li><li>Consistent reporting</li><li>Multithreading support</li></ul><p>Possible pitfalls of using JMH:</p><ul><li>Dead code elimination</li><li>Other compiler optimizations</li><li>Assumptions</li></ul><p>JMH has been developed as part of open jdk long time ago. In Java 12, JDK team added JMH and created a set of around 100 testsuites in JDK, making JMH defacto standard micro-benchmarking suite.<br>Note that JMH is still a separate project. If you want to include it to your project have a look at:<br><a href="https://openjdk.java.net/projects/code-tools/jmh/">Official project page</a><br><a href="https://gist.github.com/msievers/ce80d343fc15c44bea6cbb741dde7e45">Example integration with spring boot</a></p><h3>JVM Changes</h3><h4>G1 improvements</h4><p>Promptly return unused committed memory. The main goal for this feature is to improve the G1 garbage collector to immediately return Java heap memory to the operating system when inactive. To achieve this goal G1 will during low application activity periodically generate or continue a concurrent cycle to check the complete Java heap usage.</p><p>This will trigger it to immediately return unused Java heap portions to the operating system. When under user control, there’s an option to perform a full GC to maximise the volume of memory returned.</p><h3>Shenandoah</h3><p>Shenandoah is an experimental, low-pause-time garbage collector which targets large heap applications. It is contributed by Red Hat, and for some reason Oracle excludes it from their Open JDK build.<br>According to Red Hat, pause times are no longer in direct proportion with the size of the heap. In theory, this means that a heap that’s 2 GB could have the same pause time as a heap that’s 200 GB. You can read more about Shenandoah at <a href="https://wiki.openjdk.java.net/display/shenandoah/Main">https://wiki.openjdk.java.net/display/shenandoah/Main</a></p><h3>JVM Constants API</h3><p>This is a Low-level JVM feature that can be helpful for tools that manipulate classes and methods.<br>Read more at <a href="https://cr.openjdk.java.net/~vromero/constant.api/javadoc.04/java/lang/invoke/constant/package-summary.html">https://cr.openjdk.java.net/~vromero/constant.api/javadoc.04/java/lang/invoke/constant/package-summary.html</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aca181d69276" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/after-java-8-part-5-java-12-aca181d69276">After Java 8: Part 5 — Java 12</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[After Java 8: Part 4 — Java 11]]></title>
            <link>https://medium.com/hybriditsolutions/after-java-8-part-4-java-11-44313341eb37?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/44313341eb37</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java11]]></category>
            <category><![CDATA[openjdk]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Mon, 09 Dec 2019 10:00:41 GMT</pubDate>
            <atom:updated>2019-12-09T11:22:48.604Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cdRj06QU10Rr54Jya7zmrg.png" /></figure><h3>After Java 8: Part 4 — Java 11</h3><p>In the <a href="https://medium.com/hybriditsolutions/after-java-8-part-3-java-10-f22e017689ad">previous article</a>, we covered changes in Java 10. In this article, we will discuss changes in the language that came with version 11.</p><h3>Launching single source code file</h3><p><a href="http://openjdk.java.net/jeps/330"><em>JEP 330</em></a></p><p>Before Java 11 in order to run Java program, we would need to compile it first using <em>javac</em> and then run class file we got using <em>java</em> command.</p><p>With Java 11 we can run java program directly from source. <br>java Hello.java</p><p>The Java launcher will identify that the file contains Java source code and will compile the code into memory before executing it.<br>Parameters placed after the name of the source file are passed as parameters when executing the application. <br>Parameters placed before the name of the source file are passed as parameters to the Java launcher after the code has been compiled. This allows for things like the classpath to be set on the command line. <br>Parameters that are relevant to the compiler (such as the classpath) will also be passed to javac for compilation.</p><p>To further simplify things Java 11 comes with “<a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>” support.</p><p>Just add shebang line at the beginning of your script: <br> #!/usr/bin/java --source 11 <br>Make the script executable: <br>chmod +x ShebangDemo <br>And run it: <br> ./ShebangDemo .</p><p><a href="https://github.com/MiodragB/after-java-eight/blob/master/ShebangDemo"><strong>Demo</strong></a></p><h3><strong>Removed Enterprise APIs</strong></h3><p>With the introduction of Java Platform Module System in JDK 9, it was possible to divide the monolithic rt.jar file into multiple modules. An additional advantage of JPMS is it is now possible to create a Java runtime that only includes the modules you need for your application, reducing the size considerably. With cleanly defined module boundaries, it is now simpler to remove parts of the Java API that are outdated. This is what this JEP does; the java.se.ee meta-module includes six modules that will no longer be part of the Java SE 11 standard and not included in the JDK. The affected modules are:</p><ul><li>JAXB</li><li>JAX-WS</li><li>JAX-WS Annotations</li><li>CORBA</li><li>JTA</li></ul><p>More info in <a href="http://openjdk.java.net/jeps/320">JEP 320</a></p><ul><li><strong>Removed methods</strong></li></ul><p>Thread class lost destroy() and stop(Throwable) <br>Methods related to object finalizers have been removed</p><ul><li><strong>JavaFX moved to OpenJFX</strong></li><li><strong>Applets are finally removed</strong></li><li><strong>Java Web Start is removed</strong></li><li><strong>Nashorn has been deprecated</strong></li></ul><h3>Language and library improvements</h3><h3>HTTP2 client is moved from the incubator module to java.net.</h3><p>JDK 9 introduced a new API to provide support for the HTTP Client protocol (JEP 110). Since JDK 9 introduced the Java Platform Module System (JPMS), this API was included as an incubator module. <em>(Incubator modules are intended to provide new APIs without making them part of the Java SE standard. Developers can try the API and provide feedback. Once any necessary changes have been made (this API was updated in JDK 10), the API can be moved to become part of the standard.)</em></p><p>The HTTP Client API is now part of the Java SE 11 standard. This introduces a new module and package to the JDK, java.net.http.<br>The main types defined are: HttpClient; HttpRequest; HttpResponse; WebSocket<br>The API can be used synchronously or asynchronously. The asynchronous mode makes use of CompletableFutures and CompletionStages</p><p><a href="https://github.com/MiodragB/after-java-eight/blob/master/src/main/java/com/mbrkljac/afterjavaeight/java11/HttpClientDemo.java">HttpClientDemo</a></p><h3>Small library additions</h3><ul><li>String::repeat()</li><li>String::isBlank()</li><li>String::strip()</li><li>String::lines()</li><li>Files::readString()</li><li>Files::writeString()</li><li>Upgrade from Unicode 8 to 10</li></ul><p>Full list of API changes: <a href="https://gunnarmorling.github.io/jdk-api-diff/jdk10-jdk11-api-diff.html">https://gunnarmorling.github.io/jdk-api-diff/jdk10-jdk11-api-diff.html</a></p><h3>Performance and security improvements</h3><h4>Epsilon GC</h4><ul><li>No-Op experimental garbage collector. Handles memory allocation but does not implement any actual memory reclamation mechanism. Once the available Java heap is exhausted, the JVM will shut down</li><li>To be used for apps with predictable, bounded memory usage; Short-lived programs and performance testing</li><li>-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC</li></ul><h4><a href="https://www.opsian.com/blog/javas-new-zgc-is-very-exciting/"><strong>Z Garbage Collector</strong></a></h4><ul><li>Pause times under 10ms</li><li>No pause time increase with heap size increase</li><li>Scale to the multi-terabyte heap size</li><li>Linux/x64 only</li><li>-XX:+UnlockExperimentalVMOptions -XX:+UseZGC</li></ul><h3>TLS 1.3 is supported</h3><ul><li>Legacy algorithms pruned</li><li>All handshake messages except first are encrypted</li><li>Elliptic curve algorithms in the base specification</li><li>Not all of TLS 1.3 are implemented see more at JEP 332</li></ul><h3>Local-Variable Syntax for Lambda Parameters</h3><p>JDK 10 introduced the Local-Variable Type Inference. Java 11 extends the use of this syntax to the parameters of Lambda expressions. Since Lambda expressions already have type inference, this feature is mostly used when we want to add an annotation to the Lambda parameter.<br>Simple example:</p><pre>list.stream()<br>     .map((@Notnull var t) -&gt; t.toLowerCase())<br>     .collect(Collectors.toList())</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=44313341eb37" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/after-java-8-part-4-java-11-44313341eb37">After Java 8: Part 4 — Java 11</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[After Java 8: Part 3— Java 10]]></title>
            <link>https://medium.com/hybriditsolutions/after-java-8-part-3-java-10-f22e017689ad?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/f22e017689ad</guid>
            <category><![CDATA[java]]></category>
            <category><![CDATA[java10]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Fri, 29 Nov 2019 14:45:55 GMT</pubDate>
            <atom:updated>2019-11-29T15:08:25.165Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jNNLxbHXjIOcNYkXCmOx4Q.png" /></figure><h3>After Java 8: Part 3 — Java 10</h3><p>This is the third in a series of articles about changes in Java ecosystem after version 8. In the <a href="https://medium.com/hybriditsolutions/after-java-8-part-2-java-9-c0824eca31dd">previous article</a>, we covered changes in java 9. In this article, we will discuss changes in the language that came with version 10.</p><p>Java 10 is released in March 2018, it is non LTS release with the end of support in September 2018 for Oracle Open JDK and Oracle JDK. It is the first release in the new 6 months release cycle and therefore contains only minor, incremental changes.</p><h3>Local variable type inference</h3><p>Java 10 introduced <strong><em>var</em></strong> as a reserved type name that can be used to initialise local variable without declaring it explicitly. The idea of <strong><em>var</em></strong> is to reduce boilerplate code and increase readability.</p><pre>//declaring variable explicitly<br>BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(&quot;path/file&quot;));</pre><pre>//using var<br>var someString = &quot;someString&quot;;</pre><p><strong>At compile time, the compiler infers a type based on the initialisation statement.</strong></p><pre>//var after compilation <br>String someString = &quot;someString&quot;;</pre><p>From Java 10, creating class or interface with name var is not possible because var is a reserved type name. However, class or interface with name Var (upper case ) can be created.</p><pre>public class var {<br>    //compile error: var cannot be used for type declarations<br>} <br>public class Var {<br>   //compiles successfully <br>}</pre><h4>How var cannot be used in code:</h4><ul><li>var cannot be used as a field type, method parameter type or constructor parameter type.</li><li>Because var is a reserved type name, methods and fields can be named var</li></ul><pre>class SomeClass {<br>   private int var;<br>   public void var() {<br>   }   <br> }</pre><ul><li>var must be initialized</li></ul><pre>//compile error, var must be initialised<br>var x;</pre><ul><li>var cannot be referenced to a null</li></ul><pre>//compile error, cannot infer type, var initialiser is null <br>var x = null;</pre><ul><li>var is not allowed in a compound declaration.</li></ul><pre>//compile error, cannot infer type<br> var i, j =0;</pre><ul><li>var cannot replace the type of lambda expression</li></ul><pre>var lambda = x -&gt; x &gt; 3</pre><h4>How to and how not to use war:</h4><p>Think twice before using it. Does it really add to readability off your code?</p><p>If you decide to use it, here are some advices that can help you to use it better, and to annoy the person who will be doing maintenance of that code a little bit less:</p><ul><li>Choose a good variable name</li></ul><pre>var x = dbConnection.executeQuery(query);  //bad example</pre><pre>var users = dbConnection.executeQuery(query); //good example</pre><ul><li>Use good initializer information</li></ul><pre>var user = get();  //bad example</pre><pre>var users = getUsers(); //good example</pre><pre>var user = getUser(); //good example</pre><ul><li>Take care with &lt;&gt;</li></ul><pre>var users = new ArrayList&lt;&gt;();  //bad example - ArrayList&lt;Object&gt; is inferred</pre><pre>var users = new ArrayList&lt;User&gt;(); //good example - ArrayList&lt;User&gt; is inferred</pre><ul><li>don’t use var for initialising anonymous object</li></ul><pre>var object = new Object(){} // the type of the object variable is Object$1 extends Object</pre><pre>object = new Object(); // won&#39;t compile, object type isn&#39;t compatible with Object$1 which is inferred type of the variable</pre><ul><li>intersection types</li></ul><pre>var list = List.of(1, 2.0, &quot;3&quot;);</pre><pre>// type =&gt; List&lt;Serializable &amp; Comparable&lt;? extends Serializable &amp; Comparable&lt;?&gt;&gt;&gt;</pre><h3>OrElseThrow</h3><p>Java 8 introduced Optional API for preventing the NullPointerException by wrapping the object that we suspect may be null. Java 10 introduced orElseThrow() method which can be called on object type Optional and it will throw NoSuchElementException if object inside the Optional is null.</p><pre>Optional&lt;String&gt; optional = Optional.empty();</pre><pre>optional.orElseThrow() // Will throw NoSuchElementException</pre><h3>APIs for creating unmodifiable collections</h3><p>Java 10 added List.copyOf, Set.copyOf, Map.copyOf for creating the unmodifiable collection with copied instances of other collection</p><pre>var cars = new ArrayList&lt;String&gt;(List.of(&quot;Opel&quot;, &quot;Mercedes&quot;, &quot;Toyota&quot;));</pre><pre>var unmodifiableCarList = List.copyOf(cars);</pre><pre>unmodifiableCarList.add(&quot;Audi&quot;); //Will throw UnsupportedOperationException</pre><p>Difference between Collections.unmodifiableList(cars) and List.copyOf(cars)</p><pre>var cars = new ArrayList&lt;&gt;(List.of(&quot;Opel&quot;, &quot;Mercedes&quot;, &quot;Toyota&quot;));</pre><pre>var unmodifiableList = Collections.unmodifiableList(cars);</pre><pre>var unmodifiableCopiedList = List.copyOf(cars);<br>cars.add(&quot;Haudi&quot;);</pre><pre>System.out.println(&quot;Unmodifiable list: &quot; + unmodifiableList);<br>System.out.println(&quot;Unmodifiable copied list: &quot; + unmodifiableCopiedList);<br>/* <br>      Output:<br>      Unmodifiable list: [Opel, Mercedes, Toyota, Haudi]<br>      Unmodifiable copied list: [Opel, Mercedes, Toyota]<br> */</pre><p>Also, unmodifiable collection can be created from stream using Collectors.toUnmodifiableList, Collectors.toUnmodifiableSet, Collectors.toUnmodifiableMap</p><pre>var collectionFromStream = list.stream().collect(Collectors.toUnmodifiableList());<br>    <br>collectionFromStream.add(&quot;test&quot;); //Will throw UnsupportedOperationException</pre><h3>Other improvements</h3><ul><li><a href="https://www.baeldung.com/graal-java-jit-compiler"><strong>Graal</strong></a><strong> As a result of </strong><a href="https://openjdk.java.net/jeps/243"><strong>JVM Compiler Interface</strong></a><strong> </strong>introduced in java 9</li></ul><p>Graal compiler is written entirely in java (unlike C1 and C2 compilers that are written in C). Since it uses JVM Compiler Interface to communicate with VM it can be used with both HotSpot VM as well as Graal VM. More about GraalVM and Graal Compiler: <a href="https://www.graalvm.org/">https://www.graalvm.org/</a> , <a href="https://github.com/oracle/graal/">https://github.com/oracle/graal/</a></p><pre>-XX:+UnlockExperimentalVMOptions <br>-XX:+EnableJVMCI <br>-XX:+UseJVMCICompiler</pre><ul><li><strong>G1GC improvements</strong></li></ul><p>Mainly introduction of full parallel processing during a Full GC. This change won’t help the best-case performance times of the garbage collector, but it does significantly reduce the worst-case latencies.</p><ul><li><strong>Thread-local handshakes</strong></li></ul><p>During serviceability operations, like collecting stack traces for all threads or performing garbage collections, when the JVM needed to pause one thread, it needed to stop them all. Sometimes, these are referred to as “stop-the-world” pauses. This was due to the JVM wanting to create a global safepoint from which all application threads could begin again once the JVM was done. In Java 10, though, the JVM can put an arbitrary number of threads into a safepoint, and threads may continue running after performing the prescribed “handshake”. The result is that if the JVM can pause just one thread at a time, whereas before it had to pause them all.</p><ul><li><strong>Container awareness</strong></li></ul><p>Before java was not container aware. So, in case you had you java app running in Docker, and for some reason you didn’t set max heap size on app startup, JVM would allocate 1/4 of memory available on host. So, in case you had 10 docker containers running on the same host, and each of them taking 1/4 of available host memory things will go wrong quite fast.</p><p>Now, if you wish to have your app aware of space allocated to container where it runs, you should pass following params on startup:</p><p>-XX:+UseCGroupMemoryLimitForHeap <br>-XX:ActiveProcessorCount=xy</p><p>Where xy is number of processor cores that container is using.</p><ul><li><strong>Alternative memory allocation</strong></li></ul><p>-XX:AllocateHeapAt=&lt;path&gt;</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f22e017689ad" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/after-java-8-part-3-java-10-f22e017689ad">After Java 8: Part 3— Java 10</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[After Java 8: Part 2 — Java 9]]></title>
            <link>https://medium.com/hybriditsolutions/after-java-8-part-2-java-9-c0824eca31dd?source=rss----af2270351fe4---4</link>
            <guid isPermaLink="false">https://medium.com/p/c0824eca31dd</guid>
            <category><![CDATA[java9]]></category>
            <category><![CDATA[jdk]]></category>
            <category><![CDATA[java]]></category>
            <category><![CDATA[project-jigsaw]]></category>
            <dc:creator><![CDATA[MiodragBrkljac]]></dc:creator>
            <pubDate>Tue, 19 Nov 2019 13:36:35 GMT</pubDate>
            <atom:updated>2019-11-20T11:34:17.870Z</atom:updated>
            <cc:license>http://creativecommons.org/publicdomain/zero/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="Java 9 modular Hybrid IT solutions" src="https://cdn-images-1.medium.com/max/1024/1*PWYhghiKFqL6ZRqiOFtntA.png" /></figure><h3>After Java 8: Part 2 — Java 9</h3><p>This is the second in a series of articles about changes in Java ecosystem after version 8. In the <a href="https://medium.com/hybriditsolutions/after-java-8-part-1-licences-and-release-cadence-3605f47eaadf">previous article</a>, we covered changes in licensing and release cadence. In this article, we will discuss changes in the language itself that came with version 9.</p><h3>Java 9</h3><p>Java 9 is released in September 2017 and it is non LTS release, with the end of support scheduled for March 2018, it brought probably the biggest changes to Java ecosystem in the last 10 years.</p><h3>Module system</h3><p>A huge amount of credits for making Java 9 release with the biggest changes in the last 10 years go to the module system. It was initially planned for Java 7, but postponed for 8 and subsequently to 9. It is one of the biggest changes in Java ever, since it does not affect only language itself but also a compiler, VM, and Tooling.</p><p>Module system is a result of project <a href="http://openjdk.java.net/projects/jigsaw/">Jigsaw</a>. The first and main reason for this feature is to modularize JDK itself, make it maintainable again. Second (and to be honest a lot smaller) reason is to enable developers to modularize their own applications. Of course, modularizing applications is purely optional, but still, they run on modular JDK.<br><strong><em>JDK becoming too large is the main motivation behind the module system.</em></strong> Now, there are more than 90 platform modules.</p><h3>Migration</h3><p><strong><em>Easy unless:</em></strong><br><strong>1. You or some libs use JDK types that have been encapsulated.<br></strong>They will still run, but they will not compile… This can change in the next versions. If you want, you can enforce encapsulation in runtime by passing the following flag to jvm:<strong><em> </em></strong><strong><em>--illegal-access=deny</em></strong> You can bypass encapsulation at compile time by using <strong><em>-add-exports $moduleYouNeed/$packageYouNeed=$yourModule</em></strong><br>This command line option exports $packageYouNeed of $moduleYouNeed to $yourModule. Code in $yourModule can hence access all public types in $packageYouNeed but other modules can not.<br>This option is available for the java and javac commands. Although it is for now not necessary for java command, since as stated app will still run. But again, this is something that can change in the future.</p><p>When setting $yourModule to ALL-UNNAMED, all code from the classpath can access that package. This is a preferred way to go when accessing internal APIs during migration to Java 9. Example:<br>javac --add-exports java.base/sun.security.x509=ALL-UNNAMED Main.java</p><p>If you have trouble migrating there is a handy tool shipped with JDK to help you. <strong>jdeps -jdkinternals</strong> target/classes/com/mbrkljac/javaaftereight/HttpClientDemo.class Using this tool you can check dependencies without running or compiling. It also suggests solutions for potential problems it finds.</p><p><strong>2. You or some lib use types from non-default Java modules (java.se.ee</strong>) This can be mitigated using: javac --add-modules java.xml.bind Main.java and java --add-modules java.xml.bind Main</p><p>More info about jdeps: <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html">https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html</a></p><h3>Module system implementation</h3><p>Module has a name, it groups related code as well as resources and is fully self-contained.<br>Every module has a module descriptor which consists of:</p><ul><li>Module’s name</li><li>Module’s dependencies (that is, other modules this module depends on)</li><li>Packages it explicitly makes available to other modules (all other packages in the module are implicitly unavailable to other modules)</li><li>services it offers</li><li>services it consumes</li><li>to what other modules it allows reflection</li><li>…</li></ul><p>A module descriptor is the compiled version of a module declaration that’s defined in a file named module-info.java. Module descriptor is stored in a file named module-info.class in the module’s root folder. Each module declaration begins with the keyword module, followed by a unique module name and a module body enclosed in braces, as in:</p><pre>module modulename {}</pre><p>The module declaration’s body can be empty or may contain various module directives like:</p><ul><li><strong><em>requires</em></strong>. A requires module directive specifies that this module depends on another module — this relationship is called a module dependency. Each module must explicitly state its dependencies. When module A requires module B, module A is said to read module B and module B is read by module A. To specify a dependency on another module, use requires, as in:</li></ul><p>requires modulename;</p><ul><li><strong><em>requires transitive</em></strong> — implied readability. To specify a dependency on another module and to ensure that other modules reading your module also read that dependency — known as implied readability — use requires transitive, as in:</li></ul><p>requires transitive modulename;</p><ul><li><strong><em>exports and exports…to</em></strong><em>.</em> An exports module directive specifies one of the module’s packages whose public types (and their nested public and protected types) should be accessible to code in all other modules. An exports…to directive enables you to specify in a comma-separated list precisely which module’s or modules’ code can access the exported package — this is known as a qualified export.</li><li><strong><em>uses</em></strong>. A uses module directive specifies a service used by this module — making the module a service consumer. A service is an object of a class that implements the interface or extends the abstract class specified in the uses directive.</li><li><strong><em>provides…with</em></strong><em>. </em>A provides…with module directive specifies that a module provides a service implementation — making the module a service provider. The provides part of the directive specifies an interface or abstract class listed in a module’s uses directive and the with part of the directive specifies the name of the service provider class that implements the interface or extends the abstract class.</li><li><strong><em>open, opens, and opens…to</em></strong><em>. </em>Before Java 9, reflection could be used to learn about all types in a package and all members of a type — even its private members — whether you wanted to allow this capability or not. Thus, nothing was truly encapsulated.<br>A key motivation of the module system is strong encapsulation. By default, a type in a module is not accessible to other modules unless it’s a public type and you export its package. You expose only the packages you want to expose. With Java 9, this also applies to reflection, allowing runtime-only access to a package. An opens module directive of the form opens package<br>indicates that a specific package’s public types (and their nested public and protected types) are accessible to code in other modules at runtime only. Also, all the types in the specified package (and all of the types’ members) are accessible via reflection.</li><li>Allowing runtime-only access to a package by specific modules. An opens…to module directive of the form opens package to comma-separated-list-of-modules indicates that a specific package’s public types (and their nested public and protected types) are accessible to code in the listed modules at runtime only. All of the types in the specified package (and all of the types’ members) are accessible via reflection to code in the specified modules.</li><li>Allowing runtime-only access to all packages in a module. If all the packages in a given module should be accessible at runtime and via reflection to all other modules, you may open the entire module, as in: open module modulename {// module directives}</li></ul><p>The keywords <em>exports</em>,<em> module, open, opens, provides, requires, uses, with</em>, as well as <em>to</em> and <em>transitive</em>, are restricted keywords. They’re keywords only in module declarations and may be used as identifiers anywhere else in your code.</p><p>Cyclic dependencies are not supported.</p><h4>Advantages:</h4><ul><li>Security (Module can expose some of its packages, and encapsulate other)</li><li>Reduced footprint</li><li>Easy deprecation (In java 9, java.corba was removed)</li><li><strong>Future proof </strong>(Incubator modules jdk.incubator.httpclient)</li><li>Improved performance — The JVM uses various optimization techniques to improve application performance. JSR 376 indicates that these techniques are more effective when it’s known in advance that required types are located only in specific modules.</li></ul><h3>JShell</h3><p><a href="https://docs.oracle.com/javase/9/jshell/JSHEL.pdf">https://docs.oracle.com/javase/9/jshell/JSHEL.pdf</a></p><p>JShell is a command line tool that provides interactive use of Java Programming Language elements. JShell is a REPL(Read -&gt; type code; Eval -&gt; execute code; Print -&gt; see results; Loop -&gt; interactively refine).<br>With it, we can enter program elements one at a time, immediately seeing the result and adjusting accordingly. It is mainly intended to be used to test out ideas, explore API’s as well as teaching.</p><p>Main features:</p><ul><li>It’s just plain java.</li><li>You get code completion,</li><li>it has built-in documentation.</li><li>It is possible to incrementally create code inside of jshell. (variable can be declared later)</li><li>It is possible to save and open snippets</li><li>Snippets can be edited using an external editor</li><li>JShell API enables IDE integration. (IntelliJ: Tools/JShell Console)</li></ul><h3>Library and Language Improvements</h3><p>Java 9 comes with some small extensions to existing java libraries. There are no major changes like in java 8, changes in module system are big enough for themselves.</p><h3>Collection factory methods</h3><p>Old ways:</p><pre>List&lt;String&gt; food  = new ArrayList&lt;&gt;();<br>food.add(&quot;Lamb&quot;);<br>food.add(&quot;Pork&quot;);<br>food.add(&quot;Beef&quot;);</pre><p>List&lt;String&gt; food = Arrays.asList(&quot;Lamb&quot;)<br>List&lt;String&gt; food = new ArrayList&lt;&gt;()<br>List&lt;String&gt; food = Collections.emptyList()</p><p>New way:<br>List&lt;String&gt; food = List.of(&quot;Lamb&quot;, &quot;Pork&quot;, &quot;Beef&quot;)<br>Set&lt;String&gt; strings = Set.of(&quot;One&quot;, &quot;Two&quot;)<br>Map&lt;String, Integer&gt; map = Map.of(&quot;One&quot;, 1, &quot;Two&quot;, 2)<br>Those methods return immutable collections and are heavily optimized. Note that <strong><em>iteration order for Set and Map is not guaranteed.</em></strong> (It was not guaranteed before also, but with the old approach, the order was mostly consistent. Now, that is not the case.)</p><h3>Stream API Improvements</h3><p>Added methods:<br><em>static Stream&lt;T&gt; ofNullable(T t)</em></p><pre>List&lt;String&gt; nullableList = getStringsPossibleNull();<br>//Old way</pre><pre>Stream strings = nullableList == null ? Stream.empty() : nullableList.stream();</pre><pre>//New way<br>Stream strings = Stream.offNullable(nullableList);</pre><p><em>Stream&lt;T&gt; takeWhile(Predicate&lt;? super T&gt; predicate)</em><br>TakeWhile is similar to filter in the sense that it expects a predicate and returns a new stream consisting only of the elements that match the given predicate. In an ordered stream, takeWhile takes elements from the initial stream while the predicate holds true. Meaning that when an element is encountered that does not match the predicate, the rest of the stream is discarded.<br>If the stream is unordered, if some of the elements in the stream match the predicate (but not all) then the operation is nondeterministic and an arbitrary subset of matching elements is returned or removed. If all elements match the predicate, all input will be returned. If none matches, the empty stream will be returned.</p><pre>jshell&gt; Stream.of(2, 4, 5, 6 ,8)<br>    .takeWhile(n -&gt; n % 2 == 0)<br>    .forEach(System.out::print);<br>// prints out: 24</pre><pre>jshell&gt; Set&lt;Integer&gt; numbers = Set.of(2, 4, 5, 6 ,8);<br>numbers.stream()<br>    .takeWhile(n -&gt; n % 2 == 0)<br>    .forEach(System.out::print);<br>//Prints out different result depending on how Set has been initialised</pre><pre>numbers ==&gt; [2, 8, 6, 5, 4]<br>286</pre><p><em>Stream&lt;T&gt; dropWhile(Predicate&lt;? super T&gt; predicate)</em> dropWhile is the opposite of takeWhile. It drops the element until the first element that matches the predicate, and includes the rest in the result stream;</p><p><em>static Stream&lt;T&gt; iterate(T seed, Predicate&lt;? super T&gt; hasNext, UnaryOperator&lt;T&gt; next)</em> Overloaded iterate method, added hasNext parameter which is used to determine when the Stream must terminate.</p><pre>jshell&gt; Stream.iterate(0, i -&gt; i &lt; 9, i -&gt; i + 1)<br>  .forEach(System.out::print);<br>//Prints out: 012345678</pre><h3>New Collectors:</h3><h4>filtering</h4><p>The Collectors.filtering is similar to the Stream filter(); it’s used for filtering input elements but used for different scenarios. The Stream’s filter is used in the stream chain, whereas the filtering is a Collector that was designed to be used along with groupingBy.</p><p>With Stream’s filter, the values are filtered first and then it’s grouped. In this way, the values which are filtered out are gone and there is no trace of it. If we need a trace then we would need to group first and then apply filtering which actually the Collectors.filtering does.</p><p>The Collectors.filtering takes a function for filtering the input elements and a collector to collect the filtered elements:</p><pre>jshell&gt; <br>    List&lt;Integer&gt; numbers = List.of(1, 2, 3, 5, 5);<br> <br>    Map&lt;Integer, Long&gt; result = numbers.stream()<br>      .filter(val -&gt; val &gt; 3)<br>      .collect(Collectors.groupingBy(i -&gt; i, Collectors.counting()));<br>  <br>    result = numbers.stream()<br>      .collect(Collectors.groupingBy(i -&gt; i,<br>        Collectors.filtering(val -&gt; val &gt; 3, Collectors.counting())));</pre><p><strong>flatMapping</strong></p><p>The Collectors.flatMapping is similar to Collectors.mapping but has a more fine-grained objective. Both the collectors take a function and a collector where the elements are collected but flatMapping function accepts a Stream of elements which is then accumulated by the collector.</p><h3>Additions to optional</h3><ul><li><strong><em>ifPresentOrElse</em></strong><br>public void ifPresentOrElse(Consumer&lt;? super T&gt; action, Runnable emptyAction)<br>Example:<br>Optional&lt;String&gt; value = Optional.of(&quot;someValue&quot;); value2.ifPresentOrElse(v -&gt; System.out.println(v), () -&gt; System.out.println(&quot;empty&quot;));</li><li><strong><em>or</em></strong><br>Used when we want to execute some other action that also returns an Optional.<br>Prior to Java 9, the Optional class had only the orElse() and orElseGet() methods but both need to return unwrapped values.<br>Java 9 introduces the or() method that returns another Optional lazily if our Optional is empty. If our first Optional has a defined value, the lambda passed to the or() method will not be invoked, and value will not be calculated and returned:<br>Optional&lt;String&gt; result = value.or(() -&gt; defaultValue);</li><li><strong><em>stream<br></em></strong>Added to achieve interoperability between Optional and Stream. Calling stream() on empty optional will result in an empty stream.<br>Quite useful in combination with Stream.flatMap</li></ul><pre>List&lt;Optional&lt;String&gt;&gt; listOfOptionals = Arrays.asList(Optional.empty(), Optional.of(&quot;foo&quot;),<br> Optional.empty(), Optional.of(&quot;bar&quot;));  <br>  <br> // Java 8:</pre><pre>List&lt;String&gt; filteredList = listOfOptionals.stream()<br>   .flatMap(o -&gt; o.isPresent() ? Stream.of(o.get()) : Stream.empty())<br>   .collect(Collectors.toList());</pre><pre>//Java 9:  <br>`List&lt;String&gt; filteredList = listOfOptionals.stream()<br>   .flatMap(Optional::stream)<br>   .collect(Collectors.toList());</pre><h3>java.time improvements</h3><ul><li>long dividedBy(Duration divisor)</li><li>Duration truncatedTo(TemporalUnit unit)</li><li>static Clock systemUTC() -&gt; can be accurate in nanoseconds depending on platform.</li><li>Stream datesUntil(LocalDate endExclusive, Period step) &amp;&amp; Stream datesUntil(LocalDate endExclusive)</li></ul><h3>Other small improvements</h3><ul><li><strong>Single underscore as an identifier is now illegal.</strong></li><li><strong>Try-with-resources improvements</strong> With the old approach, a new variable was required:</li></ul><pre>public void doWithFileInputStream(FileInputStream fis) {<br>	try(FileInputStream fis2 =fis) {<br>		fis2.read();<br>	}<br>}</pre><p>New approach:</p><pre>public void doWithFileInputStream(FileInputStream fis) {<br>	try(fis) {<br>		fis.read();<br>	}<br>}</pre><p>Note: in order to use a variable in try statement, it needs to be effectively final. Effectively final variable is variable that either has the final keyword or is not reassigned within the method.</p><ul><li><strong>Private interface methods</strong></li><li><strong>Javadoc is HTML5 compliant, Search is added, modules documentation also added </strong><a href="https://docs.oracle.com/en/java/javase/12/docs/api/index.html">https://docs.oracle.com/en/java/javase/12/docs/api/index.html</a></li><li><strong>Localization improvements. Unicode 8.0 support.</strong></li><li><a href="http://openjdk.java.net/jeps/243"><strong>JVM Compiler Interface</strong></a></li></ul><h3>New APIs. Process API and Http2 API</h3><h3>Process API</h3><p>java.lang.Process Represents native processes created from Java java.lang.ProcessHandle Represents any native process on the operating system</p><p>ProcessHandle.of(123)<br>ProcessHandle.info()<br>ProcessHandle.allProcesses() -&gt; Returns a stream of a current snapshot of processes state…</p><p>Demo:<br><a href="https://github.com/MiodragB/after-java-eight/blob/master/src/main/java/com/mbrkljac/afterjavaeight/java9/ProcessHandleInfoDemo.java">ProcessHandleInfoDemo</a> <a href="https://github.com/MiodragB/after-java-eight/blob/master/src/main/java/com/mbrkljac/afterjavaeight/java9/ProcessHandleDestroyDemo.java">ProcessHandleDestroyDemo</a></p><h3>HttpClient API</h3><p>Supports HTTP/2 and WebSocket <br>Caveat: incubator module (They can change, and are not by default part of jdk.)<br>In order to use it pass following flag: --add-modules jdk.incubator.httpclient</p><h3>Reactive Streams (Flow API)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*5mLzfuPvYNihTlOn.png" /></figure><ul><li>Not meant as end-user API</li><li>Stream data with support for backpressure</li><li>Vendor-neutral specification (<a href="http://www.reactive-streams.org/">www.reactive-streams.org</a>)</li><li>Flow API: interfaces added to JDK</li><li>Interoperability for reactive projects like RxJava, Akka Streams</li><li>HttpClient implements Publisher/Subscriber interfaces</li><li>java.util.concurrent.Flow support is implemented in RxJava 2, Spring 5, Akka Streams</li></ul><h3>StackWalker API</h3><p>Old way:<br>StackTraceElement[] stackTrace = Thread.getStackTrace()</p><ul><li>Low performance</li><li>No guarantee all stack elements are returned</li><li>No partial handling possible</li></ul><p>New way:</p><pre>StackWalker walker = StackWalker.getInstance();<br>walker.forEach()</pre><p>Demo:<br><a href="https://github.com/MiodragB/after-java-eight/blob/master/src/main/java/com/mbrkljac/afterjavaeight/java9/StackWalkerDemo.java">StackWalkerDemo</a></p><h3>Performance and security improvements</h3><h3>G1 Garbage Collector</h3><p>GC combinations deprecated in Java 8 were removed. CMS Collector is deprecated</p><ul><li>G1 (garbage first) garbage collector is introduced in java 6 and is now default when JVM is running in server mode (as opposed as running in client mode)</li></ul><p>To read more about server vs client JVM: <a href="https://javapapers.com/core-java/jvm-server-vs-client-mode/">https://javapapers.com/core-java/jvm-server-vs-client-mode/</a></p><p><strong>Important commands to remember for tuning G1:</strong></p><pre>--XX:MaxGCPauseMillis=200<br>--XX:+G1EnableStringDeduplication</pre><p>Concurrent Mark Sweep Heap structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/399/0*M_nQeEMZu6LJangh.png" /></figure><p>G1 Heap structure:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/0*kLypBNelqyuJc954.png" /></figure><p>G1 Heap allocation:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/0*YMAY9VUbvZMGDrIq.png" /></figure><p>Read more: <a href="https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html">https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html</a></p><h3>String performance</h3><ul><li>Compact strings</li><li>Lower memory usage without any code changes.</li><li>Strings in Java are internally represented by a char[] containing the characters of the String. And, every char is made up of 2 bytes because Java internally uses UTF-16. If a String contains a word in the English language, the leading 8 bits will all be 0 for every char, as an ASCII character can be represented using a single byte.</li><li><strong>As of Java 9, strings are stored as byte[] and not as char[]</strong></li><li>Final field coder is added. This field preserves information about encoding.</li><li>If encoding is LATIN1, single byte will be used to represent every char. In the case of UTF16, 2 bytes will be used.</li><li>This leads up to 15% less memory consumption.</li></ul><pre>/**<br>        * The identifier of the encoding used to encode the bytes in<br>        * {@code value}. The supported values in this implementation are<br>        *<br>        * LATIN1<br>        * UTF16<br>        *<br>        * @implNote This field is trusted by the VM, and is a subject to<br>        * constant folding if String instance is constant. Overwriting this<br>        * field after construction will cause problems.<br>        */<br>       private final byte coder;</pre><h4>Concatenation of Strings</h4><p>Before java9:</p><pre>String nemaRajaBez = &quot;rodnoga &quot; + &quot;kraja&quot;;</pre><p>Would result in:</p><pre>6:  new           #4      // class StringBuilder<br>9:  dup<br>10: invokespecial #5      // Method StringBuilder.&quot;&lt;init&gt;&quot;<br>13: aload_1	          // String rodnoga<br>14: invokevirtual #6      // Method StringBuilder.append:(LString;)LStringBuilder;             <br>17: aload_2		  // String kraja<br>18: invokevirtual #6      // Method StringBuilder.append:(LString;)LStringBuilder;</pre><pre>21: invokevirtual #7      // Method StringBuilder.toString:()LString;<br>....</pre><p>Java 9:</p><pre>6: aload_1		  // String rodnoga           <br>7: aload_2		  // String kraja<br>.....<br>8: invokedynamic #4, 0    // InvokeDynamic #0:makeConcatWithConstants:<br>                          // (LString;LString;)LString;</pre><pre>BootstrapMethods:<br>   0: #19 invokeStatic StringConcatFactory.makeConcatWithConstants:<br>     (… , … , LMethodType; , LString; , … ) LCallSite;<br>     Method arguments:<br>        #20 \u0001\u0001</pre><p>The reason to change the compiler now in this way is, from the project description, to “enable future optimizations of String concatenation without requiring further changes to the bytecode emitted by javac.”. Dynamic method invocation is an ideal solution for that challenge, as it delays method implementation to the runtime. The developers of the Java runtime can then improve the implementation of the factory class, without all other developers needing to recompile their projects.</p><p><a href="https://www.guardsquare.com/en/blog/string-concatenation-java-9-untangling-invokedynamic">https://www.guardsquare.com/en/blog/string-concatenation-java-9-untangling-invokedynamic</a></p><h3>Serialization</h3><p>There are numerous vulnerabilities related to serialization. Java 9 tries to address this by adding a new interface to filter data before deserializing.</p><pre>interface ObjectInputFilter {<br>	Status checkInput(FilterInput filterInput);<br>	enum Status {<br>		UNDECIDED,<br>		ALLOWED,<br>		REJECTED;<br>	}<br>}</pre><p><em>ObjectInoutStream::setObjectInputFilter </em>-&gt; per stream<br><em>ObjectInputFilter.Config.setSerialFilter</em> -&gt; for all streams</p><p>Alternatively, you can filter incoming serialization data without adding or changing code. For this, you can use <em>jdk.serialFilter</em> system property. This property is backported to Java 6/7/8</p><p><em>maxbytes=n; maxarray=n; maxdepth=n;</em><br><em>com.hybrid.dto</em>.<em>; (All types from this package can be serialized)<br>!com.someoneelse.</em>; (No types from this package can be serialized)</p><h3>Further reading:</h3><p><a href="https://docs.oracle.com/javase/9/whatsnew/toc.htm">https://docs.oracle.com/javase/9/whatsnew/toc.htm</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c0824eca31dd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hybriditsolutions/after-java-8-part-2-java-9-c0824eca31dd">After Java 8: Part 2 — Java 9</a> was originally published in <a href="https://medium.com/hybriditsolutions">HybridITSolutions</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>