<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://inside.java/feed.xml" rel="self" type="application/atom+xml" /><link href="https://inside.java/" rel="alternate" type="text/html" /><updated>2026-05-21T08:28:21+00:00</updated><id>https://inside.java/feed.xml</id><title type="html">insidejava</title><subtitle>News and views from members of the Java team at Oracle</subtitle><entry><title type="html">On Default Values for Primitive-Like Classes</title><link href="https://inside.java/2026/05/21/values-primitive-classes/" rel="alternate" type="text/html" title="On Default Values for Primitive-Like Classes" /><published>2026-05-21T00:00:00+00:00</published><updated>2026-05-21T00:00:00+00:00</updated><id>https://inside.java/2026/05/21/values-primitive-classes</id><content type="html" xml:base="https://inside.java/2026/05/21/values-primitive-classes/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/DukeReadingDocuments.png" /></p>]]></content><author><name>[&quot;JohnRose&quot;]</name></author><category term="Valhalla" /><summary type="html"><![CDATA[Primitive defaults are chosen so that they are (probably) represented by memory set to one or more bytes with all bits set to zero; we call these all-zero-bits values. We want “primitive-like” classes to have similar optimization opportunities, even if some classes will choose to nominate defaults values that are not all-zero-bits values. This document discusses possible semantics for such default values, as well as examines their possible quality of implementation, as supported by the JVM and runtime. It will look at cross-cutting interactions with class definition, classfile format, class initialization, bytecode verification, instance construction, and array creation (with some notes on frozen arrays).]]></summary></entry><entry><title type="html">Quality Outreach Heads-up - JDK 27: Numeric Fields in JSON Thread Dumps</title><link href="https://inside.java/2026/05/20/quality-heads-up/" rel="alternate" type="text/html" title="Quality Outreach Heads-up - JDK 27: Numeric Fields in JSON Thread Dumps" /><published>2026-05-20T00:00:00+00:00</published><updated>2026-05-20T00:00:00+00:00</updated><id>https://inside.java/2026/05/20/Quality-Heads-Up</id><content type="html" xml:base="https://inside.java/2026/05/20/quality-heads-up/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>

<p><em>The <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">OpenJDK Quality Group</a> is promoting the testing of FOSS projects with OpenJDK builds as a way to improve the overall quality of the release. This heads-up is part of a <a href="https://mail.openjdk.org/archives/list/quality-discuss@openjdk.org/thread/REAJQSW4DJ6BZNEKLGU56HB2757I26HM/">Quality Outreach</a> update sent to the projects involved. To learn more about the program and how to join, please check the <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">Quality Outreach wiki page</a>.</em></p>

<h2 id="numeric-values-usage-in-json-thread-dumps">Numeric Values Usage in JSON Thread Dumps</h2>

<p>JSON thread dumps generated by <code class="language-plaintext highlighter-rouge">com.sun.management.HotSpotDiagnosticMXBean.dumpThreads</code> and the<code class="language-plaintext highlighter-rouge"> jcmd Thread.dump_to_file</code> command now write thread identifiers, thread counts, and the process identifier as JSON numbers instead of strings.</p>

<p>For example, when using a command like <code class="language-plaintext highlighter-rouge">jcmd &lt;PID&gt; Thread.dump_to_file -format=json threads.json</code> to write thread stack traces to a file in JSON format, the output would look like in the snippet below.</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">"threadDump"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"formatVersion"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
    </span><span class="nl">"processId"</span><span class="p">:</span><span class="w"> </span><span class="mi">36340</span><span class="p">,</span><span class="w">
    </span><span class="nl">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-05-15T12:43:21.601545Z"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"runtimeVersion"</span><span class="p">:</span><span class="w"> </span><span class="s2">"27-ea+22-2010"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"threadContainers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
      </span><span class="p">{</span><span class="w">
        </span><span class="nl">"container"</span><span class="p">:</span><span class="w"> </span><span class="s2">"&lt;root&gt;"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"parent"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
        </span><span class="nl">"owner"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
        </span><span class="nl">"threads"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
          </span><span class="p">{</span><span class="w">
            </span><span class="nl">"tid"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w">
            </span><span class="nl">"time"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2026-05-15T12:43:21.604046Z"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"main"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="s2">"TIMED_WAITING"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"stack"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
              </span><span class="s2">"java.base</span><span class="se">\/</span><span class="s2">java.lang.Thread.sleepNanos0(Native Method)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"java.base</span><span class="se">\/</span><span class="s2">java.lang.Thread.sleepNanos(Thread.java:562)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"java.base</span><span class="se">\/</span><span class="s2">java.lang.Thread.sleep(Thread.java:593)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"HelloThreads.main(HelloThreads.java:4)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"java.base</span><span class="se">\/</span><span class="s2">jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"java.base</span><span class="se">\/</span><span class="s2">java.lang.reflect.Method.invoke(Method.java:583)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"jdk.compiler</span><span class="se">\/</span><span class="s2">com.sun.tools.javac.launcher.SourceLauncher.execute(SourceLauncher.java:260)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"jdk.compiler</span><span class="se">\/</span><span class="s2">com.sun.tools.javac.launcher.SourceLauncher.run(SourceLauncher.java:138)"</span><span class="p">,</span><span class="w">
              </span><span class="s2">"jdk.compiler</span><span class="se">\/</span><span class="s2">com.sun.tools.javac.launcher.SourceLauncher.main(SourceLauncher.java:76)"</span><span class="w">
            </span><span class="p">]</span><span class="w">
          </span><span class="p">}</span><span class="w">
        </span><span class="p">],</span><span class="w">
        </span><span class="nl">"threadCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">7</span><span class="w">
      </span><span class="p">}</span><span class="w">
      </span><span class="err">....</span><span class="w">
    </span><span class="p">]</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>This change of format also introduces versioning through <code class="language-plaintext highlighter-rouge">"formatVersion": 2</code> member, while metadata fields such as <code class="language-plaintext highlighter-rouge">processId</code>, <code class="language-plaintext highlighter-rouge">tid</code>, and <code class="language-plaintext highlighter-rouge">threadCount</code> are serialized as JSON numeric values rather than JSON string types.</p>

<h2 id="call-to-action">Call to Action</h2>

<p>We encourage you to download the <a href="https://jdk.java.net/27/">JDK 27 early-access builds</a> and test any tools, scripts, tests, or applications that parse JSON thread dumps.
If needed, update them to handle numeric values for thread identifiers, thread counts, and the process identifier, and use the new formatVersion field to detect and handle future thread dump format changes.</p>

<center>~</center>]]></content><author><name>[&quot;Ana-MariaMihalceanu&quot;]</name></author><category term="JDK 27" /><category term="Serviceability" /><summary type="html"><![CDATA[This Heads-Up is part of the regular communication sent to the projects involved; it covers thatJSON thread dumps now emit thread identifiers, thread counts, and the process identifier as numeric types.]]></summary></entry><entry><title type="html">Java 26: Better Language, Better APIs, Better Runtime</title><link href="https://inside.java/2026/05/19/javaone-better-jdk26/" rel="alternate" type="text/html" title="Java 26: Better Language, Better APIs, Better Runtime" /><published>2026-05-19T00:00:00+00:00</published><updated>2026-05-19T00:00:00+00:00</updated><id>https://inside.java/2026/05/19/JavaOne-Better-JDK26</id><content type="html" xml:base="https://inside.java/2026/05/19/javaone-better-jdk26/"><![CDATA[<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/86eK0Or2eIE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>Since JavaOne 2025, JDK 25 was released, the latest version with long-term support. But Java never stands still; it’s already time to ship JDK 26. This talk summarizes the most important changes between Java 21 and 25:</em></p>

<ul>
  <li><em>from unnamed patterns and flexible constructors to module imports</em></li>
  <li><em>from the foreign-function and memory API to stream gatherers and the class-file API</em></li>
  <li><em>from a simpler <code class="language-plaintext highlighter-rouge">main</code> to launching multisource-file programs</em></li>
  <li><em>from Markdown in JavaDoc to quantum-resistant encryption</em></li>
  <li><em>from faster launch times to improved garbage collection</em></li>
</ul>

<p><em>… before taking a closer look at the newest release, including its preview features:</em></p>

<ul>
  <li><em>Primitive patterns and lazy constants</em></li>
  <li><em>Updated structured concurrency</em></li>
  <li><em>PEM encoding and HTTP/3 support</em></li>
  <li><em>New command-line options to enable deep reflection</em></li>
</ul>

<p><em>There are plenty of features in the language, API, and runtime to discuss; whether new, improved, or finalized. Let’s go over them.</em></p>

<p><em>Make sure to check the <a href="https://www.youtube.com/playlist?list=PLX8CzqL3ArzUMVSzm-z_-if8BIB55EGl4">JavaOne 2026 playlist</a>.</em></p>]]></content><author><name>[&quot;NicolaiParlog&quot;]</name></author><category term="JDK 26" /><summary type="html"><![CDATA[Since JavaOne 2025, Java has moved from JDK 25, the latest LTS release, toward JDK 26, with major updates across the language, APIs, runtime, tooling, security, startup performance, and garbage collection. This talk reviews the most important changes from Java 21 through 25, then explores JDK 26 and its preview features, including primitive patterns, lazy constants, structured concurrency, PEM encoding, HTTP/3, and new deep-reflection options.]]></summary></entry><entry><title type="html">Caching for Agentic Java Systems: Internal, Distributed, and Semantic</title><link href="https://inside.java/2026/05/18/javaone-caching-agentic-ai/" rel="alternate" type="text/html" title="Caching for Agentic Java Systems: Internal, Distributed, and Semantic" /><published>2026-05-18T00:00:00+00:00</published><updated>2026-05-18T00:00:00+00:00</updated><id>https://inside.java/2026/05/18/JavaOne-Caching-Agentic-AI</id><content type="html" xml:base="https://inside.java/2026/05/18/javaone-caching-agentic-ai/"><![CDATA[<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/YPxMiaXToWs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>Caching is a first-class architectural concern in agentic systems. This talk breaks down how Java applications can layer internal, distributed, and semantic caches. We’ll explore in-process caching with Caffeine for ultra-low-latency access, distributed caching with Redisson and Valkey for shared cache and semantic caching using Vector Similarity Search to reduce latency and cost while scaling LLM access.</em></p>

<p><em>Make sure to check the <a href="https://www.youtube.com/playlist?list=PLX8CzqL3ArzUMVSzm-z_-if8BIB55EGl4">JavaOne 2026 playlist</a>.</em></p>]]></content><author><name></name></author><category term="AI" /><summary type="html"><![CDATA[Caching is a first-class architectural concern in agentic systems. This talk breaks down how Java applications can layer internal, distributed, and semantic caches. We'll explore in-process caching with Caffeine for ultra-low-latency access, distributed caching with Redisson and Valkey for shared cache and semantic caching using Vector Similarity Search to reduce latency and cost while scaling LLM access.]]></summary></entry><entry><title type="html">JEP targeted to JDK 27: 531: Lazy Constants (3rd Preview)</title><link href="https://inside.java/2026/05/17/jep531-target-jdk27/" rel="alternate" type="text/html" title="JEP targeted to JDK 27: 531: Lazy Constants (3rd Preview)" /><published>2026-05-17T00:00:00+00:00</published><updated>2026-05-17T00:00:00+00:00</updated><id>https://inside.java/2026/05/17/JEP531-target-JDK27</id><content type="html" xml:base="https://inside.java/2026/05/17/jep531-target-jdk27/"><![CDATA[<p>The following JEP is targeted to JDK 27: 531: Lazy Constants (Third Preview)</p>

<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/jep.jpg?499236221" /></p>]]></content><author><name>[&quot;Per-AkeMinborg&quot;, &quot;MaurizioCimadamore&quot;]</name></author><category term="JDK 27" /><category term="Core Libraries" /><summary type="html"><![CDATA[The following JEP is targeted to JDK 27: 531: Lazy Constants (Third Preview)]]></summary></entry><entry><title type="html">Quality Outreach Heads-up - JDK 27: Post-Quantum Hybrid Key Exchange for TLS 1.3</title><link href="https://inside.java/2026/05/17/quality-heads-up/" rel="alternate" type="text/html" title="Quality Outreach Heads-up - JDK 27: Post-Quantum Hybrid Key Exchange for TLS 1.3" /><published>2026-05-17T00:00:00+00:00</published><updated>2026-05-17T00:00:00+00:00</updated><id>https://inside.java/2026/05/17/Quality-Heads-Up</id><content type="html" xml:base="https://inside.java/2026/05/17/quality-heads-up/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>

<p><i>The <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">OpenJDK Quality Group</a> is promoting the testing of FOSS projects with OpenJDK builds as a way to improve the overall quality of the release. This heads-up is part of a <a href="https://mail.openjdk.org/archives/list/quality-discuss@openjdk.org/thread/REAJQSW4DJ6BZNEKLGU56HB2757I26HM/">Quality Outreach</a> update sent to the projects involved. To learn more about the program, and how-to join, please check <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">here</a>.</i></p>

<h2 id="configure-hybrid-key-exchange-support">Configure Hybrid Key Exchange Support</h2>

<p><a href="https://openjdk.org/jeps/527">JEP 527</a> has been integrated in JDK 27 early-access builds, bringing hybrid post-quantum key exchange to TLS 1.3. This improves Java’s TLS implementation by combining traditional elliptic-curve key algorithms with quantum-resistant ML-KEM, helping protect against future <a href="https://en.wikipedia.org/wiki/Harvest_now%2C_decrypt_later">harvest-now, decrypt-later</a> threats.</p>

<p>Java applications that use the standard <code class="language-plaintext highlighter-rouge">javax.net.ssl</code> APIs can benefit by default, without code changes, as long as they do not override the TLS named groups. 
By default, JDK 27 enables <code class="language-plaintext highlighter-rouge">X25519MLKEM768</code> alongside existing classical key exchange algorithms, so TLS clients offer both a hybrid <code class="language-plaintext highlighter-rouge">X25519MLKEM768</code> key share and a traditional <code class="language-plaintext highlighter-rouge">x25519</code> key share.</p>

<p>JDK 27 adds three hybrid key exchange options through the SunJSSE provider:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">X25519MLKEM768</code> is a hybrid scheme combining <code class="language-plaintext highlighter-rouge">ECDHE</code> with <code class="language-plaintext highlighter-rouge">X25519</code> and <code class="language-plaintext highlighter-rouge">ML-KEM-768</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">SecP256r1MLKEM768</code> is a hybrid scheme combining <code class="language-plaintext highlighter-rouge">ECDHE</code> using the <code class="language-plaintext highlighter-rouge">secp256r1</code> curve with <code class="language-plaintext highlighter-rouge">ML-KEM-768</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">SecP384r1MLKEM1024</code> is a hybrid scheme combining <code class="language-plaintext highlighter-rouge">ECDHE</code> using the <code class="language-plaintext highlighter-rouge">secp384r1</code> curve with <code class="language-plaintext highlighter-rouge">ML-KEM-1024</code>.</li>
</ul>

<p>You can customize the enabled groups either with the <code class="language-plaintext highlighter-rouge">jdk.tls.namedGroups</code> system property or programmatically via <code class="language-plaintext highlighter-rouge">SSLParameters::setNamedGroups</code>:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">SSLSocket</span> <span class="n">tlsSocket</span> <span class="o">=</span> <span class="o">(</span><span class="nc">SSLSocket</span><span class="o">)</span> <span class="nc">SSLContext</span><span class="o">.</span><span class="na">getDefault</span><span class="o">()</span>
        <span class="o">.</span><span class="na">getSocketFactory</span><span class="o">()</span>
        <span class="o">.</span><span class="na">createSocket</span><span class="o">();</span>

<span class="nc">SSLParameters</span> <span class="n">params</span> <span class="o">=</span> <span class="n">tlsSocket</span><span class="o">.</span><span class="na">getSSLParameters</span><span class="o">();</span>

<span class="n">params</span><span class="o">.</span><span class="na">setNamedGroups</span><span class="o">(</span><span class="k">new</span> <span class="nc">String</span><span class="o">[]</span> <span class="o">{</span>
        <span class="s">"SecP384r1MLKEM1024"</span><span class="o">,</span>
        <span class="s">"X25519MLKEM768"</span><span class="o">,</span>
        <span class="s">"secp384r1"</span><span class="o">,</span>
        <span class="s">"x25519"</span>
<span class="o">});</span>

<span class="n">tlsSocket</span><span class="o">.</span><span class="na">setSSLParameters</span><span class="o">(</span><span class="n">params</span><span class="o">);</span>
</code></pre></div></div>

<h2 id="call-to-action">Call to Action</h2>

<p>As this implementation is still new, we encourage you to download the <a href="https://jdk.java.net/27/">JDK 27 early-access builds</a>, try this feature, and share your feedback through the <a href="https://mail.openjdk.org/mailman/listinfo/security-dev">security-dev OpenJDK mailing list</a> (registration required).</p>

<center>~</center>]]></content><author><name>[&quot;Ana-MariaMihalceanu&quot;]</name></author><category term="JDK 27" /><category term="Security" /><summary type="html"><![CDATA[This Heads-Up is part of the regular communication sent to the projects involved; it covers that JDK 27 EA Builds now include post-quantum hybrid key exchange for TLS 1.3.]]></summary></entry><entry><title type="html">Post-Mortem JVM Crash Analysis with jcmd</title><link href="https://inside.java/2026/05/16/javaone-jcmd-jvm-analysis/" rel="alternate" type="text/html" title="Post-Mortem JVM Crash Analysis with jcmd" /><published>2026-05-16T00:00:00+00:00</published><updated>2026-05-16T00:00:00+00:00</updated><id>https://inside.java/2026/05/16/JavaOne-Jcmd-JVM-Analysis</id><content type="html" xml:base="https://inside.java/2026/05/16/javaone-jcmd-jvm-analysis/"><![CDATA[<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/mng0DTspxpQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>This session highlights the progress of JEP 528, which brings core dump and minidump support to jcmd. The jcmd tool is widely used for monitoring and troubleshooting live HotSpot JVMs. With JEP 528, jcmd will also be able to diagnose crashed JVMs, creating a more consistent troubleshooting experience across both live and post-mortem environments.</em></p>

<p><em>Join us for a deep dive into the future of JVM crash analysis and post-mortem diagnostics.</em></p>

<p><em>Make sure to check the <a href="https://www.youtube.com/playlist?list=PLX8CzqL3ArzUMVSzm-z_-if8BIB55EGl4">JavaOne 2026 playlist</a>.</em></p>]]></content><author><name>[&quot;FairozMatte&quot;]</name></author><category term="HotSpot" /><category term="Serviceability" /><summary type="html"><![CDATA[This session highlights the progress of JEP 528, which brings core dump and minidump support to jcmd. The jcmd tool is widely used for monitoring and troubleshooting live HotSpot JVMs. With JEP 528, jcmd will also be able to diagnose crashed JVMs, creating a more consistent troubleshooting experience across both live and post-mortem environments.]]></summary></entry><entry><title type="html">Quality Outreach Heads-up - JDK 26: Warnings About Final Field Mutation</title><link href="https://inside.java/2026/05/15/quality-heads-up/" rel="alternate" type="text/html" title="Quality Outreach Heads-up - JDK 26: Warnings About Final Field Mutation" /><published>2026-05-15T00:00:00+00:00</published><updated>2026-05-15T00:00:00+00:00</updated><id>https://inside.java/2026/05/15/Quality-Heads-Up</id><content type="html" xml:base="https://inside.java/2026/05/15/quality-heads-up/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>

<p><em>The <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">OpenJDK Quality Group</a> is promoting the testing of FOSS projects with OpenJDK builds as a way to improve the overall quality of the release. This heads-up is part of a <a href="https://mail.openjdk.org/archives/list/quality-discuss@openjdk.org/thread/REAJQSW4DJ6BZNEKLGU56HB2757I26HM/">Quality Outreach</a> update sent to the projects involved. To learn more about the program and how to join, please check the <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">Quality Outreach wiki page</a>.</em></p>

<h2 id="reflective-mutation-of-final-fields">Reflective Mutation of Final Fields</h2>

<p>Java’s reflection API is a powerful meta-programming tool and a cornerstone of the ecosystem’s capabilities - without it, many important frameworks and libraries were impossible.
It does not come without downsides, though.
One is its ability to undermine the integrity of the keyword <code class="language-plaintext highlighter-rouge">final</code>, which promises that such a field is assigned exactly once, but, with reflection, that promise can be easily broken:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">main</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
	<span class="kt">var</span> <span class="n">box</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Box</span><span class="o">(</span><span class="s">"element"</span><span class="o">);</span>
	<span class="c1">// prints "[element]"</span>
	<span class="no">IO</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">box</span><span class="o">);</span>

	<span class="kt">var</span> <span class="n">elementField</span> <span class="o">=</span> <span class="nc">Box</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getDeclaredField</span><span class="o">(</span><span class="s">"element"</span><span class="o">);</span>
	<span class="n">elementField</span><span class="o">.</span><span class="na">setAccessible</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>
	<span class="n">elementField</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">box</span><span class="o">,</span> <span class="s">"new element"</span><span class="o">);</span>

	<span class="c1">// prints "[new element]"</span>
	<span class="no">IO</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">box</span><span class="o">);</span>
<span class="o">}</span>

<span class="kd">class</span> <span class="nc">Box</span> <span class="o">{</span>

	<span class="kd">final</span> <span class="nc">String</span> <span class="n">element</span><span class="o">;</span>

	<span class="nc">Box</span><span class="o">(</span><span class="nc">String</span> <span class="n">element</span><span class="o">)</span> <span class="o">{</span>
		<span class="k">this</span><span class="o">.</span><span class="na">element</span> <span class="o">=</span> <span class="n">element</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="nc">String</span> <span class="nf">toString</span><span class="o">()</span> <span class="o">{</span>
		<span class="k">return</span> <span class="s">"["</span> <span class="o">+</span> <span class="n">element</span> <span class="o">+</span> <span class="s">"]"</span><span class="o">;</span>
	<span class="o">}</span>

<span class="o">}</span>
</code></pre></div></div>

<p>Final field mutation has unfortunate downstream effects where developers can’t rely on established invariants for correctness or for security, and the just-in-time compiler can’t apply all possible optimizations (particularly constant-folding).
This is why recent additions to Java that deal with fields do not allow their mutation through reflection: hidden classes, records, and the preview API <code class="language-plaintext highlighter-rouge">LazyConstant</code>.</p>

<h2 id="integrity-by-default">Integrity by Default</h2>

<p>The characteristics of reflection follow a pattern where Java occasionally makes guarantees whose integrity can be undermined with the very tools it comes with.
Of course, the application of these tools can be generally beneficial (as is the case here) but that doesn’t erase the negative impact on a project’s maintainability, security, or performance that comes from undermining Java’s integrity.
There is clearly a tradeoff.</p>

<p>Since the additional capabilities as well as the potential downsides are ultimately borne by applications (not frameworks nor libraries), it should be their developers or operators who make the tradeoff.
This is achieved by making Java stricter by default, by making it uphold the integrity of its guarantees unless specific actions are taken by application maintainers.
So the various ways to undermine Java’s integrity are either replaced by features without that capability or (more often) guarded by command-line options:</p>

<ul>
  <li>module internals <a href="https://openjdk.org/jeps/403">are strongly encapsulated</a> by default, but access is possible with <code class="language-plaintext highlighter-rouge">--add-exports</code> and <code class="language-plaintext highlighter-rouge">--add-opens</code></li>
  <li>attaching an agent at run time <a href="https://openjdk.org/jeps/451">leads to a warning</a> (in the future, an error) unless allowed with <code class="language-plaintext highlighter-rouge">-XX:+EnableDynamicAgentLoading</code></li>
  <li>calling a restricted JNI or FFM method <a href="https://openjdk.org/jeps/472">causes a warning</a> (in the future, an error) unless allowed with <code class="language-plaintext highlighter-rouge">--enable-native-access</code></li>
  <li><code class="language-plaintext highlighter-rouge">Unsafe</code>’s memory access methods <a href="https://openjdk.org/jeps/498">are being removed</a> after having been replaced by the foreign memory API</li>
</ul>

<p>As proposed by <a href="https://openjdk.org/jeps/500">JEP 500</a> and starting with JDK 26, the same is true for reflective mutation of final fields.</p>

<h2 id="new-warnings-and-soon-errors">New Warnings and (Soon) Errors</h2>

<p>If no new command-line options are applied, mutating a final field through the reflection API <code class="language-plaintext highlighter-rouge">java.lang.reflect.Field::set</code> on JDK 26 leads to a warning like the following on the standard error stream:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>WARNING: Final field f in p.C has been [mutated/unreflected for mutation] by class com.foo.Bar.caller in module N (file:/path/to/foo.jar)
WARNING: Use --enable-final-field-mutation=N to avoid a warning
WARNING: Mutating final fields will be blocked in a future release unless final field mutation is enabled
</code></pre></div></div>

<p>This warning is emitted once per reflecting module.
Consequently, if the entire application resides on the class path only one such warning is printed.</p>

<p>In future Java releases, this warning will become an error, at which point command-line options are <em>required</em> to mutate final fields through reflection.</p>

<h2 id="adapting-to-immutable-final-fields">Adapting to Immutable Final Fields</h2>

<p>Two new command-line options are introduced that application maintainers can use to handle these warnings/errors:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">--enable-final-field-mutation</code> is a permanent option that allows specific modules to mutate final fields</li>
  <li><code class="language-plaintext highlighter-rouge">--illegal-final-field-mutation</code> is a temporary option with values <code class="language-plaintext highlighter-rouge">allow</code>, <code class="language-plaintext highlighter-rouge">warn</code> (default on JDK 26), <code class="language-plaintext highlighter-rouge">debug</code>, and <code class="language-plaintext highlighter-rouge">deny</code> (future default) that manages how code without specific permission that tries to mutate final fields will be handled</li>
</ul>

<p><a href="https://openjdk.org/jeps/500">JEP 500</a> as well as <a href="https://www.youtube.com/watch?v=bdHkbEIdBAs">Inside Java Newscast #101</a> discuss the use of these options as well as their interaction with strong encapsulation in detail, which is particularly important for application maintainers.</p>

<p>However, even given theses options, as Java moves towards a future where final fields are truly immutable by default, it is imperative for library and framework maintainers (and to a lesser degree, even application developers) to avoid mutating them through the reflection API.
The article <a href="https://inside.java/2026/04/27/avoiding-final-field-mutation/"><em>Avoiding Final Field Mutation</em></a> examines various scenarios in which final fields are commonly mutated via reflection and discusses alternative approaches for each.</p>

<center>~</center>]]></content><author><name>[&quot;NicolaiParlog&quot;]</name></author><category term="JDK 26" /><category term="Integrity by Default" /><summary type="html"><![CDATA[This Heads-Up is part of the regular communication sent to the projects involved; it covers the warnings that JDK 26 emits when final fields are mutated through reflection.]]></summary></entry><entry><title type="html">Java Gets Post-Quantum TLS - Inside Java Newscast #112</title><link href="https://inside.java/2026/05/14/newscast-112/" rel="alternate" type="text/html" title="Java Gets Post-Quantum TLS - Inside Java Newscast #112" /><published>2026-05-14T00:00:00+00:00</published><updated>2026-05-14T00:00:00+00:00</updated><id>https://inside.java/2026/05/14/Newscast-112</id><content type="html" xml:base="https://inside.java/2026/05/14/newscast-112/"><![CDATA[<p><br /></p>

<iframe title="Libsyn Player" style="border: none" src="//html5-player.libsyn.com/embed/episode/id/41330025/height/90/theme/custom/thumbnail/yes/direction/forward/render-playlist/no/custom-color/000000/" height="90" width="100%" scrolling="no"></iframe>

<div class="youtube-embed">
    <iframe src="https://www.youtube.com/embed/FCtD53xYyZ0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></iframe>
</div>

<p><em>With JDK 27 introducing hybrid key exchange schemes that combine ML-KEM with traditional ECDHE algorithms, Java applications can gain TLS-layer protection against the “harvest-now, decrypt-later” threat without rewriting business logic.</em></p>

<p><em>In this episode of the Inside Java Newscast, Ana explains post-quantum hybrid key exchange for TLS 1.3 and demonstrates how a Java application can take advantage of it.</em></p>

<p><em>Make sure to check the <a href="https://www.youtube.com/watch?v=FCtD53xYyZ0">show-notes</a>.</em></p>]]></content><author><name>[&quot;Ana-MariaMihalceanu&quot;]</name></author><category term="JDK 27" /><category term="Security" /><summary type="html"><![CDATA[With JDK 27 introducing hybrid key exchange schemes that combine ML-KEM with traditional ECDHE algorithms, Java applications can gain TLS-layer protection against the “harvest-now, decrypt-later” threat without rewriting business logic. In this episode of the Inside Java Newscast, Ana explains post-quantum hybrid key exchange for TLS 1.3 and demonstrates how a Java application can take advantage of it.]]></summary></entry><entry><title type="html">Quality Outreach Heads-up - JDK 27: Removal of Deprecated Java Launcher Options</title><link href="https://inside.java/2026/05/13/quality-heads-up/" rel="alternate" type="text/html" title="Quality Outreach Heads-up - JDK 27: Removal of Deprecated Java Launcher Options" /><published>2026-05-13T00:00:00+00:00</published><updated>2026-05-13T00:00:00+00:00</updated><id>https://inside.java/2026/05/13/Quality-Heads-Up</id><content type="html" xml:base="https://inside.java/2026/05/13/quality-heads-up/"><![CDATA[<p><img class="webfeedsFeaturedVisual" style="display: none;" src="/images/thumbnail/code.jpg" /></p>

<p><i>The <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">OpenJDK Quality Group</a> is promoting the testing of FOSS projects with OpenJDK builds as a way to improve the overall quality of the release. This heads-up is part of a <a href="https://mail.openjdk.org/archives/list/quality-discuss@openjdk.org/thread/REAJQSW4DJ6BZNEKLGU56HB2757I26HM/">Quality Outreach</a> update sent to the projects involved. To learn more about the program, and how-to join, please check <a href="https://wiki.openjdk.java.net/display/quality/Quality+Outreach">here</a>.</i></p>

<h2 id="deprecated-java-launcher-options">Deprecated Java Launcher Options</h2>

<p>In Java 13, through <a href="https://bugs.openjdk.org/browse/JDK-8214731">JDK-8214731</a>, the <code class="language-plaintext highlighter-rouge">-Xverify:none</code> and <code class="language-plaintext highlighter-rouge">-noverify</code> options were deprecated. Using either of those options currently results in bytecode verification being disabled and a warning being printed that these 2 options will be removed in the near future:</p>

<blockquote>
  <p>OpenJDK 64-Bit Server VM warning: Options <code class="language-plaintext highlighter-rouge">-Xverify:none</code> and <code class="language-plaintext highlighter-rouge">-noverify</code> were deprecated in JDK 13 and will likely be removed in a future release.</p>
</blockquote>

<p>Disabling bytecode verification (which is what these 2 options do) is not recommended and the deprecation warning has been in place for several releases now, which will have given enough time for applications to stop using them.</p>

<p>Similarly, in Java 24, through <a href="https://bugs.openjdk.org/browse/JDK-8340244">JDK-8340244</a>, several other <code class="language-plaintext highlighter-rouge">java</code> launcher options were deprecated for removal. Out of those deprecated, the following 2 are less commonly used:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">-noclassgc</code></li>
  <li><code class="language-plaintext highlighter-rouge">-verifyremote</code></li>
</ul>

<p>Currently, when <code class="language-plaintext highlighter-rouge">java</code> is launched with <code class="language-plaintext highlighter-rouge">-noclassgc</code>, the launcher replaces its usage with <code class="language-plaintext highlighter-rouge">-Xnoclassgc</code> when launching the VM. A deprecation warning is also printed for this option:</p>

<blockquote>
  <p>Warning: <code class="language-plaintext highlighter-rouge">-noclassgc</code> option is deprecated and may be removed in a future release.</p>
</blockquote>

<p>Similarly, when <code class="language-plaintext highlighter-rouge">-verifyremote</code> is used, the launcher replaces its usage with <code class="language-plaintext highlighter-rouge">-Xverify:remote</code> VM option and prints a deprecation warning:</p>

<blockquote>
  <p>Warning: <code class="language-plaintext highlighter-rouge">-verifyremote</code> option is deprecated and may be removed in a future release.</p>
</blockquote>

<p>The deprecation warnings have been in place for some releases now and it’s time to remove support for <code class="language-plaintext highlighter-rouge">-noclassgc</code>, <code class="language-plaintext highlighter-rouge">-verifyremote</code>, <code class="language-plaintext highlighter-rouge">-noverify</code>, and <code class="language-plaintext highlighter-rouge">-Xverify:none</code> altogether.</p>

<h2 id="removal-in-jdk-27">Removal in JDK 27</h2>

<p>Support for the options <code class="language-plaintext highlighter-rouge">-noclassgc</code>, <code class="language-plaintext highlighter-rouge">-verifyremote</code>, and <code class="language-plaintext highlighter-rouge">-noverify</code> will be removed from the <code class="language-plaintext highlighter-rouge">java</code> launcher. Support for <code class="language-plaintext highlighter-rouge">-Xverify:none</code> will be removed from the HotSpot VM. Using any of these options will now result in them being considered as unrecognized options and the <code class="language-plaintext highlighter-rouge">java</code> launcher (and the HotSpot VM) will fail with an error.</p>

<p>For example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java -verifyremote -version
Unrecognized option: -verifyremote
...
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">-Xverify:remote</code> and <code class="language-plaintext highlighter-rouge">-Xnoclassgc</code> HotSpot VM options are untouched in this change and will continue to function normally.</p>

<p>For more information, please check <a href="https://bugs.openjdk.org/browse/JDK-8382727">JDK-8382727</a>.</p>

<center>~</center>]]></content><author><name>[&quot;BillyKorando&quot;]</name></author><category term="JDK 27" /><category term="Serviceability" /><summary type="html"><![CDATA[This Heads-Up is part of the regular communication sent to the projects involved; it covers the removal of deprecated Java launcher options.]]></summary></entry></feed>