<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://carloschac.in/feed.xml" rel="self" type="application/atom+xml" /><link href="https://carloschac.in/" rel="alternate" type="text/html" hreflang="en" /><updated>2025-09-29T07:48:38+00:00</updated><id>https://carloschac.in/feed.xml</id><title type="html">Carlos Chacin</title><subtitle>Software Engineering experiences</subtitle><author><name>Carlos Chacin</name><email>cchacin@gmail.com</email></author><entry xml:lang="es-es"><title type="html">Crea una REST API sin usar ningún Framework con Java Servlets, JDBC, PostgreSQL y Jackson</title><link href="https://carloschac.in/2025/02/01/frameworkless-rest-api/" rel="alternate" type="text/html" title="Crea una REST API sin usar ningún Framework con Java Servlets, JDBC, PostgreSQL y Jackson" /><published>2025-02-01T15:00:00+00:00</published><updated>2025-02-01T15:00:00+00:00</updated><id>https://carloschac.in/2025/02/01/frameworkless-rest-api</id><content type="html" xml:base="https://carloschac.in/2025/02/01/frameworkless-rest-api/"><![CDATA[<h2 id="crea-una-rest-api-sin-usar-ningún-framework-con-java-servlets-jdbc-postgresql-y-jackson">Crea una REST API sin usar ningún Framework con Java Servlets, JDBC, PostgreSQL y Jackson</h2>

<p>En éste video, veremos como implementar una REST API sin usar ningún framework como Quarkus, Micronaut, Helidon o Spring Boot.
Usaremos Servlets para exponer la API, JDBC para conectarnos a PostgreSQL y Jackson para la serialización a JSON, Integration Testing con Junit5, AssertJ y TestContainers.</p>

<p>Recursos:</p>

<ul>
  <li>Jetty: https://jetty.org/</li>
  <li>HikariCP: https://github.com/brettwooldridge/HikariCP</li>
  <li>12 Factor Apps: https://12factor.net/</li>
  <li>Código: https://github.com/cchacin/frameworkless-rest-api</li>
</ul>

<h3 id="parte-1">Parte 1</h3>
<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/-UVrMS43uEQ?si=93KAZ9J7EnZgu7Ty" title="Crea una REST API sin usar ningún Framework - Parte 1" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</div>

<h3 id="parte-2">Parte 2</h3>
<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/b8E3WhSWLhs?si=Qjca1rd11r73aeqr" title="Crea una REST API sin usar ningún Framework - Parte 2" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
  Servlet Container                                                                   │
 │-----------------             ┌───────────────┐
  Jetty                         │ Serialization │                                     │
 │                              ├───────────────┤
                                │     JSON      │                                     │
 │        ┌───────────────┐     │    -------    │◀─────┐
          │     REST      │     │    Jackson    │      │                              │
 │        ├───────────────┤     └───────────────┘      │
          │   API Layer   │                            │                              │
 │        │   --------    │◀────────────────┐          │
          │   Servlets    │                 │          │                              │
 │        └───────────────┘                 │          │
                                            │          │                              │
 │                                          │          │
                                            │          │                              │
 │        ┌───────────────┐                 │          │       ┌───────────────┐
          │   Core DTOs   │                 │          │       │     Main      │      │
 │        ├───────────────┤                 │          │       ├───────────────┤
          │ Service Layer │                 │          │       │   App Layer   │      │
 │        │ ------------- │◀────────────────┼──────────┴───────│ ------------- │
          │  Plain Java   │                 │                  │  Plain Java   │      │
 │        └───────────────┘                 │                  └───────────────┘
                                            │                                         │
 │                                          │
                                            │                                         │
 │        ┌───────────────┐                 │
          │    DB DTOs    │                 │                                         │
 │        ├───────────────┤                 │
          │  Data Layer   │                 │                                         │
 │        │---------------│◀────────────────┘
          │JDBC / Postgres│                                                           │
 │        └───────────────┘
                  │                                                                   │
 │                │
                  │                                                                   │
 │                │
  ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
                  │
                  └────────────────────────┐
                                           │
                                           │
                                           │
                                           │
                                           │
                                           │
                                           ▼
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
 DATABASE                                                                            │
│----------
 PostgreSQL                                                                          │
│
                                                                                     │
│
                                                                                     │
│
                                                                                     │
│
                                                                                     │
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
</code></pre></div></div>]]></content><author><name>Carlos Chacin</name></author><category term="java" /><category term="jdbc" /><category term="postgres" /><category term="postgresql" /><category term="rest" /><category term="api" /><category term="frameworkless" /><category term="servlets" /><summary type="html"><![CDATA[Crea una REST API sin usar ningún Framework con Java Servlets, JDBC, PostgreSQL y Jackson]]></summary></entry><entry xml:lang="en-en"><title type="html">🚀 Auto-Switch iTerm2 Modes, Day &amp;amp; Night! 🌞🌚</title><link href="https://carloschac.in/2024/05/27/iterm2-dark-light-mode/" rel="alternate" type="text/html" title="🚀 Auto-Switch iTerm2 Modes, Day &amp;amp; Night! 🌞🌚" /><published>2024-05-27T15:00:00+00:00</published><updated>2024-05-27T15:00:00+00:00</updated><id>https://carloschac.in/2024/05/27/iterm2-dark-light-mode</id><content type="html" xml:base="https://carloschac.in/2024/05/27/iterm2-dark-light-mode/"><![CDATA[<p><img src="/public/images/iterm2-theme-switch/header.png" alt="header" loading="lazy" /></p>

<p><a href="https://iterm2.com/">iTerm2</a> recently introduced a great feature: separate light and dark mode colors. This feature enhances the visual appeal of your terminal and keeps it in sync with your Mac’s mode.</p>

<p>This feature is not just about aesthetics; it’s about comfort. Imagine your terminal always matching your Mac’s light or dark mode, creating a seamless and visually pleasing experience. This enhances the visual appeal and reduces eye strain, making your terminal usage more comfortable.</p>

<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/Lrvdve8JNm0?si=Dlf-_rwaz8HZCn6X" title="Auto-Switch iTerm2 Modes, Day &amp; Night!" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
</div>

<h2 id="the-problem">The Problem</h2>

<p>In the image below, you can notice that the iTerm2 does not change by default when we switch between light and dark modes.</p>

<!-- more -->

<p><img src="/public/images/iterm2-theme-switch/before.gif" alt="header" loading="lazy" /></p>

<h2 id="ok-lets-discover-this-game-changer-feature">Ok, let’s discover this game-changer feature!</h2>

<h2 id="step-1">Step 1</h2>

<p>Go to iTerm2 settings and click the <code class="language-plaintext highlighter-rouge">Profiles</code> tab.</p>

<p><img src="/public/images/iterm2-theme-switch/1.png" alt="header" loading="lazy" /></p>

<h2 id="step-2">Step 2</h2>

<p>Click the <code class="language-plaintext highlighter-rouge">Colors</code> tab under <code class="language-plaintext highlighter-rouge">Profiles.</code></p>

<p><img src="/public/images/iterm2-theme-switch/2.png" alt="header" loading="lazy" /></p>

<h2 id="step-3">Step 3</h2>

<p>Enable the checkbox to <code class="language-plaintext highlighter-rouge">Use different colors for light and dark mode.</code></p>

<p><img src="/public/images/iterm2-theme-switch/3.png" alt="header" loading="lazy" /></p>

<h2 id="step-4">Step 4</h2>

<p>Select the desired dual theme. In this case, I’m selecting <code class="language-plaintext highlighter-rouge">Solarized,</code> which has light and dark versions.</p>

<p><img src="/public/images/iterm2-theme-switch/4.png" alt="header" loading="lazy" /></p>

<h2 id="step-5">Step 5</h2>

<p>Click on <code class="language-plaintext highlighter-rouge">Update Both Modes</code></p>

<p><img src="/public/images/iterm2-theme-switch/5.png" alt="header" loading="lazy" /></p>

<h2 id="the-result">The Result</h2>

<p><img src="/public/images/iterm2-theme-switch/after.gif" alt="header" loading="lazy" /></p>]]></content><author><name>Carlos Chacin</name></author><category term="iterm2" /><category term="macos" /><category term="tips-and-tricks" /><category term="terminal" /><category term="productivity" /><summary type="html"><![CDATA[iTerm2 has recently introduced a great feature, separate light and dark mode colors. This feature enhances the visual appeal of your terminal and keeps it in sync with your Mac's mode.]]></summary></entry><entry xml:lang="es-es"><title type="html">Java 17 + AWS Lambda</title><link href="https://carloschac.in/2023/06/06/java-17-y-aws-lambda/" rel="alternate" type="text/html" title="Java 17 + AWS Lambda" /><published>2023-06-06T16:07:00+00:00</published><updated>2023-06-06T16:07:00+00:00</updated><id>https://carloschac.in/2023/06/06/java-17-y-aws-lambda</id><content type="html" xml:base="https://carloschac.in/2023/06/06/java-17-y-aws-lambda/"><![CDATA[<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/Header.png" alt="Header" loading="lazy" /></p>

<p>AWS recently announced <a href="https://aws.amazon.com/about-aws/whats-new/2023/04/aws-lambda-java-17/">Java 17 support for Lambdas</a>, In this blog post, we’ll explore how to create a Java 17 AWS Lambda Function without IDE, build tool or any dependency.</p>

<div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/VhxhmMqjEl8?sub_confirmation=1" title="Java 17 y AWS Lambda" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p>Fist let’s create the lambda function code:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Function</span> <span class="o">{</span>

  <span class="kd">public</span> <span class="n">record</span> <span class="nf">Input</span><span class="o">(</span><span class="kt">int</span> <span class="n">x</span><span class="o">,</span> <span class="kt">int</span> <span class="n">y</span><span class="o">)</span> <span class="o">{}</span>

  <span class="kd">public</span> <span class="n">record</span> <span class="nf">Output</span><span class="o">(</span><span class="kt">long</span> <span class="n">result</span><span class="o">)</span> <span class="o">{}</span>

  <span class="kd">public</span> <span class="nc">Output</span> <span class="nf">add</span><span class="o">(</span><span class="nc">Input</span> <span class="n">input</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nf">Output</span><span class="o">(</span><span class="n">input</span><span class="o">.</span><span class="na">x</span> <span class="o">+</span> <span class="n">input</span><span class="o">.</span><span class="na">y</span><span class="o">);</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>In this example, we have an <code class="language-plaintext highlighter-rouge">add</code> method that takes an <code class="language-plaintext highlighter-rouge">Input</code> java record with 2 fields: <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code>, and returns an <code class="language-plaintext highlighter-rouge">Output</code> java record with the sum of <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code> assigned to the <code class="language-plaintext highlighter-rouge">result</code> field.</p>

<p>This is the only requirement for a AWS Lambda Function:</p>

<p>An instance method that takes one single parameter and returns something an object or <code class="language-plaintext highlighter-rouge">Void</code>.</p>

<p>That’s it. Now we can proceed to compile and package our AWS Lambda Function:</p>

<p>Compile:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javac Function.java
</code></pre></div></div>

<p>Package:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>zip <span class="k">function</span>.zip <span class="k">*</span>.class
</code></pre></div></div>

<p>Next, let’s navigate to the AWS Lambda Console.
<img src="https://carloschac.in/public/images/java-17-aws-lambda/2.png" alt="2" loading="lazy" /></p>

<p>Click on the <code class="language-plaintext highlighter-rouge">Create function</code> button.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/3.png" alt="3" loading="lazy" /></p>

<p>Assign a lambda name and select Java 17 as the runtime.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/4.png" alt="4" loading="lazy" /></p>

<p>Click on the <code class="language-plaintext highlighter-rouge">Upload from</code> button.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/5.png" alt="5" loading="lazy" /></p>

<p>Click <code class="language-plaintext highlighter-rouge">Upload</code> button.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/6.png" alt="6" loading="lazy" /></p>

<p>Choose the <code class="language-plaintext highlighter-rouge">function.zip</code> file that we generated.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/7.png" alt="7" loading="lazy" /></p>

<p>Click <code class="language-plaintext highlighter-rouge">Edit</code> on the <code class="language-plaintext highlighter-rouge">Code properties</code> section.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/8.png" alt="8" loading="lazy" /></p>

<p>Change the Handler to <code class="language-plaintext highlighter-rouge">Function::add</code> and click <code class="language-plaintext highlighter-rouge">Save</code>.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/9.png" alt="9" loading="lazy" /></p>

<p>Go to the <code class="language-plaintext highlighter-rouge">Test</code> tab.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/10.png" alt="10" loading="lazy" /></p>

<p>Change the JSON payload to:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"x"</span><span class="p">:</span><span class="w"> </span><span class="mi">123</span><span class="p">,</span><span class="w">
  </span><span class="nl">"y"</span><span class="p">:</span><span class="w"> </span><span class="mi">333</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Click the <code class="language-plaintext highlighter-rouge">Test</code> button, then expand the <code class="language-plaintext highlighter-rouge">Details</code> section to see the result.</p>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/11.png" alt="11" loading="lazy" /></p>

<p>That’s it! You have successfully created and tested your Java 17 AWS Lambda function. The output should be:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="mi">456</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><img src="https://carloschac.in/public/images/java-17-aws-lambda/12.png" alt="12" loading="lazy" /></p>

<p>This demonstrates the simplicity and power of using Java 17 with AWS Lambda. With just a few steps, you can leverage the latest Java version to build efficient and scalable serverless applications.</p>

<p>Feel free to explore further and unleash the full potential of Java 17 on AWS Lambda. Happy coding!</p>]]></content><author><name>Carlos Chacin</name></author><category term="aws" /><category term="java" /><category term="java17" /><category term="lambda" /><category term="aws-lambda" /><summary type="html"><![CDATA[AWS recently announced Java 17 support for Lambdas, In this blog post, we'll explore how to create a Java 17 AWS Lambda Function without IDE, build tool or any dependency.]]></summary></entry><entry xml:lang="en-us"><title type="html">🏆 Default 🔗 Maven and ☕ Java settings per project</title><link href="https://carloschac.in/2021/09/23/setup-default-maven-and-java-settings-per-project/" rel="alternate" type="text/html" title="🏆 Default 🔗 Maven and ☕ Java settings per project" /><published>2021-09-23T06:00:00+00:00</published><updated>2021-09-23T06:00:00+00:00</updated><id>https://carloschac.in/2021/09/23/setup-default-maven-and-java-settings-per-project</id><content type="html" xml:base="https://carloschac.in/2021/09/23/setup-default-maven-and-java-settings-per-project/"><![CDATA[<p><img src="/public/images/maven-config/tree.png" alt="github-actions" loading="lazy" /></p>

<p>I generally use many different options on maven projects to set up things like memory lower and upper limits, fail at the end, the process in batch, use x number of threads, etc. In addition to this, sometimes I need to pass flags to the JVM like add modules, garbage collector flags, etc., and it is difficult to remember and also error-prone to have something like this:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ JAVA_OPTS</span><span class="o">=</span><span class="s2">"-Xms512m -Xmx1024m -Djava.awt.headless=true"</span> <span class="se">\</span>
  mvn <span class="nt">-B</span> <span class="nt">-T</span> 4 <span class="nt">-fae</span> <span class="nt">-P</span> ci verify
</code></pre></div></div>

<p>or even worst with the extended version of the flags:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ JAVA_OPTS="-Xms512m -Xmx1024m -Djava.awt.headless=true" \
mvn --batch-mode --threads 4 -fail-at-end --activate-profiles ci verify
</code></pre></div></div>

<p>Fortunately for us, since maven 3.3.1, we now can setup this per project, including the flags in these two files relatives to the project directory:</p>

<!-- more -->

<p><code class="language-plaintext highlighter-rouge">.mvn/maven.config</code> with:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-B</span> <span class="nt">-T</span> 4 <span class="nt">-fae</span> <span class="nt">-P</span> ci
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">.mvn/jvm.config</code> with:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Xms512m</span> <span class="nt">-Xmx1024m</span> <span class="nt">-Djava</span>.awt.headless<span class="o">=</span><span class="nb">true</span>
</code></pre></div></div>

<p>Now, all we need to do is run the maven command, and the settings in the files will be honored:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mvn verify
</code></pre></div></div>]]></content><author><name>Carlos Chacin</name></author><category term="java" /><category term="maven" /><category term="settings" /><category term="configuration" /><category term="setup" /><summary type="html"><![CDATA[Almost every single project requires some specific options for Maven and Java, like memory, profiles, etc., and we are going to see how to set up those per project in a few easy steps.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://carloschac.in/public/images/maven-config/tree.png" /><media:content medium="image" url="https://carloschac.in/public/images/maven-config/tree.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry xml:lang="en-us"><title type="html">☕🚢 Maven Build in &amp;lt; 20 lines of yaml 🕟</title><link href="https://carloschac.in/2021/09/22/maven-build-on-github/" rel="alternate" type="text/html" title="☕🚢 Maven Build in &amp;lt; 20 lines of yaml 🕟" /><published>2021-09-22T05:08:00+00:00</published><updated>2021-09-22T05:08:00+00:00</updated><id>https://carloschac.in/2021/09/22/maven-build-on-github</id><content type="html" xml:base="https://carloschac.in/2021/09/22/maven-build-on-github/"><![CDATA[<p><img src="/public/images/maven-github-actions/github-actions.png" alt="github-actions" loading="lazy" /></p>

<blockquote>
  <p><a href="https://github.com/features/actions">GitHub Actions</a> makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.</p>
</blockquote>

<h2 id="create-the-directory">Create the directory</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">mkdir</span> <span class="nt">-p</span> .github/workflows
</code></pre></div></div>

<h2 id="create-the-yaml-file">Create the yaml file</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">touch</span> .github/workflows/maven.yml
</code></pre></div></div>

<h2 id="copy-this-content">Copy this content</h2>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Maven Build</span>
<span class="na">on</span><span class="pi">:</span>
  <span class="na">push</span><span class="pi">:</span>
    <span class="na">branches</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="s">main</span>
<span class="na">jobs</span><span class="pi">:</span>
  <span class="na">build</span><span class="pi">:</span>
    <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Maven</span><span class="nv"> </span><span class="s">Build"</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Checkout</span><span class="nv"> </span><span class="s">Sources"</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v2</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">fetch-depth</span><span class="pi">:</span> <span class="m">2</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Set</span><span class="nv"> </span><span class="s">up</span><span class="nv"> </span><span class="s">JDK"</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-java@v2</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">distribution</span><span class="pi">:</span> <span class="s2">"</span><span class="s">temurin"</span>
          <span class="na">java-version</span><span class="pi">:</span> <span class="m">11</span>
          <span class="na">cache</span><span class="pi">:</span> <span class="s2">"</span><span class="s">maven"</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Build</span><span class="nv"> </span><span class="s">with</span><span class="nv"> </span><span class="s">Maven"</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">mvn verify</span>
</code></pre></div></div>

<h2 id="commit-and-push-to-github">Commit and push to Github</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git add .github <span class="o">&amp;&amp;</span> <span class="se">\</span>
  git commit <span class="nt">-m</span> <span class="s2">"maven build action"</span>
</code></pre></div></div>

<h2 id="enjoy-your-builds">Enjoy your builds</h2>

<p>Go to the actions tab for your repository over github.com:</p>

<p>https://github.com/${USER}/${PROJECT}/actions/workflows/maven-build.yml</p>

<p><img src="/public/images/maven-github-actions/maven-build.png" alt="maven-build" loading="lazy" /></p>]]></content><author><name>Carlos Chacin</name></author><category term="java" /><category term="maven" /><category term="github" /><category term="actions" /><category term="github-actions" /><category term="build" /><summary type="html"><![CDATA[Automate your maven build using GitHub Actions in a simple step with less than 20 lines of yaml.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://carloschac.in/public/images/maven-github-actions/maven-build.png" /><media:content medium="image" url="https://carloschac.in/public/images/maven-github-actions/maven-build.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry xml:lang="en-us"><title type="html">💾 Java Records 💿 with Jackson 2.12</title><link href="https://carloschac.in/2021/03/04/jacksonrecords/" rel="alternate" type="text/html" title="💾 Java Records 💿 with Jackson 2.12" /><published>2021-03-04T01:33:16+00:00</published><updated>2021-03-04T01:33:16+00:00</updated><id>https://carloschac.in/2021/03/04/jacksonrecords</id><content type="html" xml:base="https://carloschac.in/2021/03/04/jacksonrecords/"><![CDATA[<p><img src="https://carloschac.in/public/images/java-records-jackson.png" alt="java-records-jackson" loading="lazy" /></p>

<p>In the previous article about Java 14 Records, we saw how to start creating Records to avoid writing much boilerplate code that the compiler would generate for us.</p>

<p>Now the next steps are to see how we can serialize records to JSON and deserialize JSON to records to be able to use them as a request/response representation for microservices.</p>

<p>In this case, we would use the Jackson 2.12+.</p>

<!-- more -->

<p>Continuing with the <a href="https://carloschac.in/2020/04/17/java-records/">same example</a> that we used in the previous article, we would need to add Jackson Dependencies to our existing pom.xml file:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>com.fasterxml.jackson.core<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>jackson-databind<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>2.12.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<h3 id="-now-lets-see-our-example-record">💾 Now let’s see our example Record:</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nd">@JsonProperty</span><span class="o">(</span><span class="s">"first_name"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">firstName</span><span class="o">,</span>
    <span class="nd">@JsonProperty</span><span class="o">(</span><span class="s">"last_name"</span><span class="o">)</span> <span class="nc">String</span> <span class="n">lastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">address</span><span class="o">,</span>
    <span class="nc">Date</span> <span class="n">birthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="-java-14-compiler-would-generate-all-of-the-following">💡 Java 14+ compiler would generate all of the following:</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javap <span class="nt">-p</span> Person.class
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Record</span> <span class="o">{</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">lastName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">address</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Date</span> <span class="n">birthday</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">;</span>
  <span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span>
    <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span>
    <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span>
    <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Date</span><span class="o">,</span>
    <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;);</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">toString</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span><span class="o">);</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">firstName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">lastName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">address</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">Date</span> <span class="nf">birthday</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="nf">achievements</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="-our-test-setup">🔨 Our test setup:</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="nc">ObjectMapper</span> <span class="n">mapper</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ObjectMapper</span><span class="o">()</span>
      <span class="o">.</span><span class="na">enable</span><span class="o">(</span><span class="nc">SerializationFeature</span><span class="o">.</span><span class="na">INDENT_OUTPUT</span><span class="o">);</span>
</code></pre></div></div>

<p>To serialize/deserialize a record like this:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
    <span class="s">"John"</span><span class="o">,</span>
    <span class="s">"Doe"</span><span class="o">,</span>
    <span class="s">"USA"</span><span class="o">,</span>
    <span class="k">new</span> <span class="nf">Date</span><span class="o">(</span><span class="mi">981291289182L</span><span class="o">),</span>
    <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>

<p>To/From a json string like this:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"first_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"last_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Doe"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"USA"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"birthday"</span><span class="p">:</span><span class="w"> </span><span class="mi">981291289182</span><span class="p">,</span><span class="w">
  </span><span class="nl">"achievements"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Speaker"</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="-testing-serialization">💊 Testing Serialization</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kt">void</span> <span class="nf">serializeRecord</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
    <span class="c1">// Given</span>
    <span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="k">new</span> <span class="nf">Date</span><span class="o">(</span><span class="mi">981291289182L</span><span class="o">),</span>
            <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
    <span class="o">);</span>

    <span class="kt">var</span> <span class="n">json</span> <span class="o">=</span> <span class="s">"""
            {
              "</span><span class="n">first_name</span><span class="s">" : "</span><span class="nc">John</span><span class="s">",
              "</span><span class="n">last_name</span><span class="s">" : "</span><span class="nc">Doe</span><span class="s">",
              "</span><span class="n">address</span><span class="s">" : "</span><span class="no">USA</span><span class="s">",
              "</span><span class="n">birthday</span><span class="s">" : 981291289182,
              "</span><span class="n">achievements</span><span class="s">" : [ "</span><span class="nc">Speaker</span><span class="s">" ]
            }"""</span><span class="o">;</span>

    <span class="c1">// When</span>
    <span class="kt">var</span> <span class="n">serialized</span> <span class="o">=</span> <span class="n">mapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>

    <span class="c1">// Then</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">serialized</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">json</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="-testing-deserialization">💊 Testing Deserialization</h2>

<p>Let’s use the same record to try the deserialization using also the same configuration:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kt">void</span> <span class="nf">deserializeRecord</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
    <span class="c1">// Given</span>
    <span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="k">new</span> <span class="nf">Date</span><span class="o">(</span><span class="mi">981291289182L</span><span class="o">),</span>
            <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
    <span class="o">);</span>

    <span class="kt">var</span> <span class="n">json</span> <span class="o">=</span> <span class="s">"""
            {
              "</span><span class="n">first_name</span><span class="s">" : "</span><span class="nc">John</span><span class="s">",
              "</span><span class="n">last_name</span><span class="s">" : "</span><span class="nc">Doe</span><span class="s">",
              "</span><span class="n">address</span><span class="s">" : "</span><span class="no">USA</span><span class="s">",
              "</span><span class="n">birthday</span><span class="s">" : 981291289182,
              "</span><span class="n">achievements</span><span class="s">" : [ "</span><span class="nc">Speaker</span><span class="s">" ]
            }"""</span><span class="o">;</span>

    <span class="c1">// When</span>
    <span class="kt">var</span> <span class="n">deserialized</span> <span class="o">=</span> <span class="n">mapper</span><span class="o">.</span><span class="na">readValue</span><span class="o">(</span><span class="n">json</span><span class="o">,</span> <span class="nc">Person</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>

    <span class="c1">// Then</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">deserialized</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="-conclusions">🔆 Conclusions</h2>

<ul>
  <li>✅ We can start using Jackson &gt;= <a href="https://github.com/FasterXML/jackson/wiki/Jackson-Release-2.12">2.12.0</a> to serialize/deserialize Java Records.</li>
  <li>👷 This is a new feature, and there can be edge cases, try it out with caution.</li>
  <li>🐞 Report issues <a href="https://github.com/FasterXML/jackson-core/issues">here</a> if you find any</li>
</ul>]]></content><author><name>Carlos Chacin</name></author><category term="jackson" /><category term="java14" /><category term="records" /><category term="serialization" /><summary type="html"><![CDATA[Java Record is a new kind of type declaration in the Java language. In this article, we are going to see how we can serialize and deserialize records to/from JSON using Jackson 2.12.0.]]></summary></entry><entry xml:lang="en-us"><title type="html">🌒 JakartaEE JSON-B 🐝 Retrofit2 Converter</title><link href="https://carloschac.in/2020/09/23/jsonb-retrofit2-converter/" rel="alternate" type="text/html" title="🌒 JakartaEE JSON-B 🐝 Retrofit2 Converter" /><published>2020-09-23T00:00:00+00:00</published><updated>2020-09-23T00:00:00+00:00</updated><id>https://carloschac.in/2020/09/23/jsonb-retrofit2-converter</id><content type="html" xml:base="https://carloschac.in/2020/09/23/jsonb-retrofit2-converter/"><![CDATA[<p><img src="/public/images/retrofit2.png" alt="java-records-jsonb" loading="lazy" /></p>

<blockquote>
  <p>Retrofit is pluggable allowing different serialization formats and their libraries to be used for converting Java types to their HTTP representation and parsing HTTP entities back into Java types.</p>

  <p>These are called converters, and Retrofit includes a few first-party modules for popular frameworks</p>
</blockquote>

<p>Just for fun, I created a <a href="(https://square.github.io/retrofit/)">Retrofit2</a> <code class="language-plaintext highlighter-rouge">Converter.Factory</code> for <a href="(http://json-b.net/)">JakartaEE Json-B</a>.</p>

<!-- more -->

<h3 id="usage">Usage</h3>

<h4 id="add-the-dependencies">Add the dependencies:</h4>

<h5 id="retrofit2">Retrofit2</h5>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
  <span class="nt">&lt;groupId&gt;</span>com.squareup.retrofit2<span class="nt">&lt;/groupId&gt;</span>
  <span class="nt">&lt;artifactId&gt;</span>retrofit<span class="nt">&lt;/artifactId&gt;</span>
  <span class="nt">&lt;version&gt;</span>2.9.0<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<h5 id="okhttp3">OkHttp3</h5>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
  <span class="nt">&lt;groupId&gt;</span>com.squareup.okhttp3<span class="nt">&lt;/groupId&gt;</span>
  <span class="nt">&lt;artifactId&gt;</span>okhttp<span class="nt">&lt;/artifactId&gt;</span>
  <span class="nt">&lt;version&gt;</span>3.14.9<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<h5 id="jakartaee-json-binding-reference-implementation">JakartaEE Json Binding Reference Implementation</h5>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
  <span class="nt">&lt;groupId&gt;</span>org.eclipse<span class="nt">&lt;/groupId&gt;</span>
  <span class="nt">&lt;artifactId&gt;</span>yasson<span class="nt">&lt;/artifactId&gt;</span>
  <span class="nt">&lt;version&gt;</span>1.0.8<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<h5 id="jsonb-retrofit2-converter">JsonB Retrofit2 Converter</h5>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
  <span class="nt">&lt;groupId&gt;</span>io.github.cchacin<span class="nt">&lt;/groupId&gt;</span>
  <span class="nt">&lt;artifactId&gt;</span>jsonb-retrofit-converter<span class="nt">&lt;/artifactId&gt;</span>
  <span class="nt">&lt;version&gt;</span>1.0.2<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<p>Add a converter factory when building your <code class="language-plaintext highlighter-rouge">Retrofit</code> instance using the
<code class="language-plaintext highlighter-rouge">create</code> method:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">retrofit</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Retrofit</span><span class="o">.</span><span class="na">Builder</span><span class="o">()</span>
    <span class="o">.</span><span class="na">baseUrl</span><span class="o">(</span><span class="s">"https://example.com/"</span><span class="o">)</span>
    <span class="o">.</span><span class="na">addConverterFactory</span><span class="o">(</span><span class="nc">JsonbConverterFactory</span><span class="o">.</span><span class="na">create</span><span class="o">())</span>
    <span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<p>Alternatively, you can pass an instance of <code class="language-plaintext highlighter-rouge">javax.json.bind.Jsonb</code>:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">jsonb</span> <span class="o">=</span> <span class="nc">JsonbBuilder</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="cm">/* configure your jsonb instance here */</span> <span class="o">);</span>
<span class="kt">var</span> <span class="n">retrofit</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Retrofit</span><span class="o">.</span><span class="na">Builder</span><span class="o">()</span>
    <span class="o">.</span><span class="na">baseUrl</span><span class="o">(</span><span class="s">"https://example.com/"</span><span class="o">)</span>
    <span class="o">.</span><span class="na">addConverterFactory</span><span class="o">(</span><span class="nc">JsonbConverterFactory</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="n">jsonb</span><span class="o">))</span>
    <span class="o">.</span><span class="na">build</span><span class="o">();</span>
</code></pre></div></div>

<p>Now we are able to use <strong>JakartaEE JsonB</strong> to serialize and deserialize POJOs using <strong>Retrofit2</strong></p>

<p>The code is available on <a href="(https://github.com/cchacin/jsonb-retrofit-converter/)">Github</a>.</p>]]></content><author><name>Carlos Chacin</name></author><category term="jakartaee" /><category term="jsonb" /><category term="serialization" /><category term="retrofit" /><summary type="html"><![CDATA[A Retrofit2 Converter.Factory for JakartaEE JSON Binding]]></summary></entry><entry xml:lang="en-us"><title type="html">🔌 Restore IntelliJ Idea settings ⛽</title><link href="https://carloschac.in/2020/04/30/restore-intellij-settings/" rel="alternate" type="text/html" title="🔌 Restore IntelliJ Idea settings ⛽" /><published>2020-04-30T00:00:00+00:00</published><updated>2020-04-30T00:00:00+00:00</updated><id>https://carloschac.in/2020/04/30/restore-intellij-settings</id><content type="html" xml:base="https://carloschac.in/2020/04/30/restore-intellij-settings/"><![CDATA[<p><img src="https://carloschac.in/public/images/intellij-restore-settings.png" alt="intellij-restore-settings" loading="lazy" /></p>

<p>After a long day trying to figure out how to reset all my IntelliJ settings, I decided to write this to document the obvious solution that was not that obvious to me.</p>

<p>I was using the 🔥 JetBrains Toolbox App 🔥 for a while to manage my IntelliJ Idea Ultimate installation along with other tools like Rider, WebStorm, and the Early Access Preview for IntelliJ Community Edition.</p>

<p><img src="https://carloschac.in/public/images/toolbox-app.png" alt="toolboxapp" loading="lazy" /></p>

<p>After several installations and reinstallations of IDEs and different Java/JDK versions (8, 9, 11, 14), the IDE was not able to import my maven projects. The IntelliJ IDEA was acting as a simple text editor at this time 😟.</p>

<!-- more -->

<h2 id="-failed-attempt-to-solve-it-">💀 Failed attempt to solve it 🔇</h2>

<ol>
  <li>Uninstall IntelliJ IDEA Ultimate using the Toolbox App</li>
  <li>Uninstall the Toolbox App</li>
  <li>Delete the following directories:</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> ~/Library/Application<span class="se">\ </span>Support/JetBrains/
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">rm</span> <span class="nt">-rf</span> ~/Library/Caches/JetBrains/IntelliJIdea2020.1
</code></pre></div></div>

<ol>
  <li>Reinstall IntelliJ IDEA without using Toolbox</li>
</ol>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>brew cask <span class="nb">install </span>intellij
</code></pre></div></div>

<h2 id="-the-obvious-and-simple-solution-">💊 The obvious and simple solution 🍏</h2>

<p><img src="https://carloschac.in/public/images/intellij-restore-settings.gif" alt="intellij-restore-settings-gif" /></p>

<p>Go to:</p>

<p><code class="language-plaintext highlighter-rouge">Configure</code> -&gt; <code class="language-plaintext highlighter-rouge">Restore Default Settings</code> -&gt; <code class="language-plaintext highlighter-rouge">Restore and Restart</code></p>]]></content><author><name>Carlos Chacin</name></author><category term="java" /><category term="ide" /><category term="IntelliJ" /><category term="idea" /><summary type="html"><![CDATA[After several installations and reinstallations of IDEs and different Java/JDK versions (8, 9, 11, 14), the IDE was not able to import my maven projects. The IntelliJ IDEA was acting as a simple text editor at this time 😟.]]></summary></entry><entry xml:lang="en-us"><title type="html">💾 Java 14 Records 🐞 with JakartaEE JSON-B</title><link href="https://carloschac.in/2020/04/20/java-records-jsonb/" rel="alternate" type="text/html" title="💾 Java 14 Records 🐞 with JakartaEE JSON-B" /><published>2020-04-20T00:00:00+00:00</published><updated>2020-04-20T00:00:00+00:00</updated><id>https://carloschac.in/2020/04/20/java-records-jsonb</id><content type="html" xml:base="https://carloschac.in/2020/04/20/java-records-jsonb/"><![CDATA[<p><img src="https://carloschac.in/public/images/java-records-jsonb.png" alt="java-records-jsonb" loading="lazy" /></p>

<p>In the previous article about Java 14 Records, we saw how to start creating Records to avoid writing much boilerplate code that the compiler would generate for us.</p>

<p>Now the next steps are to see how we can serialize records to JSON and deserialize JSON to records to be able to use them as a request/response representation for microservices.</p>

<p>In this case, we would use the JSON-B specification used by JakartaEE and MicroProfile implementations like GlashFish, TomEE, Wildfly, OpenLiberty, and Quarkus.</p>

<!-- more -->

<p>Continuing with the <a href="https://carloschac.in/2020/04/17/java-records/">same example</a> that we used in the previous article, we would need to add a JSON-B implementation, let’s add the Eclipse Yasson dependency to our existing pom.xml file:</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>org.eclipse<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>yasson<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>1.0.6<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;scope&gt;</span>test<span class="nt">&lt;/scope&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>

<h3 id="-now-lets-see-our-example-record">💾 Now let’s see our example Record:</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nc">String</span> <span class="n">firstName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">lastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">address</span><span class="o">,</span>
    <span class="nc">LocalDate</span> <span class="n">birthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="-java-14-compiler-would-generate-all-of-the-following">💡 Java 14+ compiler would generate all of the following:</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javap <span class="nt">-p</span> Person.class
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Record</span> <span class="o">{</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">lastName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">address</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="n">birthday</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">;</span>
  <span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;);</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">toString</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span><span class="o">);</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">firstName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">lastName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">address</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="nf">birthday</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="nf">achievements</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="-our-test-case-would-consist-of-using-yasson">🔨 Our test case would consist of using Yasson</h3>

<p>To serialize a record like this:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
    <span class="s">"John"</span><span class="o">,</span>
    <span class="s">"Doe"</span><span class="o">,</span>
    <span class="s">"USA"</span><span class="o">,</span>
    <span class="nc">LocalDate</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1990</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">11</span><span class="o">),</span>
    <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
<span class="o">);</span>
</code></pre></div></div>

<p>To a json output like this:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"achievements"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"Speaker"</span><span class="p">],</span><span class="w">
  </span><span class="nl">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"USA"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"birthday"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1990-11-11"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"firstName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"John"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"lastName"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Doe"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<h3 id="-lets-check-the-complete-test-code">🔎 Let’s check the complete test code:</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kt">void</span> <span class="nf">serializeRecords</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
    <span class="c1">// Given</span>
    <span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="nc">LocalDate</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1990</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">11</span><span class="o">),</span>
            <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
    <span class="o">);</span>

    <span class="kt">var</span> <span class="n">expected</span> <span class="o">=</span> <span class="s">"""
            {
                "</span><span class="n">achievements</span><span class="s">": [
                    "</span><span class="nc">Speaker</span><span class="s">"
                ],
                "</span><span class="n">address</span><span class="s">": "</span><span class="no">USA</span><span class="s">",
                "</span><span class="n">birthday</span><span class="s">": "</span><span class="mi">1990</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">11</span><span class="s">",
                "</span><span class="n">firstName</span><span class="s">": "</span><span class="nc">John</span><span class="s">",
                "</span><span class="n">lastName</span><span class="s">": "</span><span class="nc">Doe</span><span class="s">"
            }"""</span><span class="o">;</span>

    <span class="c1">// When</span>
    <span class="kt">var</span> <span class="n">jsonb</span> <span class="o">=</span> <span class="nc">JsonbBuilder</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="k">new</span> <span class="nc">JsonbConfig</span><span class="o">().</span><span class="na">withFormatting</span><span class="o">(</span><span class="kc">true</span><span class="o">));</span>
    <span class="kt">var</span> <span class="n">serialized</span> <span class="o">=</span> <span class="n">jsonb</span><span class="o">.</span><span class="na">toJson</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>

    <span class="c1">// Then</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">serialized</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">expected</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>After running the test with maven or in the IDE, we get the following assertion’s failure:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>org.opentest4j.AssertionFailedError:
Expecting:
 &lt;"
{
}"&gt;
to be equal to:
 &lt;"
{
    "achievements": [
        "Speaker"
    ],
    "address": "USA",
    "birthday": "1990-11-11",
    "firstName": "John",
    "lastName": "Doe"
}"&gt;
but was not.
</code></pre></div></div>

<p>JSON-B is serializing the record as an empty object :(</p>

<p>Let’s read the specification:</p>

<blockquote>
  <p>For a serialization operation, if a matching public getter method exists, the method is called to obtain the value of the property. If a matching getter method with private, protected or defaulted to package-only access exists, then this field is ignored. If no matching getter method exists and the field is public, then the value is obtained directly from the field.</p>
</blockquote>

<p>Let’s take a look at the field <code class="language-plaintext highlighter-rouge">firstName</code> on the record as an example:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javap <span class="nt">-p</span> Person.class
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Record</span> <span class="o">{</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">;</span> <span class="c1">// This field is private</span>
  <span class="o">.</span>
  <span class="o">.</span>
  <span class="o">.</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">firstName</span><span class="o">();</span> <span class="c1">// This property is not a getter, i.e. getFirstName()</span>
</code></pre></div></div>

<p>We are not complaining with the specification, but we can solve this renaming the field defined in the record to use the JavaBean setters convention:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nc">String</span> <span class="n">getFirstName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">getLastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">getAddress</span><span class="o">,</span>
    <span class="nc">LocalDate</span> <span class="n">getBirthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">getAchievements</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>

<p>⚠️ The above example can be problematic if we forget about adding the <code class="language-plaintext highlighter-rouge">get</code> prefix. For primitive <code class="language-plaintext highlighter-rouge">boolean</code> properties, the prefix for getters is <code class="language-plaintext highlighter-rouge">is</code> instead of <code class="language-plaintext highlighter-rouge">get</code>, also easy to forget.</p>

<p>Another alternative is to specify to the JSON-B implementation to serialize using private fields instead of the getters, for that we need to implement the <a href="http://json-b.net/docs/api/java.json.bind/javax/json/bind/config/PropertyVisibilityStrategy.html">PropertyVisibilityStrategy</a> interface.</p>

<blockquote>
  <p>Provides mechanism on how to define customized property visibility strategy.
This strategy can be set via <a href="http://json-b.net/docs/api/java.json.bind/javax/json/bind/JsonbConfig.html">JsonbConfig</a>.</p>
</blockquote>

<p>🔧 The interface has two methods:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">boolean isVisible(Field field)</code> Responds whether the given field should be considered as the JsonbProperty.</li>
  <li><code class="language-plaintext highlighter-rouge">boolean isVisible(Method method)</code> Responds whether the given method should be considered as the JsonbProperty.</li>
</ul>

<p>To achieve our goal, we want to return <code class="language-plaintext highlighter-rouge">true</code> to serialize fields and <code class="language-plaintext highlighter-rouge">false</code> to serialize methods:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">visibilityStrategy</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PropertyVisibilityStrategy</span><span class="o">()</span> <span class="o">{</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isVisible</span><span class="o">(</span><span class="nc">Field</span> <span class="n">field</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isVisible</span><span class="o">(</span><span class="nc">Method</span> <span class="n">method</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">};</span>
</code></pre></div></div>

<p>And then we pass it to the <code class="language-plaintext highlighter-rouge">JsonbConfig</code> object:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">jsonb</span> <span class="o">=</span> <span class="nc">JsonbBuilder</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="k">new</span> <span class="nc">JsonbConfig</span><span class="o">().</span><span class="na">withFormatting</span><span class="o">(</span><span class="kc">true</span><span class="o">).</span><span class="na">withPropertyVisibilityStrategy</span><span class="o">(</span><span class="n">visibilityStrategy</span><span class="o">));</span>
</code></pre></div></div>

<h3 id="️-now-we-have-a-passing-test">♻️ Now we have a passing test:</h3>

<p><img src="https://carloschac.in/public/images/records-jsonb-passing-test.png" alt="records-jsonb-passing-test" loading="lazy" /></p>

<h2 id="-testing-deserialization">💊 Testing Deserialization</h2>

<p>Let’s use the same record to try the deserialization using also the same configuration, the only thing that we need to add to our test is the deserialization itself using the <code class="language-plaintext highlighter-rouge">Jsonb</code> object and the assertion to compare:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kt">void</span> <span class="nf">serializeRecords</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
    <span class="c1">// Given</span>
    <span class="kt">var</span> <span class="n">person</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="nc">LocalDate</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1990</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">11</span><span class="o">),</span>
            <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">)</span>
    <span class="o">);</span>

    <span class="kt">var</span> <span class="n">json</span> <span class="o">=</span> <span class="s">"""

            {
                "</span><span class="n">achievements</span><span class="s">": [
                    "</span><span class="nc">Speaker</span><span class="s">"
                ],
                "</span><span class="n">address</span><span class="s">": "</span><span class="no">USA</span><span class="s">",
                "</span><span class="n">birthday</span><span class="s">": "</span><span class="mi">1990</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">11</span><span class="s">",
                "</span><span class="n">firstName</span><span class="s">": "</span><span class="nc">John</span><span class="s">",
                "</span><span class="n">lastName</span><span class="s">": "</span><span class="nc">Doe</span><span class="s">"
            }"""</span><span class="o">;</span>

    <span class="c1">// When</span>
    <span class="kt">var</span> <span class="n">visibilityStrategy</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PropertyVisibilityStrategy</span><span class="o">()</span> <span class="o">{</span>
        <span class="nd">@Override</span>
        <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isVisible</span><span class="o">(</span><span class="nc">Field</span> <span class="n">field</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
        <span class="o">}</span>

        <span class="nd">@Override</span>
        <span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">isVisible</span><span class="o">(</span><span class="nc">Method</span> <span class="n">method</span><span class="o">)</span> <span class="o">{</span>
            <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
        <span class="o">}</span>
    <span class="o">};</span>
    <span class="kt">var</span> <span class="n">jsonb</span> <span class="o">=</span> <span class="nc">JsonbBuilder</span><span class="o">.</span><span class="na">create</span><span class="o">(</span>
            <span class="k">new</span> <span class="nf">JsonbConfig</span><span class="o">()</span>
                    <span class="o">.</span><span class="na">withFormatting</span><span class="o">(</span><span class="kc">true</span><span class="o">)</span>
                    <span class="o">.</span><span class="na">withPropertyVisibilityStrategy</span><span class="o">(</span><span class="n">visibilityStrategy</span><span class="o">)</span>
    <span class="o">);</span>
    <span class="kt">var</span> <span class="n">serialized</span> <span class="o">=</span> <span class="n">jsonb</span><span class="o">.</span><span class="na">toJson</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>
    <span class="kt">var</span> <span class="n">deserialized</span> <span class="o">=</span> <span class="n">jsonb</span><span class="o">.</span><span class="na">fromJson</span><span class="o">(</span><span class="n">json</span><span class="o">,</span> <span class="nc">Person</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>

    <span class="c1">// Then</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">deserialized</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">person</span><span class="o">);</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">serialized</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">json</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Our test case fails for deserialization with the following error:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">javax</span><span class="o">.</span><span class="na">json</span><span class="o">.</span><span class="na">bind</span><span class="o">.</span><span class="na">JsonbException</span><span class="o">:</span> <span class="nc">Cannot</span> <span class="n">create</span> <span class="n">an</span> <span class="n">instance</span> <span class="n">of</span> <span class="n">a</span> <span class="kd">class</span><span class="err">:</span> <span class="nc">class</span> <span class="n">records</span><span class="o">.</span><span class="na">Person</span><span class="o">,</span> <span class="nc">No</span> <span class="k">default</span> <span class="n">constructor</span> <span class="n">found</span><span class="o">.</span>
</code></pre></div></div>

<p>📌 Per the specification, we need either to:</p>

<ul>
  <li>✅ Define an empty/null constructor</li>
  <li>✅ Define a constructor or method annotated with <code class="language-plaintext highlighter-rouge">@JsonbCreator</code></li>
</ul>

<p>But how can we do that if the compiler generates the constructor for a record?</p>

<h3 id="-java-records--compact-constructor">💾 Java Records 👷 Compact Constructor:</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nc">String</span> <span class="n">firstName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">lastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">address</span><span class="o">,</span>
    <span class="nc">LocalDate</span> <span class="n">birthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span>

    <span class="kd">public</span> <span class="nc">Person</span> <span class="o">{</span>
        <span class="k">if</span> <span class="o">(</span><span class="n">birthday</span> <span class="o">&gt;=</span> <span class="nc">LocalDate</span><span class="o">.</span><span class="na">now</span><span class="o">())</span> <span class="o">{</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span> <span class="s">"Birthday must be &lt; today!"</span><span class="o">);</span>
        <span class="o">}</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This compact constructor is meant to be used only for validation purposes as in the example above and notice that we don’t have to repeat the field parameters nor the field initializations, The remaining initialization code is supplied by the compiler.</p>

<p>But how this helps to our deserialization problem, well, as another regular constructor we can add annotations there, let’s fix it:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nc">String</span> <span class="n">firstName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">lastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">address</span><span class="o">,</span>
    <span class="nc">LocalDate</span> <span class="n">birthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span>

    <span class="nd">@JsonbCreator</span>
    <span class="kd">public</span> <span class="nc">Person</span> <span class="o">{}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>This is the decompiled bytecode generated by the compiler:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Record</span> <span class="o">{</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">lastName</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">address</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="n">birthday</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">;</span>

    <span class="nd">@javax</span><span class="o">.</span><span class="na">json</span><span class="o">.</span><span class="na">bind</span><span class="o">.</span><span class="na">annotation</span><span class="o">.</span><span class="na">JsonbCreator</span>
    <span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">lastName</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">address</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="n">birthday</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">final</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="kd">final</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span> <span class="n">o</span><span class="o">)</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">firstName</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">lastName</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">address</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="nf">birthday</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>

    <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="nf">achievements</span><span class="o">()</span> <span class="o">{</span> <span class="cm">/* compiled code */</span> <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>We can notice the <code class="language-plaintext highlighter-rouge">@JsonbCreator</code> annotation passed to the generated constructor. After that change, our test suite for serialization and deserialization of records with JSON-B passes.</p>

<h2 id="-conclusions">🔆 Conclusions</h2>

<ul>
  <li>✅ We can use records to serialize and deserialize JSON request/response objects.</li>
  <li>✅ We described two ways of achieving serialization:
    <ul>
      <li>✅ Renaming the fields to use the getter convention.</li>
      <li>✅ Adding a custom <code class="language-plaintext highlighter-rouge">PropertyVisibilityStrategy</code> to serialize using the private fields.</li>
    </ul>
  </li>
  <li>✅ We described how to achieve the deserialization using the <code class="language-plaintext highlighter-rouge">@JsonbCreator</code> annotation.</li>
  <li>🔴 Most probably, in the following versions of the JSON-B API specification records would be taken in consideration and the strategies described in this article are not going to be required.</li>
</ul>]]></content><author><name>Carlos Chacin</name></author><category term="jakartaee" /><category term="jsonb" /><category term="java14" /><category term="records" /><category term="serialization" /><summary type="html"><![CDATA[Java 14 Record is a new kind of type declaration in the Java language. In this article, we are going to see how we can serialize and deserialize records to/from JSON using JakartaEE JSON-B.]]></summary></entry><entry xml:lang="en-us"><title type="html">🚀 Java 14 Records 💾 (Preview)</title><link href="https://carloschac.in/2020/04/17/java-records/" rel="alternate" type="text/html" title="🚀 Java 14 Records 💾 (Preview)" /><published>2020-04-17T00:00:00+00:00</published><updated>2020-04-17T00:00:00+00:00</updated><id>https://carloschac.in/2020/04/17/java-records</id><content type="html" xml:base="https://carloschac.in/2020/04/17/java-records/"><![CDATA[<p><img src="https://carloschac.in/public/images/java-records.png" alt="java-records" loading="lazy" /></p>

<p><strong>Record</strong> is a new kind of type declaration in the Java language. Like an <em>enum</em>, a <em>record</em> is a restricted form of class. It declares its representation and commits to an API that matches that representation. Records give up a freedom that classes usually enjoy: the ability to decouple API from representation. In return, records gain a significant degree of concision.</p>

<p>A record has a name and a state description. The state description declares the components of the record. Optionally, a record has a body. For example:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">record</span> <span class="nf">Point</span><span class="o">(</span><span class="kt">int</span> <span class="n">x</span><span class="o">,</span> <span class="kt">int</span> <span class="n">y</span><span class="o">)</span> <span class="o">{</span> <span class="o">}</span>
</code></pre></div></div>

<!-- more -->

<h2 id="lets-get-started">Let’s get started</h2>

<h3 id="️-download-openjdk-1401">⬇️ Download OpenJDK 14.0.1</h3>

<ul>
  <li><a href="https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_linux-x64_bin.tar.gz">Linux / x64</a></li>
  <li><a href="https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_osx-x64_bin.tar.gz">macOS / x64</a></li>
  <li><a href="https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_windows-x64_bin.zip">Windows / x64</a></li>
</ul>

<h3 id="-set-the-java_home-to-point-to-the-downloaded-jdk-14">🚥 Set the JAVA_HOME to point to the downloaded JDK 14</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span>/path/to/jdk14
<span class="nv">$ </span><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$JAVA_HOME</span>/bin:<span class="nv">$PATH</span>
</code></pre></div></div>

<h3 id="-writing-our-first-java-record-">🚀 Writing our first Java Record 💾</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="n">record</span> <span class="nf">Person</span><span class="o">(</span>
    <span class="nc">String</span> <span class="n">firstName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">lastName</span><span class="o">,</span>
    <span class="nc">String</span> <span class="n">address</span><span class="o">,</span>
    <span class="nc">LocalDate</span> <span class="n">birthday</span><span class="o">,</span>
    <span class="nc">List</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="-compile-it-with-javac">💻 Compile it with <code class="language-plaintext highlighter-rouge">javac</code></h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javac <span class="nt">--enable-preview</span> <span class="nt">-source</span> 14 Person.java
</code></pre></div></div>

<h3 id="-compile-it-with-maven">💻 Compile it with <code class="language-plaintext highlighter-rouge">maven</code></h3>

<p>Add the following configuration for the compiler plugin in your <code class="language-plaintext highlighter-rouge">pom.xml</code></p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;plugin&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>maven-compiler-plugin<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>3.8.1<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;configuration&gt;</span>
        <span class="nt">&lt;release&gt;</span>14<span class="nt">&lt;/release&gt;</span>
        <span class="nt">&lt;compilerArgs&gt;</span>--enable-preview<span class="nt">&lt;/compilerArgs&gt;</span>
    <span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>mvn compile
</code></pre></div></div>

<h3 id="-whats-generated-by-the-compiler">🚧 What’s generated by the compiler?</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>javap <span class="nt">-p</span> Person.class
</code></pre></div></div>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="kd">extends</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Record</span> <span class="o">{</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">firstName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">lastName</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="n">address</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="n">birthday</span><span class="o">;</span>
  <span class="kd">private</span> <span class="kd">final</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="n">achievements</span><span class="o">;</span>
  <span class="kd">public</span> <span class="nf">Person</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span><span class="o">,</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;);</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">toString</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">int</span> <span class="nf">hashCode</span><span class="o">();</span>
  <span class="kd">public</span> <span class="kd">final</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">Object</span><span class="o">);</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">firstName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">lastName</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span> <span class="nf">address</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">time</span><span class="o">.</span><span class="na">LocalDate</span> <span class="nf">birthday</span><span class="o">();</span>
  <span class="kd">public</span> <span class="n">java</span><span class="o">.</span><span class="na">util</span><span class="o">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="o">.</span><span class="na">lang</span><span class="o">.</span><span class="na">String</span><span class="o">&gt;</span> <span class="nf">achievements</span><span class="o">();</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Because records make the semantic claim of being simple, transparent holders for their data, a record acquires many standard members automatically:</p>

<ul>
  <li>A private final field for each component of the state description;</li>
  <li>A public read accessor method for each element of the state description, with the same name and type as the component;</li>
  <li>A public constructor, whose signature is the same as the state description, which initializes each field from the corresponding argument;</li>
  <li>Implementations of equals and hashCode that say two records are equal if they are of the same type and contain the same state; and</li>
  <li>An implementation of toString that includes the string representation of all the record components, with their names.</li>
</ul>

<h2 id="️-shallowly-immutable-data">⚠️ Shallowly Immutable Data</h2>

<p>Similarly to the tests that we did in the article <a href="https://carloschac.in/2020/04/12/immutables-autovalue-lombok/">Immutables/AutoValue/Lombok Which One?</a> where we check the default behavior in terms of immutability for those libraries, with the below test we demonstrate the statement mentioned in the <a href="https://openjdk.java.net/jeps/359">JEP 359: Records</a>:</p>

<blockquote>
  <p>Records provide a compact syntax for declaring classes, which are transparent holders for <strong>shallowly immutable data</strong>.</p>
</blockquote>

<h4 id="-test-immutability">📐 Test Immutability</h4>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kt">void</span> <span class="nf">immutability</span><span class="o">()</span> <span class="o">{</span>
    <span class="c1">// Create a mutable list with 1 element</span>
    <span class="kt">var</span> <span class="n">achievements1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ArrayList</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">&gt;();</span>
    <span class="n">achievements1</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">);</span>
    <span class="n">achievements1</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"Blogger"</span><span class="o">);</span>
    <span class="kt">var</span> <span class="n">achievements2</span> <span class="o">=</span> <span class="nc">List</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="s">"Speaker"</span><span class="o">,</span> <span class="s">"Blogger"</span><span class="o">);</span>


    <span class="c1">// Create person 1, assigning the list1</span>
    <span class="kt">var</span> <span class="n">person1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="nc">LocalDate</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1990</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">11</span><span class="o">),</span>
            <span class="n">achievements1</span>
    <span class="o">);</span>

    <span class="c1">// Create person 2, assigning the list2</span>
    <span class="kt">var</span> <span class="n">person2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Person</span><span class="o">(</span>
            <span class="s">"John"</span><span class="o">,</span>
            <span class="s">"Doe"</span><span class="o">,</span>
            <span class="s">"USA"</span><span class="o">,</span>
            <span class="nc">LocalDate</span><span class="o">.</span><span class="na">of</span><span class="o">(</span><span class="mi">1990</span><span class="o">,</span> <span class="mi">11</span><span class="o">,</span> <span class="mi">11</span><span class="o">),</span>
            <span class="n">achievements2</span>
    <span class="o">);</span>

    <span class="c1">// Compare the 2 objects</span>
    <span class="c1">// Test passes since the fields contain the same values</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">person1</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="n">person2</span><span class="o">);</span>

    <span class="c1">// Mutate the list used on Model 1</span>
    <span class="n">achievements1</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="s">"AnotherValue"</span><span class="o">);</span>

    <span class="c1">// Compare the 2 objects:</span>
    <span class="c1">// - PASSES objects are NOT EQUAL for Records 😮 🔴</span>
    <span class="n">assertThat</span><span class="o">(</span><span class="n">person1</span><span class="o">).</span><span class="na">isNotEqualTo</span><span class="o">(</span><span class="n">person2</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>There are two ways of guaranteeing immutability when using records with mutable data types in their signature or when the data type is an interface, and we are not sure about the implementation, i.e., <code class="language-plaintext highlighter-rouge">java.util.Date</code> or <code class="language-plaintext highlighter-rouge">java.util.List</code></p>

<ol>
  <li>Create a safe copy of the data type in the record’s constructor.</li>
  <li>Pass only immutable objects when creating the records.</li>
</ol>

<h2 id="-conclusions">🔆 Conclusions</h2>

<ul>
  <li>✅ <em>Records</em> can reduce several lines of code to a one-liner.</li>
  <li>✅ With JDK 14, we can prescind of using some code generation libraries to minimize boilerplate code.</li>
  <li>✅ A great option for:
    <ul>
      <li>🔝 Tree nodes</li>
      <li>🔝 DTOs</li>
      <li>🔝 Compound map keys</li>
      <li>🔝 Messages</li>
      <li>🔝 Value wrappers</li>
      <li>🔝 Discriminated Entities</li>
    </ul>
  </li>
  <li>⚠️ <em>Records</em> are only <strong>Shallowly Immutables</strong>, which means that we have to take into consideration the data types passed to them if we want to guarantee immutability.</li>
  <li>⚠️ <em>Records</em> are a preview language feature, and it is not yet a standard in the JDK.</li>
</ul>]]></content><author><name>Carlos Chacin</name></author><category term="java" /><category term="jdk" /><category term="jdk14" /><category term="java14" /><category term="records" /><category term="immutability" /><summary type="html"><![CDATA[Java 14 Record is a new kind of type declaration in the Java language. Like an enum, a record is a restricted form of class. It declares its representation and commits to an API that matches that representation.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://carloschac.in/public/images/java-records.png" /><media:content medium="image" url="https://carloschac.in/public/images/java-records.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>