<?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 foojay.io - Friends Of OpenJDK</title><link>https://foojay.io/today/category/java/</link><description>Recent content in Java on foojay.io - Friends Of OpenJDK</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 07 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://foojay.io/today/category/java/index.xml" rel="self" type="application/rss+xml"/><item><title>Adding RAG to a Jakarta EE 11 App With Only the JDK and Jakarta Specs</title><link>https://foojay.io/today/adding-rag-to-jakarta-ee-11-app/</link><pubDate>Wed, 07 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/adding-rag-to-jakarta-ee-11-app/</guid><description>&lt;p&gt;The standard story about AI in the enterprise goes something like this. Your app needs AI, so you spin up a Python service. You add a vector database like Pinecone or Weaviate. You pick an orchestration framework. You now have two deployment pipelines, two languages, and two teams. The original Java monolith that handled your business logic just fine becomes one half of a distributed system that exists mostly to connect to the other half.&lt;/p&gt;</description></item><item><title>Green Build, Wrong Task: A Working Agreement for Java Teams Using AI Coding Agents</title><link>https://foojay.io/today/green-build-wrong-task-a-working-agreement-for-java-teams-using-ai-coding-agents/</link><pubDate>Wed, 07 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/green-build-wrong-task-a-working-agreement-for-java-teams-using-ai-coding-agents/</guid><description>&lt;p&gt;You open a pull request. &lt;code&gt;./gradlew check&lt;/code&gt; is green, the diff is 400 lines, the description says &amp;ldquo;added tests as requested&amp;rdquo;. You scroll and see a dozen unit tests for one service class. What you asked for, in a two-line Jira comment, was end-to-end coverage of the checkout flow.&lt;/p&gt;&#10;&lt;p&gt;Nobody lied. The agent filled a gap in the request with the most likely reading and got to work. This is the first of three failure modes our team went through in a webinar on September 28. I am writing it up because the fixes turned out to be boring and mechanical, and they work with whatever agent your team has already installed.&lt;/p&gt;</description></item><item><title>Real-Time Fraud Detection in Java with Kafka Streams and Vector Similarity</title><link>https://foojay.io/today/real-time-fraud-detection-kafka-vector-similarity/</link><pubDate>Wed, 07 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/real-time-fraud-detection-kafka-vector-similarity/</guid><description>&lt;p&gt;&lt;em&gt;This content is based on a talk that my colleague Tim Kelly and I presented at &lt;a href="https://devnexus.com/events/real-time-fraud-detection-in-java-with-kafka-streams-vector-similarity" target="_blank" rel="noopener noreferrer"&gt;DevNexus 2026&lt;/a&gt; in Atlanta, one of the largest Java conferences in the world.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;Imagine you&amp;rsquo;re at a supermarket or shopping online. You tap your card or click &amp;ldquo;Buy Now&amp;rdquo;. In that exact moment, your bank has to make a decision: is this transaction legitimate, or is it fraud? And it has to do that in milliseconds, and get it right. If it blocks a real transaction, it frustrates the customer. If it approves a fraudulent one, it leads to financial loss. So the question is: how do banks actually do this? What&amp;rsquo;s happening behind the scenes? In this article, we&amp;rsquo;ll explore a real-world approach to solving this problem using Java, Apache Kafka, Kafka Streams, and vector similarity with MongoDB.&lt;/p&gt;</description></item><item><title>Building a Code Editor Control in JavaFX</title><link>https://foojay.io/today/building-a-javafx-code-editor-control/</link><pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/building-a-javafx-code-editor-control/</guid><description>&lt;p&gt;JavaFX doesn&amp;rsquo;t ship with a code-editor control, and &lt;code&gt;TextArea&lt;/code&gt; isn&amp;rsquo;t built to grow into one — no per-character styling, no gutter, no virtualization tuned for thousands of lines. Building a real one means going back to &lt;code&gt;Control&lt;/code&gt; + &lt;code&gt;Skin&lt;/code&gt; and constructing the editor surface yourself. This post walks through several pieces of a custom editor control.&lt;/p&gt;&#10;&lt;h2 id="the-core-idea-two-virtualized-lists-not-one"&gt;The core idea: two virtualized lists, not one&lt;/h2&gt;&#10;&lt;p&gt;The instinctive design is a single &lt;code&gt;ListView&amp;lt;String&amp;gt;&lt;/code&gt;, one row per line, with each row containing both the line number and the code. This approach has a drawback: when the user scrolls horizontally, the line numbers disappear.&lt;/p&gt;</description></item><item><title>Run Java in the Browser with TeaVM</title><link>https://foojay.io/today/java-in-the-browser-with-teavm/</link><pubDate>Tue, 06 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/java-in-the-browser-with-teavm/</guid><description>&lt;p&gt;There’s something satisfying about editing a line of Java on a web page, clicking &lt;strong&gt;Run&lt;/strong&gt;, and seeing the result appear right there in the browser. I use this approach for the live Java snippets at &lt;a href="https://nablatensor.com/learn" target="_blank" rel="noopener noreferrer"&gt;nablatensor.com/learn&lt;/a&gt; and for source code used to bootstrap &lt;a href="https://nablatensor.com/quantlab" target="_blank" rel="noopener noreferrer"&gt;nablatensor.com/quantlab&lt;/a&gt;. In this article, I’ll explain how the pieces fit together and walk you through a React app you can run yourself.&lt;/p&gt;&#10;&lt;h2 id="from-java-source-to-a-result"&gt;From Java source to a result&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://teavm.org/docs/intro/overview.html" target="_blank" rel="noopener noreferrer"&gt;TeaVM&lt;/a&gt; compiles Java bytecode into JavaScript or WebAssembly for the browser. To let readers edit and compile the examples, I use &lt;a href="https://github.com/Vsprocessing/teavm-javac" target="_blank" rel="noopener noreferrer"&gt;teavm-javac&lt;/a&gt;, which brings a Java compiler into the browser as well. &lt;strong&gt;Compilation happens directly in the reader&amp;rsquo;s browser:&lt;/strong&gt; the edited source is sent to a Web Worker in the same tab, without sending a compilation request to a server.&lt;/p&gt;</description></item><item><title>Foojay Podcast #102: Why Foojay Walked Away From WordPress for Static Sites</title><link>https://foojay.io/today/foojay-podcast-102/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/foojay-podcast-102/</guid><description>&lt;p&gt;Foojay.io quietly moved off WordPress and onto Hugo, a static site generator. No more CMS login, no database, no admin panel — just Markdown and AsciiDoc files, built and deployed straight from GitHub. In this episode we dig into why that move happened, and into the bigger question behind it: is a traditional CMS still the right way to run a content site in 2026, or has static tooling caught up? Along the way we go through the real security numbers behind WordPress&amp;rsquo;s plugin ecosystem — more than 10,000 vulnerabilities found in WordPress plugins since 2025 alone — and put very different static site generators head to head: Hugo and Jekyll, the veterans, versus Roq, the Java-and-Quarkus-based newcomer.&lt;/p&gt;</description></item><item><title>Changes Included in Release 26.08 of Azul Zing Builds of OpenJDK</title><link>https://foojay.io/today/changes-included-in-release-26-08-of-azul-zing-builds-of-openjdk/</link><pubDate>Fri, 02 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/changes-included-in-release-26-08-of-azul-zing-builds-of-openjdk/</guid><description>&lt;p&gt;Azul Zing Builds of OpenJDK, the optimized Java runtime within &lt;a href="https://www.azul.com/products/prime" target="_blank" rel="noopener noreferrer"&gt;Azul Platform Prime&lt;/a&gt;, has reached the release of the 26.08 Stable Release line. This Stable Build represents an August 2026 promotion from Stream to Stable status, consolidating six months of Stream Build work into a single, supported release line. The headline addition is &lt;strong&gt;Compilation Streaming&lt;/strong&gt;, which lets a JVM download pre-compiled code from Azul Optimizer Hub at startup instead of waiting on its own JIT compilation queue.&lt;/p&gt;</description></item><item><title>Announcing 'Skinning JavaFX Applications'</title><link>https://foojay.io/today/announcing-skinning-javafx-applications/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/announcing-skinning-javafx-applications/</guid><description>&lt;p&gt;If you&amp;rsquo;ve ever tried to make a JavaFX application look like Microsoft or JetBrains, you know that CSS is not enough. &lt;em&gt;Skinning JavaFX Applications&lt;/em&gt; is my attempt to close that gap — a practical, code-first book built from years of shipping real desktop business applications.&lt;/p&gt;&#10;&lt;p&gt;The main purpose of this book is to cover the Control-Skin architecture, so you can create your own custom controls and skins. We&amp;rsquo;ll cover how to implement custom window chrome, runtime theme switching, Fluent Design materials like Mica and Acrylic, and a full set of micro-interactions.&lt;/p&gt;</description></item><item><title>Lathe: A Java Language Server That Works Straight From Your Maven Build</title><link>https://foojay.io/today/lathe-a-java-language-server-from-your-maven-build/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/lathe-a-java-language-server-from-your-maven-build/</guid><description>&lt;p&gt;I have written Java in many editors and IDEs over the years, and they all seem to struggle with the same&#10;thing.&lt;/p&gt;&#10;&lt;p&gt;For me, the hard part of a Java IDE or language server was never the code intelligence. It was getting&#10;the project structure right. The IDE reads your build files and then tries to guess the module&#10;structure from them. And over time, Java&amp;rsquo;s compiler and runtime configuration has become more and more&#10;complex: annotation processors, the module system, and more. So you often end up in a familiar place:&#10;the code compiles and runs in the build, but not in the IDE. Even the best ones tend to break the&#10;project setup after an upgrade.&lt;/p&gt;</description></item><item><title>Durable Execution Is a Property, Not a Product</title><link>https://foojay.io/today/durable-execution-is-a-property-not-a-product/</link><pubDate>Wed, 30 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/durable-execution-is-a-property-not-a-product/</guid><description>&lt;p&gt;Three method calls. That is my entire workflow: charge a payment, reserve inventory, send a confirmation email.&lt;/p&gt;&#10;&lt;p&gt;Run those three calls on a dedicated workflow engine and here is what happens before your business logic is done: 23 history events are appended, 15 durable state transitions are committed to a database, and 15 gRPC round trips travel between your worker and the orchestration cluster.&lt;/p&gt;&#10;&lt;p&gt;That, in one paragraph, is why I want to talk about durable execution. Not because the engines are bad. They are impressive systems built by serious engineers. I want to talk about it because the Java community is being sold a property as if it were a product, and I think most of us already own the property.&lt;/p&gt;</description></item><item><title>Lies, Damn Lies and Benchmarks</title><link>https://foojay.io/today/performance-work-between-benchmarks/</link><pubDate>Wed, 30 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/performance-work-between-benchmarks/</guid><description>&lt;p&gt;&lt;img src="https://foojay.io/today/performance-work-between-benchmarks/performance-work-between-benchmarks-add0d8fe44.jpg" alt="Lies, Damn Lies And Benchmarks" width="1024" height="512" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;There&amp;rsquo;s an old joke about three kinds of lies: &lt;a href="https://www.spec.org/osg/news/articles/news9412/lies.html" target="_blank" rel="noopener noreferrer"&gt;lies, damn lies, and benchmarks&lt;/a&gt;. Codename One did very well in our benchmarks. But were they accurate? Were they representative?&lt;/p&gt;&#10;&lt;aside style="border-left: 4px solid #007aff; padding: 14px 18px; margin: 24px 0; border-radius: 4px; font-size: 0.95em;"&gt;&lt;strong&gt;What is Codename One?&lt;/strong&gt; Codename One is an open-source framework for building native iOS, Android, desktop, and web apps from a single Java or Kotlin codebase. Learn more at &lt;a href="https://www.codenameone.com/"&gt;codenameone.com&lt;/a&gt;.&lt;/aside&gt;&#10;&lt;p&gt;Performance is the fitted sheet of programming. Just when you get the damn corner into place, the rest of the bed is a complete mess.&lt;/p&gt;</description></item><item><title>My love-hate relationship with Java formatters</title><link>https://foojay.io/today/my-love-hate-relationship-with-java-formatters/</link><pubDate>Wed, 30 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/my-love-hate-relationship-with-java-formatters/</guid><description>&lt;p&gt;Disclaimer: I don&amp;rsquo;t want to turn this into &amp;ldquo;Java formatters week&amp;rdquo;, but I started my own project a while ago, and I think it&amp;rsquo;s time for it to come out of stealth mode.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;ve been writing Java for many, many years, and the Sun Code Conventions were my favorite bedside reading. I&amp;rsquo;ve seen plenty of variations over the years, and even after they became the Oracle Code Conventions, they were still the same few-page guide on how to write a hello-world app with the standard class library. For some reason I never took to the Google conventions: too C-flavored, with tiny indents, too few columns on the screen, and so on.&lt;/p&gt;</description></item><item><title>The Java 21 Doomsday Clock Countdown</title><link>https://foojay.io/today/the-java-21-doomsday-clock-countdown/</link><pubDate>Tue, 29 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/the-java-21-doomsday-clock-countdown/</guid><description>&lt;h2 id="the-java-21-countdown-is-pressing"&gt;The Java 21 Countdown Is Pressing&lt;/h2&gt;&#10;&lt;p&gt;Oracle JDK 21 was free to use in production under Oracle&amp;rsquo;s No-Fee Terms and Conditions (NFTC) license. That free ride is over. Oracle&amp;rsquo;s licensing rule ties free NFTC use to one year after the next Long Term Support (LTS) release ships, and since Java 25 became generally available on September 16, 2025, the license window closed on September 16, 2026.&lt;/p&gt;&#10;&lt;p&gt;The date that matters now is &lt;strong&gt;October 20, 2026&lt;/strong&gt;. That is Oracle&amp;rsquo;s next quarterly update — the first batch of Java 21 patches, including Critical Security Patch Updates (CSPUs), that no longer reaches you under the free license. Every Java 21 fix from that day forward requires a paid Oracle subscription. This is not a one-time event: the same mechanism already retired free updates for Java 17, and it will retire Java 25&amp;rsquo;s free updates in turn once Java 29 ships. It&amp;rsquo;s a recurring toll booth built into Oracle&amp;rsquo;s licensing terms.&lt;/p&gt;</description></item><item><title>How much will post-quantum migration cost your Java codebase?</title><link>https://foojay.io/today/how-much-will-post-quantum-migration-cost-your-java-codebase/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/how-much-will-post-quantum-migration-cost-your-java-codebase/</guid><description>&lt;p&gt;The post-quantum transition has stopped being a research topic and become a set of dates. NIST finalized ML-KEM (FIPS 203), ML-DSA (FIPS 204) and SLH-DSA (FIPS 205) in August 2024. NIST IR 8547 deprecates RSA, ECDSA, (EC)DH and the rest after 2030 and disallows them after 2035, and similar timelines are turning up in government guidance elsewhere.&lt;/p&gt;&#10;&lt;p&gt;So the destination is settled. For most Java teams the hard question is not &lt;em&gt;what&lt;/em&gt; to migrate to. It is &lt;em&gt;how much&lt;/em&gt; the migration will cost for their specific codebase, and where the expensive parts are hiding. That question has been oddly hard to answer, and most of the post-quantum migration tooling I could find targets C, C++ and Rust, even though a great deal of enterprise cryptography runs on the JVM.&lt;/p&gt;</description></item><item><title>Testing Kafka Consumer Recovery Contracts With Testcontainers and JUnit</title><link>https://foojay.io/today/testing-kafka-consumer-recovery-contracts-with-testcontainers-and-junit/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/testing-kafka-consumer-recovery-contracts-with-testcontainers-and-junit/</guid><description>&lt;p&gt;A Kafka consumer can pass a unit test and still fail when production redelivers a&#10;record.&lt;/p&gt;&#10;&lt;p&gt;That happens because the unit test usually checks the handler, not the recovery&#10;contract. It verifies that one message produces one expected side effect. It&#10;rarely verifies what happens when the same event arrives twice, when a malformed&#10;record reaches the topic, or when the consumer applies a side effect and then&#10;crashes before committing the offset.&lt;/p&gt;</description></item><item><title>One Database, Two Models: Building AI-Friendly Java Applications with MySQL JSON Duality Views</title><link>https://foojay.io/today/one-database-two-models-mysql-json-duality-views-java/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/one-database-two-models-mysql-json-duality-views-java/</guid><description>&lt;p&gt;MySQL can now hand your application a complete JSON document, such as an order with its customer and line items, while the data stays in normal relational tables. You can even send the document back and MySQL updates the right rows. I built a small Java app to see how far that goes. Reading got much simpler. Writing works too, but it comes with a few sharp edges you should know about before you use it.&lt;/p&gt;</description></item><item><title>VoIP, VPN, and the Build System Behind Them</title><link>https://foojay.io/today/voip-vpn-builders/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://foojay.io/today/voip-vpn-builders/</guid><description>&lt;p&gt;In 2019, a reader asked whether our WhatsApp clone included VoIP. &lt;a href="https://www.codenameone.com/blog/whatsapp-clone-ga/#comment-24081" target="_blank" rel="noopener noreferrer"&gt;I said no&lt;/a&gt;. It would require native integration, and the setup was too much for that project. For years, that was the line.&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://foojay.io/today/voip-vpn-builders/voip-vpn-builders-bdff9b8012.jpg" alt="A phone, secure tunnel, and native build pipeline" width="1024" height="512" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;aside style="border-left: 4px solid #007aff; padding: 14px 18px; margin: 24px 0; border-radius: 4px; font-size: 0.95em;"&gt;&lt;strong&gt;What is Codename One?&lt;/strong&gt; Codename One is an open-source framework for building native iOS, Android, desktop, and web apps from a single Java or Kotlin codebase. Learn more at &lt;a href="https://www.codenameone.com/"&gt;codenameone.com&lt;/a&gt;.&lt;/aside&gt;&#10;&lt;p&gt;VPN sat behind the same line. These features do not live neatly inside the application process. On iOS, a VoIP push can arrive before the application installs a Java listener, yet CallKit expects the incoming call to reach the lock screen on its deadline. A Call Directory integration is a separate extension executable with its own lifecycle and signing identity. Managed VPN adds Network Extension entitlements and profile rules. Android solves the same jobs through &lt;code&gt;ConnectionService&lt;/code&gt;, &lt;code&gt;VpnManager&lt;/code&gt;, &lt;code&gt;VpnService&lt;/code&gt;, manifest declarations, and foreground-service rules.&lt;/p&gt;</description></item><item><title>BoxLang 1.17.0 Released: Module Inception, CLI Checker, Jar Loading and much more!</title><link>https://foojay.io/today/boxlang-1-17-0-released-module-inception-cli-checker-jar-loading-and-much-more/</link><pubDate>Thu, 17 Sep 2026 20:20:32 +0000</pubDate><guid>https://foojay.io/today/boxlang-1-17-0-released-module-inception-cli-checker-jar-loading-and-much-more/</guid><description>&lt;p&gt;&lt;strong&gt;BoxLang has always been an extensible language. As of 1.17.0, it is a hierarchically extensible one.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="https://foojay.io/today/boxlang-1-17-0-released-module-inception-cli-checker-jar-loading-and-much-more/boxlang-v1.17.0-700x467.jpg" alt="" width="700" height="467" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;Modules can now contain other modules; &lt;strong&gt;aka Module Inception&lt;/strong&gt; . Recursively. To any depth. Each nested module gets its own class loader, chained to its parent&amp;rsquo;s, and BoxLang&amp;rsquo;s own &lt;code&gt;ModuleService&lt;/code&gt; discovers, registers, activates, and unloads that entire tree itself. No package manager. No build tool. No install ordering. Drop in one artifact and everything it depends on comes with it, already wired up and already isolated. &lt;strong&gt;Not only that, you can now package modules into a single jar.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Can You Explain the Diff Your AI Agent Just Wrote?</title><link>https://foojay.io/today/can-you-explain-the-diff-your-ai-agent-just-wrote/</link><pubDate>Tue, 15 Sep 2026 14:12:01 +0000</pubDate><guid>https://foojay.io/today/can-you-explain-the-diff-your-ai-agent-just-wrote/</guid><description>&lt;p&gt;Every Java developer has been in a code review where the question is simple: &amp;ldquo;What does this method do?&amp;rdquo;&lt;/p&gt;&#10;&lt;p&gt;The answer used to tell you something. The developer who wrote it would describe the intent, the edge cases, the trade-off they considered and rejected. The code review was a conversation about the invariant the code protects.&lt;/p&gt;&#10;&lt;p&gt;Now the answer is sometimes: &amp;ldquo;The agent wrote it.&amp;rdquo;&lt;/p&gt;&#10;&lt;p&gt;The code compiles. The tests pass. The linter is clean. Nobody in the review can explain the architecture of the PR, including the person who submitted it.&lt;/p&gt;</description></item><item><title>How I Built an AI Assistant for My Career with Java, Spring AI, and MongoDB</title><link>https://foojay.io/today/how-i-built-an-ai-assistant-for-my-career-with-java-spring-ai-and-mongodb/</link><pubDate>Tue, 15 Sep 2026 11:51:17 +0000</pubDate><guid>https://foojay.io/today/how-i-built-an-ai-assistant-for-my-career-with-java-spring-ai-and-mongodb/</guid><description>&lt;p&gt;The best way to learn a technology is by putting it into practice in a real system.&lt;/p&gt;&#10;&lt;p&gt;A few months ago, I decided to build a virtual assistant that could answer questions about my career, help people learn more about my articles, videos, talks, and projects, and even schedule a call on my calendar.&#10;&lt;img src="https://foojay.io/today/how-i-built-an-ai-assistant-for-my-career-with-java-spring-ai-and-mongodb/unnamed-16-1024x937.png" alt="" width="1024" height="937" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;At first, the idea was simple: give the assistant access to my content and let people ask questions about it. But as the project evolved, I realized that not every question should be handled in the same way. Some questions can be answered with a direct query to the database, while others benefit from semantic search. In other cases, the assistant may need to use a tool or execute multiple steps before reaching an answer.&lt;/p&gt;</description></item><item><title>Hello Java 27! Have You Been Working Out?</title><link>https://foojay.io/today/hello-java-27-have-you-been-working-out/</link><pubDate>Tue, 15 Sep 2026 08:00:00 +0000</pubDate><guid>https://foojay.io/today/hello-java-27-have-you-been-working-out/</guid><description>&lt;p&gt;It&amp;rsquo;s been six months since we saw a new Java release, and this new edition seems to be ready to flex its muscles. With numerous improvements to performance and security, Java 27 is like that friend that you haven&amp;rsquo;t seen all summer, and when you finally see them again it&amp;rsquo;s clear that they spent a lot of time in the gym!&lt;/p&gt;&#10;&lt;p&gt;This post focuses on everything that has been added in this release, giving you a brief introduction to each of the features. Where applicable the differences with Java 26 are highlighted and a few typical use cases are provided, so that you&amp;rsquo;ll be more than ready to start using these features after reading this.&lt;/p&gt;</description></item><item><title>Foojay Podcast #101: Java 27 in Practice: Smaller Heaps, Smarter Defaults, and Valhalla on the Horizon</title><link>https://foojay.io/today/foojay-podcast-101/</link><pubDate>Mon, 14 Sep 2026 06:11:42 +0000</pubDate><guid>https://foojay.io/today/foojay-podcast-101/</guid><description>&lt;p&gt;JDK 27 arrives on 15 September 2026, and it is a feature release rather than a Long-Term Support one. That distinction matters less than it sounds: as Simon Ritter points out, all OpenJDK releases are delivered the same way, and &amp;ldquo;long-term support&amp;rdquo; is a property of the binary distributions you install, not of the platform itself. What JDK 27 does have is two changes that switch on by default and cost you nothing but the upgrade. Compact object headers shrink the per-object header from 64 bits to 32, which the JEP measures at a 22% reduction in heap and 8% in CPU on SPECjbb2015 — and because it is internal to the JVM, a JAR you built years ago benefits without a single line changing. Alongside it, G1 becomes the default garbage collector everywhere, including the small, single-core machines that used to fall back to the serial collector.&lt;/p&gt;</description></item><item><title>Come for Java. Get a Whole Lot More.</title><link>https://foojay.io/today/come-for-java-get-a-whole-lot-more/</link><pubDate>Fri, 11 Sep 2026 09:33:46 +0000</pubDate><guid>https://foojay.io/today/come-for-java-get-a-whole-lot-more/</guid><description>&lt;p&gt;JCON USA returns inside IBM TechXchange 2026 with two rooms of deep Java content, a dedicated community home, and direct access to one of the years biggest technical conferences.&lt;/p&gt;&#10;&lt;h2 id="from-orlando-to-atlanta"&gt;From Orlando to Atlanta&lt;/h2&gt;&#10;&lt;p&gt;Last year, we tried something new. We brought JCON USA into IBM TechXchange and created a Java community conference inside a much larger technology event. The result showed us that these two worlds fit together remarkably well. JCON brought the independent, developer-to-developer spirit of the Java community. TechXchange provided the scale, infrastructure, learning opportunities, and access to experts that only a major international conference can offer.&lt;/p&gt;</description></item><item><title>Reflection-Free Serialization on the JVM: Four Formats In, Avro Out</title><link>https://foojay.io/today/reflection-free-serialization-on-the-jvm-four-formats-in-avro-out/</link><pubDate>Thu, 10 Sep 2026 06:56:00 +0000</pubDate><guid>https://foojay.io/today/reflection-free-serialization-on-the-jvm-four-formats-in-avro-out/</guid><description>&lt;p&gt;I run a model layer that accepts the same business data in JSON, XML, YAML, and TOML and converts it all to Avro. The project was greenfield, so the question was never what to migrate away from. It was a question of which serialization library the layer would be built with: Jackson or kotlinx.serialization. Jackson was the safe answer, with a module for every format we needed and years of production behind it. What pulled me the other way was the assumption that runtime reflection costs real CPU under load. That turned out to be true of one Jackson path and not the other, which I will get to. The reasons the choice held up were not the reasons I made it.&lt;/p&gt;</description></item><item><title>One Base URL, Many Coding Agents: What an OpenAI-Compatible Gateway Looks Like From java.net.http</title><link>https://foojay.io/today/one-base-url-many-coding-agents-what-an-openai-compatible-gateway-looks-like-from-java-net-http/</link><pubDate>Wed, 09 Sep 2026 16:09:53 +0000</pubDate><guid>https://foojay.io/today/one-base-url-many-coding-agents-what-an-openai-compatible-gateway-looks-like-from-java-net-http/</guid><description>&lt;p&gt;Somewhere in every coding agent there is an HTTP client. Claude Code, Codex, Cursor, Cline, OpenCode: strip away the terminal UI or the editor pane and each of them serializes a conversation into JSON, POSTs it to a base URL with an API key in a header, and streams the answer back. The client owns the prompt assembly, the tool loop and the rendering; the model sits on the far side of that socket.&lt;/p&gt;</description></item><item><title>Masking a JVM thread dump without breaking the analysis</title><link>https://foojay.io/today/masking-a-jvm-thread-dump-without-breaking-the-analysis/</link><pubDate>Wed, 09 Sep 2026 07:32:00 +0000</pubDate><guid>https://foojay.io/today/masking-a-jvm-thread-dump-without-breaking-the-analysis/</guid><description>&lt;p&gt;A few weeks ago I posted on r/java about detecting virtual thread pinning from a plain thread dump. The technical discussion was fine. The comment that stuck with me had nothing to do with pinning: &amp;ldquo;the problem isn&amp;rsquo;t taking the dump, it&amp;rsquo;s that uploading a production dump to a third-party site is against policy&amp;rdquo;. Not a preference. Policy. And the person saying it was right.&lt;/p&gt;&#10;&lt;p&gt;I run ThreadMine, a hosted thread dump analyzer, so that comment describes my own product. This article is about what I built in response: a small open-source CLI that rewrites the dump on your machine before it goes anywhere, in a way that keeps the analysis working. It&amp;rsquo;s called &lt;code&gt;tm-anon&lt;/code&gt;, it&amp;rsquo;s MIT, and it works with any analyzer, mine included. The interesting part isn&amp;rsquo;t the tool, it&amp;rsquo;s the constraint: you can&amp;rsquo;t just strip everything, because the analyzer needs most of what&amp;rsquo;s in there.&lt;/p&gt;</description></item><item><title>Debugging Is Invariant Discovery: What One Kafka Session Taught Us About AI Agents</title><link>https://foojay.io/today/debugging-is-invariant-discovery-what-one-kafka-session-taught-us-about-ai-agents/</link><pubDate>Tue, 08 Sep 2026 14:14:36 +0000</pubDate><guid>https://foojay.io/today/debugging-is-invariant-discovery-what-one-kafka-session-taught-us-about-ai-agents/</guid><description>&lt;p&gt;Every Java team has a sentence like this one somewhere:&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Any operation on a TID must go through the single asynchronous path and must not let TMS and EMV drift apart.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;It is the kind of rule that is obvious once said and invisible until then. A terminal ID (TID) in a payments system, an asynchronous pipeline that updates two downstream systems, and the requirement that the two never disagree. Nothing in the type system enforces a rule like that, and no single class owns it. Rules of this kind live between consumers, services and stores.&lt;/p&gt;</description></item><item><title>Community Spotlight: BoxLang Express Brings Node-Style HTTP to the JVM</title><link>https://foojay.io/today/community-spotlight-boxlang-express-brings-node-style-http-to-the-jvm/</link><pubDate>Tue, 08 Sep 2026 11:25:18 +0000</pubDate><guid>https://foojay.io/today/community-spotlight-boxlang-express-brings-node-style-http-to-the-jvm/</guid><description>&lt;p&gt;&lt;img src="https://foojay.io/today/community-spotlight-boxlang-express-brings-node-style-http-to-the-jvm/boxlang-express-700x373.jpg" alt="" width="700" height="373" loading="lazy" decoding="async"&gt;&lt;/p&gt;&#10;&lt;p&gt;If you&amp;rsquo;ve spent years in Spring Boot, Micronaut, or Jakarta EE, &amp;ldquo;web framework&amp;rdquo; usually means a servlet container, an embedded Tomcat or Netty, a build step, and a fat jar before anything answers a request. What if you could skip all of that and still be on the JVM?&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;BoxLang Express&lt;/strong&gt; , a new community module built entirely by developer &lt;a href="https://kisdigital.com/posts/2026/08/introducing-boxexpress--express-js-ergonomics-for-boxlang" title="Robert Zehnder of KISDigital" target="_blank" rel="noopener noreferrer"&gt;Robert Zehnder of KISDigital&lt;/a&gt;, does exactly that. It&amp;rsquo;s built directly on &lt;code&gt;com.sun.net.httpserver.HttpServer&lt;/code&gt;, a class that&amp;rsquo;s been sitting in the JDK since Java 6, so there&amp;rsquo;s no embedded server to configure and nothing extra on the classpath for the HTTP layer itself. &lt;code&gt;boxlang server.bxs&lt;/code&gt; is the whole deployment story.&lt;/p&gt;</description></item><item><title>“Commit created” — but it isn’t: why the agent’s word needs external verification, and what the mistake costs</title><link>https://foojay.io/today/commit-created-no-no-no-what-the-the-agents-word-needs-external-verification-what-the-mistake-costs/</link><pubDate>Tue, 08 Sep 2026 08:54:03 +0000</pubDate><guid>https://foojay.io/today/commit-created-no-no-no-what-the-the-agents-word-needs-external-verification-what-the-mistake-costs/</guid><description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;A detailed report reads like proof. The agent lists the files it touched, names the branch, quotes a commit hash, adds a test count and closes with &amp;ldquo;done&amp;rdquo;. The work has a shape. The shape looks right. You have six more tickets.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;The report is model output. The commit, if it exists, lives in .git. The file, if it exists, lives on disk. The build result lives in a process exit code and a run log. The chat window is none of those places, and it can only vouch for itself.&lt;/p&gt;</description></item><item><title>From Spec-Driven Development to Living Specifications in Java Projects</title><link>https://foojay.io/today/from-spec-driven-development-to-living-specifications-in-java-projects/</link><pubDate>Fri, 04 Sep 2026 05:51:45 +0000</pubDate><guid>https://foojay.io/today/from-spec-driven-development-to-living-specifications-in-java-projects/</guid><description>&lt;h2 id="from-spec-driven-development-to-living-specifications-in-java-projects"&gt;From Spec-Driven Development to Living Specifications in Java Projects&lt;/h2&gt;&#10;&lt;p&gt;Coding agents have changed the speed at which we can produce software. But producing code faster does not automatically mean producing better software.&lt;/p&gt;&#10;&lt;p&gt;As I started using agents more frequently in real-world software development, one question became increasingly important: &lt;strong&gt;how do we give an agent enough freedom to be useful without losing engineering intent?&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Trying to control every line of code generated by an agent removes much of the value it can provide. At that point, it might simply be faster to write the code ourselves.&lt;/p&gt;</description></item></channel></rss>