<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Java on Omar H.Ajmi | Python, Java, Terraform &amp; DevOps TILs</title>
    <link>https://omar-ajmi.de5.net/tags/java/</link>
    <description>Recent content in Java on Omar H.Ajmi | Python, Java, Terraform &amp; DevOps TILs</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://omar-ajmi.de5.net/tags/java/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>☕ Java records: immutable-ish, like a chocolate shell</title>
      <link>https://omar-ajmi.de5.net/posts/en/java-records-immutability/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://omar-ajmi.de5.net/posts/en/java-records-immutability/</guid>
      <description>&lt;h1 id=&#34;-java-records-immutable-ish-like-a-chocolate-shell&#34; class=&#34;header-anchor-wrapper&#34;&gt;☕ Java records: immutable-ish, like a chocolate shell
  &lt;a href=&#34;#-java-records-immutable-ish-like-a-chocolate-shell&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Java records are lovely. Less boilerplate, clear intent, and no 47-line class just to carry a name and a list.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a small catch: &lt;strong&gt;a record doesn&amp;rsquo;t automatically make everything inside it immutable.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&#34;-the-plot-twist&#34; class=&#34;header-anchor-wrapper&#34;&gt;🧠 The plot twist
  &lt;a href=&#34;#-the-plot-twist&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h2&gt;

&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;public&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;record&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;User&lt;/span&gt;(String name, List&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;String&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; roles) {}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The record&amp;rsquo;s component fields are final. But if &lt;code&gt;roles&lt;/code&gt; refers to a mutable &lt;code&gt;ArrayList&lt;/code&gt;, that list can still change.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>🥫 Spring Boot: stop blaming application.yml</title>
      <link>https://omar-ajmi.de5.net/posts/en/springboot-yml-configs/</link>
      <pubDate>Sun, 13 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://omar-ajmi.de5.net/posts/en/springboot-yml-configs/</guid>
      <description>&lt;h1 id=&#34;-spring-boot-stop-blaming-applicationyml&#34; class=&#34;header-anchor-wrapper&#34;&gt;🥫 Spring Boot: stop blaming application.yml
  &lt;a href=&#34;#-spring-boot-stop-blaming-applicationyml&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;The app works locally. In staging, a feature flag is wrong, the port is unexpected, or the service is calling an endpoint nobody remembers configuring.&lt;/p&gt;
&lt;p&gt;You open &lt;code&gt;application.yml&lt;/code&gt;. It looks perfect.&lt;/p&gt;
&lt;p&gt;Time to interrogate the YAML? Not yet. It may have an alibi.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>🧵 Java 24: Virtual Threads Finally Stop Getting Stuck on synchronized</title>
      <link>https://omar-ajmi.de5.net/posts/en/java-virtual-threads-synchronized-pinning/</link>
      <pubDate>Tue, 12 Aug 2025 00:00:00 +0000</pubDate>
      
      <guid>https://omar-ajmi.de5.net/posts/en/java-virtual-threads-synchronized-pinning/</guid>
      <description>&lt;h1 id=&#34;-java-24-virtual-threads-finally-stop-getting-stuck-on-synchronized&#34; class=&#34;header-anchor-wrapper&#34;&gt;🧵 Java 24: Virtual Threads Finally Stop Getting Stuck on synchronized
  &lt;a href=&#34;#-java-24-virtual-threads-finally-stop-getting-stuck-on-synchronized&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Virtual threads arrived in Java 21 with a promise: block as much as you like, we&amp;rsquo;ll make threads cheap. Then came the footnote about &lt;code&gt;synchronized&lt;/code&gt;, which sent many people off to rewrite code with &lt;code&gt;ReentrantLock&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>🪵 Spring Boot: Structured Logging Without Writing a Single Encoder</title>
      <link>https://omar-ajmi.de5.net/posts/en/spring-boot-structured-logging/</link>
      <pubDate>Mon, 20 Jan 2025 00:00:00 +0000</pubDate>
      
      <guid>https://omar-ajmi.de5.net/posts/en/spring-boot-structured-logging/</guid>
      <description>&lt;h1 id=&#34;-spring-boot-structured-logging-without-writing-a-single-encoder&#34; class=&#34;header-anchor-wrapper&#34;&gt;🪵 Spring Boot: Structured Logging Without Writing a Single Encoder
  &lt;a href=&#34;#-spring-boot-structured-logging-without-writing-a-single-encoder&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Your log aggregator wants JSON. Your application prints a friendly sentence with a timestamp, a thread name and a few dashes.&lt;/p&gt;
&lt;p&gt;For years the fix was a hand-rolled Logback encoder, or an extra dependency, or a regex in the log pipeline that everyone was afraid to touch.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>☕ Spring Boot: The @Transactional Self-Invocation Trap</title>
      <link>https://omar-ajmi.de5.net/posts/en/spring-boot-transactional-ghost-bug/</link>
      <pubDate>Wed, 07 Feb 2024 00:00:00 +0000</pubDate>
      
      <guid>https://omar-ajmi.de5.net/posts/en/spring-boot-transactional-ghost-bug/</guid>
      <description>&lt;h1 id=&#34;-spring-boot-the-transactional-self-invocation-trap&#34; class=&#34;header-anchor-wrapper&#34;&gt;☕ Spring Boot: The &lt;code&gt;@Transactional&lt;/code&gt; Self-Invocation Trap
  &lt;a href=&#34;#-spring-boot-the-transactional-self-invocation-trap&#34; class=&#34;header-anchor-link&#34;&gt;
    &lt;svg width=&#34;16px&#34; height=&#34;16px&#34; viewBox=&#34;0 0 24 24&#34;&gt;
&lt;svg
    xmlns=&#34;http://www.w3.org/2000/svg&#34;
    width=&#34;24&#34; height=&#34;24&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34;
    stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34;
    stroke-linejoin=&#34;round&#34;&gt;
    &lt;line x1=&#34;4&#34; y1=&#34;9&#34; x2=&#34;20&#34; y2=&#34;9&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;4&#34; y1=&#34;15&#34; x2=&#34;20&#34; y2=&#34;15&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;10&#34; y1=&#34;3&#34; x2=&#34;8&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;&lt;line x1=&#34;16&#34; y1=&#34;3&#34; x2=&#34;14&#34; y2=&#34;21&#34;&gt;&lt;/line&gt;
&lt;/svg&gt;

&lt;/svg&gt;
  &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;You added &lt;code&gt;@Transactional&lt;/code&gt;. You threw a &lt;code&gt;RuntimeException&lt;/code&gt;. You expected the database to roll back.&lt;/p&gt;
&lt;p&gt;Yet somehow, your data is still there.&lt;/p&gt;
&lt;p&gt;Before blaming your database, check how the method was called. Spring has a little trap called &lt;strong&gt;self-invocation&lt;/strong&gt;, and it can make your transaction annotation look suspiciously decorative.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>