<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Renato Fialho</title>
    <description>The latest articles on DEV Community by Renato Fialho (@fialhorenato).</description>
    <link>https://dev.to/fialhorenato</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F675958%2Ff509f3de-7835-4f99-8a21-00afb6ff7181.jpeg</url>
      <title>DEV Community: Renato Fialho</title>
      <link>https://dev.to/fialhorenato</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fialhorenato"/>
    <language>en</language>
    <item>
      <title>Java 19 and the new Virtual Threads</title>
      <dc:creator>Renato Fialho</dc:creator>
      <pubDate>Tue, 27 Sep 2022 13:59:21 +0000</pubDate>
      <link>https://dev.to/fialhorenato/java-19-and-the-new-virtual-threads-141n</link>
      <guid>https://dev.to/fialhorenato/java-19-and-the-new-virtual-threads-141n</guid>
      <description>&lt;p&gt;This post can be read &lt;a href="https://www.renatofialho.com/blog/working-with-new-virtual-threads-java-19"&gt;here&lt;/a&gt; as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  What?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jdk.java.net/19/release-notes"&gt;Java 19&lt;/a&gt; is coming, and with this new version of Java, it brings an amazing new feature, virtual threads.&lt;/p&gt;

&lt;p&gt;This update comes to reduce the effort of writing, maintaining, and observing high-throughput, concurrent applications.&lt;/p&gt;

&lt;p&gt;This is part of the &lt;a href="https://www.infoworld.com/article/3652596/project-loom-understand-the-new-java-concurrency-model.html"&gt;Project Loom&lt;/a&gt;, a project that aims to bring a new concurrency model to java, but preserving the same simple abstraction to the developers.&lt;/p&gt;

&lt;p&gt;Don't worry, you will still be able to use the platform threads.&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;Currently, those implementations are on preview mode, so you must provide the &lt;code&gt;--enable-preview&lt;/code&gt; flag to the JVM.&lt;/p&gt;

&lt;p&gt;If you are an IntelliJ user, you can tell IntelliJ to use this flag by going into the &lt;code&gt;Open Module Settings -&amp;gt; Project -&amp;gt; Language Level&lt;/code&gt; and choose the &lt;code&gt;Java 19 (Preview)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// Declare a runnable that will print the information about the current thread&lt;/span&gt;
    &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="n"&gt;printThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// Declare a virtual thread&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;virtualThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofVirtual&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printThread&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Declare a platform thread&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;platformThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofPlatform&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printThread&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nc"&gt;VirtualThread&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;]/&lt;/span&gt;&lt;span class="n"&gt;runnable&lt;/span&gt;&lt;span class="nd"&gt;@ForkJoinPool&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you see that we have a virtual thread executing on a worker thread of the Fork-Join pool, and another platform thread running on the main process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seamless integration between platform and virtual threads
&lt;/h2&gt;

&lt;p&gt;Synchronized blocks will work transparent in between virtual and platform threads, as it is shown in this example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VirtualThreads&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VirtualThreads&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;virtualThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofVirtual&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;platformThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofPlatform&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;virtualThread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" running command A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;wait&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" running command C"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;platformThread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" running command B"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;synchronized&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notifyAll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nc"&gt;VirtualThread&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;]/&lt;/span&gt;&lt;span class="n"&gt;runnable&lt;/span&gt;&lt;span class="nd"&gt;@ForkJoinPool&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="no"&gt;A&lt;/span&gt;
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt;
    &lt;span class="nc"&gt;VirtualThread&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;]/&lt;/span&gt;&lt;span class="n"&gt;runnable&lt;/span&gt;&lt;span class="nd"&gt;@ForkJoinPool&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loom and Java in general are prominently devoted to building web applications. Obviously, Java is used in many other areas, and the ideas introduced by Loom may well be useful in these applications. &lt;/p&gt;

&lt;p&gt;It’s easy to see how massively increasing thread efficiency, and dramatically reducing the resource requirements for handling multiple competing needs, will result in greater throughput for servers. Better handling of requests and responses is a bottom-line win for a whole universe of existing and to-be-built Java applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jdk.java.net/loom/"&gt;Project Loom&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoworld.com/article/3652596/project-loom-understand-the-new-java-concurrency-model.html"&gt;Infoworld&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>Learn SOLID design principles using Java</title>
      <dc:creator>Renato Fialho</dc:creator>
      <pubDate>Mon, 26 Sep 2022 15:40:04 +0000</pubDate>
      <link>https://dev.to/fialhorenato/learn-solid-design-principles-using-java-m68</link>
      <guid>https://dev.to/fialhorenato/learn-solid-design-principles-using-java-m68</guid>
      <description>&lt;p&gt;This post can be seen &lt;a href="https://www.renatofialho.com/blog/learning-SOLID-from-coding"&gt;here&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;The main idea from this article is to show the SOLID design principles and provide examples of implementations of those principles using Java as the main language.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SOLID?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;S.O.L.I.D&lt;/strong&gt; stands for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt;ingle Responsibility Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O&lt;/strong&gt;pen Closed Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L&lt;/strong&gt;iskov Substitution Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I&lt;/strong&gt;nterface Segregation Principle&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;D&lt;/strong&gt;ependency Inversion Principle&lt;/p&gt;

&lt;p&gt;Design principles in general helps us to write better software. And also improves the developer experience of the developers that share the same codebase with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Responsibility Principle
&lt;/h2&gt;

&lt;p&gt;A class should have only one responsibility.&lt;/p&gt;

&lt;p&gt;It helps into onboarding new members into the code, as well to test, maintain and grow our codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Imagine that you have a &lt;code&gt;UserService&lt;/code&gt; that is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create our user here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return our user&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendAppNotification&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Send an app notification&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Send an email&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happens if the requirements of this class change? What if now we must send a tex now we have to send an App Notification via push or SMS?&lt;/p&gt;

&lt;p&gt;Then, we must separate the concerns and responsability by creating a &lt;code&gt;NotificationService&lt;/code&gt; that will handle all of our communications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="n"&gt;notificationService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create our user here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return our user&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendSms&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Send SMS&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendPushNotification&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Send push&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Send email&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though it can have better approaches here, the idea is to separate concerns, the other solutions to solve this kind of problem is a different topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Closed Principle
&lt;/h2&gt;

&lt;p&gt;Software entities (classes, modules, functions, etc.) should be opened to extension but closed to modification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Think that we have an CoffeeApp class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;brewSimpleCoffee&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Put water&lt;/span&gt;
        &lt;span class="c1"&gt;// Put coffee powder&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;brewPremiumCoffee&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the bean&lt;/span&gt;
        &lt;span class="c1"&gt;// Grind the bean&lt;/span&gt;
        &lt;span class="c1"&gt;// Put water&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine that everytime our system needs to support a new type of coffee, we must change the Machine in order to add a new type.&lt;/p&gt;

&lt;p&gt;Lets use of simple abstraction and polymorphism to improve this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeApp&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CoffeeMachine&lt;/span&gt; &lt;span class="n"&gt;coffeeMachine&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;coffeeMachine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;brewCoffee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESPRESSO&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;CoffeeMachine&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="nf"&gt;brewCoffee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CoffeeSelection&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BasicCoffeeMachine&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CoffeeMachine&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;BrewingUnit&lt;/span&gt; &lt;span class="n"&gt;brewingUnit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="nf"&gt;brewCoffee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CoffeeSelection&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;brewFilterCoffee&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;brewFilterCoffee&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;brewingUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;brew&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PremiumCoffeeMachine&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;CoffeeMachine&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Grinder&lt;/span&gt; &lt;span class="n"&gt;grinder&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;BrewingUnit&lt;/span&gt; &lt;span class="n"&gt;brewingUnit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="nf"&gt;brewCoffee&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CoffeeSelection&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;ESPRESSO:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;brewEspresso&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nl"&gt;FILTER_COFFEE:&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;brewFilterCoffee&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;brewEspresso&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;grinder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;grind&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;brewingUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;brew&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;brewFilterCoffee&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;brewingUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;brew&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that class is opened for extension (ItalianMachine, ColombianMachine, FrenchPressMachine) and closed for modification (won’t have a method with a different logic being added every time a new machine is added to the app).&lt;/p&gt;

&lt;h2&gt;
  
  
  Liskov Substitution Principle
&lt;/h2&gt;

&lt;p&gt;A class can be replaced by its subclass in all practical usage scenarios, meaning that you should use inheritance only for substitutability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Using an Animal example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A dog can swim&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Swim&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// But a dog cannot fly&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hawk&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A hawk cannot swim&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// But a hawk can fly&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Fly&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though, both a &lt;code&gt;Dog&lt;/code&gt; and a &lt;code&gt;Hawk&lt;/code&gt; are animals, we can break up the inheritance to follow up this principle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A dog can swim&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Swim&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hawk&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A hawk can fly&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Fly&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interface Segregation Principle
&lt;/h2&gt;

&lt;p&gt;A client shouldn’t be forced to implement an interface that it doesn’t use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Thinking about the last example, even though a Dog can only swim, some &lt;code&gt;Animal&lt;/code&gt;s can swim and fly.&lt;/p&gt;

&lt;p&gt;Isn't easier if we just implement the interfaces like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Swimmer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Swimmer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A dog can swim&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Swim&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hawk&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A hawk can fly&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Fly&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Duck&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Swimmer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bird&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// A duck can fly&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
       &lt;span class="c1"&gt;// Fly&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// A duck can swim&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;swim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Swim&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dependency Inversion Principle
&lt;/h2&gt;

&lt;p&gt;We should invert the classic dependency between higher level modules and lower level modules, by abstracting their interaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Let's say we have some implementations over a database&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="n"&gt;personRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PersonService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="n"&gt;personRepository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;personRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;personRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LocalRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement the methods&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PersonRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Hibernate entity manager to handle the communication towards the Database.&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Implement the methods&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, the high-level PersonService doesn't care if you are using a LocalDatabase for development or a real database for production.&lt;/p&gt;

&lt;p&gt;And for example, you can change your Hibernate implementation to another solution without your high-level service knowing what's going on.&lt;/p&gt;




&lt;p&gt;In case if you have any questions or suggestions, feel free to send me a &lt;a href="https://www.renatofialho.com/contact/"&gt;message&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
    </item>
    <item>
      <title>How did I move my pet project from Spring MVC to Webflux and Spring Native with GraalVM</title>
      <dc:creator>Renato Fialho</dc:creator>
      <pubDate>Mon, 27 Jun 2022 23:35:26 +0000</pubDate>
      <link>https://dev.to/fialhorenato/how-did-i-move-my-pet-project-from-spring-mvc-to-webflux-using-spring-native-3lnm</link>
      <guid>https://dev.to/fialhorenato/how-did-i-move-my-pet-project-from-spring-mvc-to-webflux-using-spring-native-3lnm</guid>
      <description>&lt;p&gt;You can read this post as well &lt;a href="https://www.renatofialho.com/blog/challenges-using-spring-native-and-webflux"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my spare time last year, I created a pet project that aggregate news from some sources and delivers them to an Android app that I developed using Flutter, but that pet project is a topic for another post.&lt;/p&gt;

&lt;p&gt;The backend for this pet project was firstly built using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kotlin
Gradle KTS
Spring Boot (Data, MVC, Security, Actuator)
PostgreSQL (Liquibase for migrations)
Deployed on a heroku free tier dyno (Validating the idea)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I mentioned above, the stack is currently deployed in a Heroku free tier dyno, and that is a must for me to validate the idea for this project without spending tons of money. &lt;/p&gt;

&lt;p&gt;The MVP was deployed in heroku using one of their buildpacks for Gradle and everything was working fine with some struggles:&lt;/p&gt;

&lt;p&gt;1 - When I was enriching the DB (POSTing more content), the response times increased a little bit.&lt;/p&gt;

&lt;p&gt;2 - Since it is a pet project, the dyno running my app sleep sometimes during the day, and the initialization was very slow (Around 14 seconds)&lt;/p&gt;

&lt;p&gt;Those problems were already bothering me, and I already saw a couple things about the reactive stack for Spring (Webflux / R2DBC) that could help me handle more requests on a peak load without scaling my infrasctructure.&lt;/p&gt;

&lt;p&gt;Usually on my pet projects, I try to implement some new ideas (On this one, I improved my knowledge in Kotlin and learned Dart and Flutter), but I wasn't 100% sure that Webflux and Spring Native were mature enough for being used in this project (Even though is a pet project, there are currently 500+ MAU)&lt;/p&gt;

&lt;p&gt;Skipping some time, I went to the We Are Developers Worldwide Conference in Berlin a couple weeks ago, where a lot of talks were showcasing the new Spring Native and the already "known" Spring Webflux.&lt;/p&gt;

&lt;p&gt;So then, I gave that stack a try and those are my learnings from it:&lt;/p&gt;

&lt;h2&gt;
  
  
  First mistakes
&lt;/h2&gt;

&lt;p&gt;Those 2 technologies are somehow "new" and AFAIK, not being used in a lot of production grade environments.&lt;/p&gt;

&lt;p&gt;Even the Spring project promises a lot of great improvements on Spring 6 and Spring Boot 3.0 for the GraalVM and Spring Native support.&lt;/p&gt;

&lt;p&gt;With that being said, after some time, i realized that my first mistake was jumping into &lt;strong&gt;BOTH&lt;/strong&gt; of the new technologies at the same time.&lt;/p&gt;

&lt;p&gt;That created a feeling of not knowing if the issue was because of Webflux or Spring Native (I lost a couple nights of a lot of Stackoverflow and Github Issues trying to resolve the problems).&lt;/p&gt;

&lt;p&gt;Then, I'll try to showcase the ones that I took notes and remember, please let me know if you faced other problems and we can spread the knowledge. &lt;/p&gt;

&lt;h3&gt;
  
  
  Heroku doesn't support Spring Native out of the box. Yet.
&lt;/h3&gt;

&lt;p&gt;By it's nature of the AOT (Ahead of Time) compiler for the GraalVM, the Spring Native build consumes a lot of resources (It is a huge memory hog) and Heroku doesn't support it yet, so instead, you must build the image yourself or in your CI running &lt;code&gt;./gradlew bootBuildImage&lt;/code&gt; , that will use a buildpack to build and generate a Docker image for you with your application.&lt;/p&gt;

&lt;p&gt;Then, you just need to tag it with the &lt;code&gt;registry.heroku.com/&amp;lt;your_app_name&amp;gt;/&amp;lt;build&amp;gt;&lt;/code&gt; , push and run &lt;code&gt;heroku container:release web -a &amp;lt;your_app_name&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Heroku has Docker containers support out of the box, so then it is the same as deploying using one of theirs buildpack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Spring Data Webflux and R2DBC drivers don't support a lot of nice features from relational databases
&lt;/h3&gt;

&lt;p&gt;We know that Spring Webflux wasn't meant to be used with relational database since the JDBC drivers are I/O blocking, but the R2DBC initiative does it's job quite nicely.&lt;/p&gt;

&lt;p&gt;Some features, such as the &lt;code&gt;@OneToMany&lt;/code&gt; or &lt;code&gt;@ManyToMany&lt;/code&gt; or &lt;code&gt;@ManyToOne&lt;/code&gt; or &lt;code&gt;@OneToOne&lt;/code&gt; are not supported (yet!) , and in order to make some things to work, you must add some annotations that are a little bit different, such as if you need auditing with the &lt;code&gt;@CreatedAt&lt;/code&gt; and other annotations , you must add the &lt;code&gt;@EnableR2dbcAuditing&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;Well, AFAIK, Quarkus and Micronaut already support some of those features with Native builds, so maybe this is something that Spring Data R2DBC will bring in the near future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Liquibase is NOT supported. Yet.
&lt;/h3&gt;

&lt;p&gt;My first thought when implementing this project was to literally "copy/paste" most of the code from the project that is currently successfully running. &lt;/p&gt;

&lt;p&gt;And the database migration management tool that I was using is Liquibase (Wasn't a must, but instead, a good to have tool).&lt;/p&gt;

&lt;p&gt;I started adding the Liquibase dependency and a lot of issues happened when building the native image, I resolved a lot of them but at the end, struggled with the fact that Liquibase currently doesn't support Spring Native with GraalVM out of the box, this is an issue for the future, hopefully when they chose their &lt;a href="https://github.com/liquibase/liquibase/issues/1552"&gt;issue&lt;/a&gt; on Github, if you are interested, give a +1 on the thumbs up @ the issue!&lt;/p&gt;

&lt;h3&gt;
  
  
  Most of the monitoring tools are not available. Yet.
&lt;/h3&gt;

&lt;p&gt;One issue for production grade applications is observability and monitoring, so far, I couldn't find any way to make the Newrelic java agent to work together with the GraalVM and Spring Native builds (So, no APM yet!). But you can still instrument your application using the Metrics provided by the actuator and Micrometer with the interfaces to the best providers in the market (Datadog, Newrelic, Prometheus and others).&lt;/p&gt;

&lt;h3&gt;
  
  
  You must provide some hints to the GraalVM, and some of them are not 100% clear
&lt;/h3&gt;

&lt;p&gt;I faced an issue when running my application as a native app because the database URL was becoming malformed somehow, then, after a lot of research I found the &lt;a href=""&gt;samples repo&lt;/a&gt; from Spring that had a lot of tips to use Spring Native with some specific technologies.&lt;/p&gt;

&lt;p&gt;The error that i was facing was an &lt;code&gt;&amp;lt;unresolved&amp;gt;&lt;/code&gt; showing up from nowhere in the middle of my database URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Caused by: io.r2dbc.postgresql.PostgresqlConnectionFactory$PostgresConnectionException: Cannot connect to localhost/&amp;lt;unresolved&amp;gt;:5432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, in order to use the R2DBC PostgreSQL and Spring Native, i had to add this hint to the GraalVM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@NativeHint(
        trigger = PostgresqlConnectionFactoryProvider.class,
        types = {
                @TypeHint(types = { Instant[].class, ZonedDateTime[].class, URI[].class }, access = {}),
        }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can have a &lt;code&gt;META-INF/native/reflect-config.json&lt;/code&gt; file as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Well, now, let's come to the results measured so far:&lt;/p&gt;

&lt;p&gt;Before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started MyApplicationKt in 13.374 seconds (JVM running for 16.857)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Started MyApplication in 0.129 seconds (JVM running for 0.132)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll try to update this post later with some insights on CPU and Memory consumption, but so far, nothing to complain!&lt;/p&gt;

</description>
      <category>java</category>
      <category>webdev</category>
      <category>performance</category>
      <category>functional</category>
    </item>
    <item>
      <title>How to create slim docker Java Images using a minimal JRE</title>
      <dc:creator>Renato Fialho</dc:creator>
      <pubDate>Thu, 14 Apr 2022 13:56:47 +0000</pubDate>
      <link>https://dev.to/fialhorenato/how-to-create-slim-docker-java-images-using-a-minimal-jre-3a20</link>
      <guid>https://dev.to/fialhorenato/how-to-create-slim-docker-java-images-using-a-minimal-jre-3a20</guid>
      <description>&lt;p&gt;This can be read as well &lt;a href="https://www.renatofialho.com/blog/creating-slim-spring-boot-images"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, I will explain how you can create slim docker images by creating customized JREs using &lt;code&gt;jlink&lt;/code&gt; and &lt;code&gt;jmods&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Those commands are present on JDKs since Java 9, but actually being mature enough since Java 11, they bring a new way to create your customized JRE with only the modules that you need from Java, and then, creating smaller Docker images to run your Java applications (Mainly focused in Spring Boot applications), saving some good bucks in your Container Repository application (ECR, Artifactory, Docker Hub).&lt;/p&gt;

&lt;h2&gt;
  
  
  But, how do we start?
&lt;/h2&gt;

&lt;p&gt;Assuming you already have a JDK installed in your machine, if not, i strongly suggest you to use &lt;a href="https://sdkman.io/"&gt;sdkman.io&lt;/a&gt; and install Java 17 version (Which is the latest LTS as of the date of this post)&lt;/p&gt;

&lt;p&gt;First of all, we need to get the list produced from &lt;code&gt;jdeps&lt;/code&gt; based in your jarfile from Spring Boot, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;jdeps &lt;span class="nt"&gt;--list-deps&lt;/span&gt; &lt;span class="nt"&gt;--ignore-missing-deps&lt;/span&gt;  your-fat-jar.jar
   java.base
   java.logging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, that doesn't seems right, huh?&lt;/p&gt;

&lt;p&gt;Spring Boot has a strategy by default to generate a fat jar with all the needed dependencies inside of it, and &lt;code&gt;jdeps&lt;/code&gt; currently can't get all the dependencies recursively inside the jars from the fat-jar.&lt;/p&gt;

&lt;p&gt;So, what you can do is to extract all the contents from the fat-jar and run jdeps against every jar in the &lt;code&gt;lib&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Or, you can try with try and error, and see which ClassNotFoundException you will get from each JRE version&lt;/p&gt;

&lt;p&gt;But, from some previous experience, we usually need those packages in our minimal JRE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java.compiler
java.logging
java.sql
java.rmi
java.naming
java.management
java.instrument
java.security.jgss
java.net.http
jdk.httpserver
jdk.naming.dns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But my suggestion is to try yourself and see which packages you will really need in your slim JRE&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating my Java slim JRE
&lt;/h2&gt;

&lt;p&gt;You can use &lt;code&gt;jlink&lt;/code&gt; locally to create your customized JRE, the command is somehow like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jlink &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--module-path&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/jmods"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--add-modules&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;the java modules your application needs joined by ,] &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--strip-debug&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--compress&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--no-header-files&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--no-man-pages&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--output&lt;/span&gt; /opt/jre-minimal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explaining each flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--module-path &amp;lt;path&amp;gt;              Module path.
                                        If not specified, the JDKs jmods directory
                                        will be used, if it exists. If specified,
                                        but it does not contain the java.base module,
                                        the JDKs jmods directory will be added,
                                        if it exists.

--verbose                         Enable verbose tracing

--strip-debug                     Strip debug information

--compress=&amp;lt;0|1|2&amp;gt;                Enable compression of resources:
                                          Level 0: No compression
                                          Level 1: Constant string sharing
                                          Level 2: ZIP

--no-header-files                 Exclude include header files

--no-man-pages                    Exclude man pages

--output &amp;lt;path&amp;gt;                   Location of output path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get those informations as well by running &lt;code&gt;jlinks --help&lt;/code&gt; in your command line tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  But then, how do I create my slim Spring Boot application docker image
&lt;/h2&gt;

&lt;p&gt;Well, take this as an example, as i mentioned, it's using the OpenJDK 17 version (Latest LTS by the time this post was written)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build our minimal JRE using jlink&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openjdk:17-oraclelinux8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; root&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;jlink &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--module-path&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$JAVA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/jmods"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--add-modules&lt;/span&gt; java.compiler,java.sql,java.naming,java.management,java.instrument,java.rmi,java.desktop,jdk.internal.vm.compiler.management,java.xml.crypto,java.scripting,java.security.jgss,jdk.httpserver,java.net.http,jdk.naming.dns,jdk.crypto.cryptoki,jdk.unsupported &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--strip-debug&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--compress&lt;/span&gt; 2 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--no-header-files&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--no-man-pages&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;--output&lt;/span&gt; /opt/jre-minimal

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; app&lt;/span&gt;

&lt;span class="c"&gt;# Now it is time for us to build our real image on top of an slim version of debian&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; bitnami/minideb:bullseye&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /opt/jre-minimal /opt/jre-minimal&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; JAVA_HOME=/opt/jre-minimal&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH="$PATH:$JAVA_HOME/bin"&lt;/span&gt;

&lt;span class="k"&gt;VOLUME&lt;/span&gt;&lt;span class="s"&gt; /tmp&lt;/span&gt;

&lt;span class="c"&gt;# Copy the JRE created in the last step into our $JAVA_HOME&lt;/span&gt;

&lt;span class="c"&gt;# For gradle&lt;/span&gt;
&lt;span class="c"&gt;# COPY build/libs/app-*.jar app.jar&lt;/span&gt;

&lt;span class="c"&gt;# For maven&lt;/span&gt;
&lt;span class="c"&gt;# COPY target/app-*.jar app.jar&lt;/span&gt;


&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java","-jar","/app.jar"] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, how efficient is this?&lt;/p&gt;

&lt;p&gt;For example, in a regular spring boot application, it saved 200Mb of storage for every image generated, from &lt;code&gt;543.03&lt;/code&gt; to &lt;code&gt;349.98&lt;/code&gt;, assuming that you always have 10 versions of your application in your container registry, you can save &lt;strong&gt;2&lt;/strong&gt; GB of storage space for each application!&lt;/p&gt;

&lt;p&gt;You can check an example in this &lt;a href="https://github.com/fialhorenato/SpringBootstrap"&gt;repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>docker</category>
      <category>spring</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Handling SIGTERM and SIGKILL on Spring Boot web applications</title>
      <dc:creator>Renato Fialho</dc:creator>
      <pubDate>Wed, 08 Dec 2021 00:01:29 +0000</pubDate>
      <link>https://dev.to/fialhorenato/handling-sigterm-and-sigkill-on-spring-boot-web-applications-45i6</link>
      <guid>https://dev.to/fialhorenato/handling-sigterm-and-sigkill-on-spring-boot-web-applications-45i6</guid>
      <description>&lt;p&gt;This post was reproduced &lt;a href="https://www.renatofialho.com/blog/spring-boot-docker-orchestrators" rel="noopener noreferrer"&gt;here&lt;/a&gt; as well&lt;/p&gt;

&lt;p&gt;When debugging one system recently, I found out that every time that a deploy, downscale, container rotation or k8s updates happened I had a lot of connection errors in the ingress car.&lt;/p&gt;

&lt;p&gt;In common on those situations, is that k8s sends a SIGTERM, then have a grace period for the application to handle it gracefully, and after N seconds, it sends a SIGKILL, and that is the end.&lt;/p&gt;

&lt;p&gt;At first, being a little bit reluctant that the issue was with Spring Boot or the web server that I run with (Tomcat), I tried to check every possible misbehave from the load balancer, no success.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodv3qb3l8tkktyibzuqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodv3qb3l8tkktyibzuqa.png" alt="This is usually how the service infra works"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One example on how this works, but mainly from AWS ECS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj88paw4ie145rh34x3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdj88paw4ie145rh34x3k.png" alt="AWS ECS ELB Container Draining"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, after some digging into the server properties in Spring Boot, we found out that the common behaviour for the web server is to shutdown immediately after receiving a SIGTERM, not waiting for any persistent&lt;code&gt;keep-alive&lt;/code&gt; connections to be properly finished and closed.&lt;/p&gt;

&lt;h2&gt;
  
  
  And how did I fix this?
&lt;/h2&gt;

&lt;p&gt;So, in order to fix that, you must add a line to your &lt;code&gt;application.properties&lt;/code&gt; or &lt;code&gt;application.yml&lt;/code&gt; file like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    server.shutdown=graceful


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;OR&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;graceful&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Passing &lt;code&gt;graceful&lt;/code&gt; to the server shutdown property allows the web server to support graceful shutdown, allowing active requests time to complete and close any persistent &lt;code&gt;keep-alive&lt;/code&gt; connections towards your service.&lt;/p&gt;

&lt;p&gt;Oh, and if in any case you ended up here but want to know more how Quarkus handles this, i suggest you to take a look &lt;a href="https://quarkus.io/guides/lifecycle#graceful-shutdown" rel="noopener noreferrer"&gt;here&lt;/a&gt;, because it explains in an easy way how to implement this on Quarkus.&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>docker</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
