<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">

    <channel>
        <title>Quarkus</title>
        <link>https://quarkus.io</link>
        <description>Quarkus: Supersonic Subatomic Java</description>
        <lastBuildDate>Thu, 14 May 2026 09:54:53 +0000</lastBuildDate>
        
        
        <item>
            <title>Introducing Quarkus Agent MCP: teaching AI agents to speak Quarkus</title>
            <link>
                https://quarkus.io/blog/introducing-agent-mcp/
            </link>
            <description>
                &lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;AI coding agents like Claude Code, GitHub Copilot, Cursor, Windsurf, and JetBrains AI are already capable of generating code, fixing bugs, and refactoring entire modules.
But they become much more effective when they have context about the framework you are using: that Quarkus dev mode hot-reloads on the next request rather than on file save, that Panache entities need &lt;code&gt;@Transactional&lt;/code&gt; for writes, that REST clients should be injected via CDI rather than instantiated manually.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus-agent-mcp&quot;&gt;Quarkus Agent MCP&lt;/a&gt; gives agents exactly that context.
It is a standalone &lt;a href=&quot;https://modelcontextprotocol.io&quot;&gt;MCP (Model Context Protocol)&lt;/a&gt; server that lets any compatible AI agent create, manage, and work effectively with Quarkus applications by providing Quarkus-specific tools, documentation, and extension-level coding patterns.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-is-mcp&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-is-mcp&quot;&gt;&lt;/a&gt;What is MCP?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://modelcontextprotocol.io&quot;&gt;Model Context Protocol&lt;/a&gt; is an open standard that lets AI agents discover and use tools exposed by external servers.
Instead of hard-coding integrations for every framework, an agent connects to MCP servers that provide domain-specific capabilities.
The agent discovers available tools at runtime and calls them as needed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s a plugin system for AI agents: connect to a server and the agent gains new capabilities.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;why-a-standalone-server&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#why-a-standalone-server&quot;&gt;&lt;/a&gt;Why a standalone server?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus already has a built-in Dev MCP server that exposes tools from inside a running application: endpoints, configuration, dev services, testing, and more.
So why add another server?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The answer is &lt;strong&gt;lifecycle&lt;/strong&gt;.
The built-in Dev MCP server lives inside the Quarkus process.
When the app crashes (a compilation error, a missing bean, a bad migration), that MCP server dies with it.
The agent loses its connection and cannot inspect what went wrong.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus Agent MCP runs as a separate process.
It wraps &lt;code&gt;quarkus dev&lt;/code&gt; as a child process and stays alive when the application crashes.
The agent can read the logs, get structured exception details, fix the code, and watch the app recover on its own.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/agent-mcp/architecture-diagram.png&quot; alt=&quot;Quarkus Agent MCP Architecture&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#getting-started&quot;&gt;&lt;/a&gt;Getting started&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Install via &lt;a href=&quot;https://www.jbang.dev&quot;&gt;JBang&lt;/a&gt; with a single command.
For Claude Code:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;claude mcp add quarkus-agent -- jbang quarkus-agent-mcp@quarkusio&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Or as a Claude Code plugin:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;claude plugin marketplace add quarkusio/quarkus-agent-mcp
claude plugin install quarkus-agent@quarkus-tools&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The README covers configuration for VS Code, Cursor, Windsurf, JetBrains, and other MCP-compatible tools.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once installed, you can verify it works by asking your agent:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;quoteblock&quot;&gt;
&lt;blockquote&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Search the Quarkus docs for how to create a REST endpoint&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The agent will use the &lt;code&gt;quarkus_searchDocs&lt;/code&gt; tool and return documentation results.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-the-agent-can-do&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-the-agent-can-do&quot;&gt;&lt;/a&gt;What the agent can do&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus Agent MCP exposes tools organized into five areas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;create-applications&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#create-applications&quot;&gt;&lt;/a&gt;Create applications&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;quarkus_create&lt;/code&gt; tool scaffolds a new Quarkus project from natural language.
Ask your agent to &lt;em&gt;&quot;create a Quarkus REST API with PostgreSQL and Panache&quot;&lt;/em&gt; and it will pick the right extensions, create the project, start it in dev mode, and generate a &lt;code&gt;AGENTS.md&lt;/code&gt; — a convention file that AI agents read for project-specific instructions.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;learn-before-coding-extension-skills&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#learn-before-coding-extension-skills&quot;&gt;&lt;/a&gt;Learn before coding: extension skills&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Before writing a single line of code, the agent calls &lt;code&gt;quarkus_skills&lt;/code&gt; to load coding patterns for the application&amp;#8217;s extensions.
These skills contain the kind of knowledge that usually lives in a senior developer&amp;#8217;s head: which annotations to use, how to write tests, what the common pitfalls are, and troubleshooting guidance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example, the Hibernate Validator skill teaches the agent that constraint violations on REST endpoint parameters automatically return HTTP 400, that &lt;code&gt;@Valid&lt;/code&gt; is required for cascading validation on nested objects, and that method validation only works on CDI-managed beans.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Without skills, the agent might still produce working code, especially with larger models, but the results become less predictable.
Skills level the playing field: even smaller, cheaper models produce correct idiomatic Quarkus code when they have the right patterns to follow.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;More on how skills work, and how you can write your own, later in this post.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;search-documentation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#search-documentation&quot;&gt;&lt;/a&gt;Search documentation&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;quarkus_searchDocs&lt;/code&gt; tool performs semantic search over the full Quarkus documentation.
On first use, a Docker/Podman container with pre-indexed documentation starts automatically.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
The search implementation (currently using BGE embeddings and pgvector) is still being iterated on and may change in future versions.
The documentation version matches the project&amp;#8217;s Quarkus version, so the agent never gives advice based on a different release.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;manage-the-application-lifecycle&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#manage-the-application-lifecycle&quot;&gt;&lt;/a&gt;Manage the application lifecycle&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The agent can start, stop, and restart the application.
It can check the application status, read logs, and list all managed instances.
When the app crashes, the agent uses the Dev MCP proxy to call &lt;code&gt;devui-exceptions_getLastException&lt;/code&gt;, which returns the exception class, message, stack trace, and exact source location.
It then fixes the code and lets hot reload do the rest.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;proxy-to-dev-mcp-tools&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#proxy-to-dev-mcp-tools&quot;&gt;&lt;/a&gt;Proxy to Dev MCP tools&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once the application is running, the agent can discover and call any tool exposed by the built-in Dev MCP server.
This includes running tests, listing endpoints, inspecting dev services, changing configuration, and managing extensions, all through a single proxy layer.
The tool list is dynamic: when you add or remove extensions, the agent re-discovers the available tools automatically.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;the-development-workflow&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-development-workflow&quot;&gt;&lt;/a&gt;The development workflow&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here is what an agent-driven development session looks like in practice:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;For a new project:&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_create&lt;/code&gt;: scaffold the project, auto-start dev mode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_skills&lt;/code&gt;: learn extension patterns before writing code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_searchDocs&lt;/code&gt;: look up APIs and configuration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write code and tests&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run tests via &lt;code&gt;quarkus_callTool&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the app crashes, read the exception, fix, and iterate&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;For an existing project:&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_update&lt;/code&gt;: check if the Quarkus version is current&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_start&lt;/code&gt;: start dev mode&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quarkus_skills&lt;/code&gt;: learn extension patterns&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Develop, test, iterate&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The key insight is &lt;strong&gt;skills before code&lt;/strong&gt;.
The agent does not guess at patterns.
It reads the skills, then writes code that follows them.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;for-extension-authors-shipping-skills-with-your-extension&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#for-extension-authors-shipping-skills-with-your-extension&quot;&gt;&lt;/a&gt;For extension authors: shipping skills with your extension&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you maintain a Quarkus extension, whether in core, Quarkiverse, or your own organization, you can ship a skill file that teaches every AI agent how to use your extension correctly.
The agent picks up the skill automatically when a developer adds your extension to their project.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;what-goes-into-an-extension-skill&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-goes-into-an-extension-skill&quot;&gt;&lt;/a&gt;What goes into an extension skill?&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A skill file is a Markdown document at &lt;code&gt;META-INF/quarkus-skill.md&lt;/code&gt; in your extension&amp;#8217;s &lt;strong&gt;deployment&lt;/strong&gt; JAR.
It should contain the practical knowledge an agent needs to write correct code with your extension:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Coding patterns&lt;/strong&gt;: the right way to use your APIs, with brief examples&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing guidelines&lt;/strong&gt;: how to write tests that work with your extension&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Common pitfalls&lt;/strong&gt;: mistakes the agent should avoid&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;: key properties and their effect&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here is an abbreviated example from the Hibernate Validator extension:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-markdown hljs&quot; data-lang=&quot;markdown&quot;&gt;### Bean Validation Annotations

- Use constraints from `jakarta.validation.constraints` packages,
  e.g. `@NotNull`, `@NotBlank`, `@Size`, `@Min`, `@Max`, `@Email`, `@Pattern`
  on class fields and getters or on method parameters of CDI beans.
- Use `@Valid` for cascading validation on nested types.

### REST Integration

- Constraint violations on REST endpoint **parameters** automatically return
  HTTP 400 with validation details.
- Return value validation results in HTTP 500, not 400. Handle
  `ConstraintViolationException` explicitly if you need custom error responses.

### Common Pitfalls

- Do NOT forget `@Valid` on nested object parameters. Without it, constraints
  on nested object fields are silently ignored.
- Method validation only works on CDI-managed beans. Calls on plain `new`
  objects are not validated.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;where-to-put-it&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#where-to-put-it&quot;&gt;&lt;/a&gt;Where to put it&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Place the file at:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-none hljs&quot;&gt;your-extension/
  deployment/
    src/main/resources/
      META-INF/
        quarkus-skill.md&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That is it.
When the extension is published and a developer adds it to their project, &lt;code&gt;quarkus_skills&lt;/code&gt; will discover the skill from the deployment JAR in the local Maven repository, compose it with metadata from &lt;code&gt;quarkus-extension.yaml&lt;/code&gt;, and include any Dev MCP tools your extension exposes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
Per-extension skill discovery from deployment JARs requires Quarkus 3.35.0+. For older versions, the agent will rely on &lt;code&gt;quarkus_searchDocs&lt;/code&gt; for guidance instead.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;writing-effective-skills&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#writing-effective-skills&quot;&gt;&lt;/a&gt;Writing effective skills&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Keep these principles in mind:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Be prescriptive, not descriptive.&lt;/strong&gt;
The agent does not need a tour of your API surface; it can read Javadoc for that.
It needs to know the &lt;em&gt;right&lt;/em&gt; pattern to use and the mistakes to avoid.
Instead of &quot;the &lt;code&gt;@Transactional&lt;/code&gt; annotation can be used on methods,&quot; write &quot;always annotate write operations with &lt;code&gt;@Transactional&lt;/code&gt;.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Focus on what surprises people.&lt;/strong&gt;
If every new developer hits the same three issues with your extension, those belong in the skill.
If something works exactly as expected, you probably do not need to mention it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Keep it concise.&lt;/strong&gt;
A skill that is 50 lines of actionable guidance beats 500 lines of documentation rehash.
The agent will search the full documentation via &lt;code&gt;quarkus_searchDocs&lt;/code&gt; when it needs details.
The skill is for the patterns and pitfalls that documentation alone does not prevent.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Include testing patterns.&lt;/strong&gt;
How should tests be written for your extension?
What test infrastructure does it provide?
This is one of the areas where agents struggle most without guidance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Test with a cheap model.&lt;/strong&gt;
A large frontier model might produce correct code even without your skill.
The real test is whether a smaller, cheaper model (like Haiku or GPT-4o mini) gets it right when following your skill.
If it does, your skill is doing its job.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;the-three-layer-composition-system&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-three-layer-composition-system&quot;&gt;&lt;/a&gt;The three-layer composition system&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Different teams have different conventions, and sometimes the built-in skill does not cover a specific use case.
To handle this, skills use a three-layer composition system:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extension skill&lt;/strong&gt;: ships with the extension itself (&lt;code&gt;META-INF/quarkus-skill.md&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User-level skill&lt;/strong&gt;: stored at &lt;code&gt;~/.quarkus/skills/&amp;lt;extension-name&amp;gt;/SKILL.md&lt;/code&gt;, applies to all projects for that developer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Project-level skill&lt;/strong&gt;: stored at &lt;code&gt;.agent/skills/&amp;lt;extension-name&amp;gt;/SKILL.md&lt;/code&gt;, applies to one project only&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Layers 1 and 2 support &lt;strong&gt;enhance&lt;/strong&gt; (append additional guidance) and &lt;strong&gt;override&lt;/strong&gt; (fully replace) composition, controlled by the &lt;code&gt;mode&lt;/code&gt; field in the SKILL.md frontmatter:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-markdown hljs&quot; data-lang=&quot;markdown&quot;&gt;---
mode: enhance
---

### Our team conventions

- Always use constructor injection, never field injection.
- Name REST resource classes with the `Resource` suffix, not `Controller`.&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project-level skills (layer 3) are standalone files read as-is, with no composition against the base layers.
This means any agent can read them directly from the filesystem without needing to understand the composition chain.
Use the &lt;code&gt;quarkus_saveSkill&lt;/code&gt; tool to materialize a fully composed skill into &lt;code&gt;.agent/skills/&lt;/code&gt;, then edit the file directly to customize it for your project.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For global customizations that apply across all projects, the agent can use &lt;code&gt;quarkus_updateSkill&lt;/code&gt; to write to &lt;code&gt;~/.quarkus/skills/&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;privacy&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#privacy&quot;&gt;&lt;/a&gt;Privacy&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus Agent MCP runs entirely on your machine.
It does not collect telemetry or send data to any third party.
Outbound network requests are limited to downloading extension JARs from Maven Central, pulling pre-indexed documentation containers, and checking for Quarkus version updates. Everything is cached locally after the first use.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-is-next&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-is-next&quot;&gt;&lt;/a&gt;What is next&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus Agent MCP is part of the &lt;a href=&quot;https://github.com/quarkusio/quarkus/discussions/53093&quot;&gt;DevStar working group&lt;/a&gt; and we are actively developing new capabilities.
If you are an extension author interested in shipping skills, or a developer with feedback on the workflow, we want to hear from you.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Try it out:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;claude mcp add quarkus-agent -- jbang quarkus-agent-mcp@quarkusio&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
This example uses Claude Code, but any coding agent that supports the MCP protocol (Cursor, Windsurf, GitHub Copilot, JetBrains AI, and others) can connect to Quarkus Agent MCP. See the &lt;a href=&quot;https://github.com/quarkusio/quarkus-agent-mcp&quot;&gt;README&lt;/a&gt; for configuration instructions for each agent.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Then ask your agent to build something.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus-agent-mcp&quot;&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus-agent-mcp/issues&quot;&gt;Report issues&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/discussions/53093&quot;&gt;DevStar working group discussion&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/introducing-agent-mcp/
            </guid>
            
            
            
            <author>Phillip Kruger (https://twitter.com/phillipkruger)</author>
            
        </item>
        
        <item>
            <title>Faster Startup on IBM Semeru with OpenJ9 Shared Classes Cache</title>
            <link>
                https://quarkus.io/blog/semeru-scc/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Slow startup times have long been a challenge for Java applications. Project Leyden addressed this for JVMs like Temurin 25+, which are based on HotSpot, but what about users of JVMs based on IBM OpenJ9 like Semeru?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In our &lt;a href=&quot;https://quarkus.io/blog/leyden-2/&quot;&gt;previous post&lt;/a&gt;, we described how we integrated Project Leyden into Quarkus, bringing JVM startup way down.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But not everyone runs HotSpot-based JVMs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Many teams, especially in enterprise environments, run &lt;a href=&quot;https://www.ibm.com/semeru-runtimes&quot;&gt;IBM Semeru Runtimes&lt;/a&gt;, IBM&amp;#8217;s production Java runtime built on the &lt;a href=&quot;https://eclipse.dev/openj9/&quot;&gt;Eclipse OpenJ9&lt;/a&gt; JVM.
These teams deserve the similar startup improvements, with the same ease of use.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That&amp;#8217;s what we built. Starting with Quarkus 3.35, the same &lt;code&gt;quarkus.package.jar.aot.enabled=true&lt;/code&gt; flag that activates Leyden on OpenJDK now automatically generates an OpenJ9 Shared Classes Cache on IBM Semeru.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No code changes. No additional configuration. Quarkus detects the JVM and does the right thing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-is-the-openj9-shared-classes-cache&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-is-the-openj9-shared-classes-cache&quot;&gt;&lt;/a&gt;What is the OpenJ9 Shared Classes Cache?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Eclipse OpenJ9 JVM has long offered a feature called &lt;a href=&quot;https://eclipse.dev/openj9/docs/shrc/&quot;&gt;Shared Classes Cache (SCC)&lt;/a&gt;.
The concept is similar to what Project Leyden does for HotSpot, but it predates Leyden by many years and goes further in some respects.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At its core, the SCC is a region of shared memory — either a memory-mapped file (persistent) or shared memory segment (non-persistent) — that stores data the JVM would otherwise have to recompute on every startup.
When a class is loaded for the first time, OpenJ9 automatically stores it in the cache.
On subsequent startups, the JVM finds it there and skips parsing, verification, and loading from disk entirely.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But class data is only the beginning. The SCC stores three categories of data:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;dlist&quot;&gt;
&lt;dl&gt;
&lt;dt class=&quot;hdlist1&quot;&gt;Class metadata&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Parsed and verified class structures, ready to use without re-reading JAR files.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class=&quot;hdlist1&quot;&gt;AOT-compiled native code&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;The OpenJ9 AOT compiler dynamically compiles Java methods into native code at runtime and stores them in the cache. On subsequent runs, these pre-compiled methods execute immediately instead of being interpreted. The VM &lt;a href=&quot;https://eclipse.dev/openj9/docs/aot/&quot;&gt;automatically selects&lt;/a&gt; which methods to AOT-compile using heuristics that identify the startup phase of large applications — no manual configuration needed.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt class=&quot;hdlist1&quot;&gt;JIT profiling data and compilation hints&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;The JIT compiler stores profiling information and optimization hints in the cache, allowing subsequent JVM instances to make better compilation decisions from the start. When a cached AOT method runs, the JIT compiler can further optimize it based on actual runtime behavior, giving you the best of both worlds.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The result: significantly faster startup, lower memory overhead during class loading, and a warmer JIT from the very first request.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Unlike other class data sharing implementations, the OpenJ9 SCC is fully dynamic: it is populated transparently as your application runs, without requiring a separate offline step to enumerate classes.
The cache is also designed for multi-JVM environments — multiple JVM instances can share the same cache simultaneously, reducing the aggregate memory footprint when running several Java applications on the same host.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are familiar with how Leyden works, much of this will sound familiar. The key difference is that SCC is specific to the OpenJ9 JVM and has been production-hardened over many years, while Leyden is a newer effort within OpenJDK targeting HotSpot.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;using-it&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#using-it&quot;&gt;&lt;/a&gt;Using it&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you already have &lt;code&gt;quarkus.package.jar.aot.enabled=true&lt;/code&gt; in your build, you don&amp;#8217;t need to change anything. Just build with a Semeru JDK:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock primary asciidoc-tabs-sync-maven&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Maven&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;./mvnw verify -Dquarkus.package.jar.aot.enabled=true -DskipITs=false&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock secondary asciidoc-tabs-sync-gradle&quot;&gt;
&lt;div class=&quot;title&quot;&gt;Gradle&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;./gradlew build quarkusIntTest -Dquarkus.package.jar.aot.enabled=true&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That&amp;#8217;s it. The build:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Packages your application with the &lt;code&gt;aot-jar&lt;/code&gt; format.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Starts the application with &lt;code&gt;-Xshareclasses:name=quarkus-app,cacheDir=app-scc&lt;/code&gt;, which tells OpenJ9 to populate the cache as the application runs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your &lt;code&gt;@QuarkusIntegrationTest&lt;/code&gt; tests run against it, exercising your endpoints and features. During this time, OpenJ9 is continuously populating the cache with class data, AOT-compiled methods, and JIT profiling hints.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the tests finish and the application shuts down, the &lt;code&gt;app-scc/&lt;/code&gt; directory contains a fully populated Shared Classes Cache.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once that is done, verify that your logs contain &lt;code&gt;Detected IBM Semeru Runtime - using Shared Classes Cache&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To run the application with the cache:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;cd target/quarkus-app
java -Xshareclasses:name=quarkus-app,cacheDir=app-scc,readonly -jar quarkus-run.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;readonly&lt;/code&gt; flag prevents the cache from being modified at runtime.
This is the recommended setting for production: the cache is an artifact of the build, not something that should drift in production.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The generated &lt;code&gt;app-scc/&lt;/code&gt; directory must be deployed alongside your JAR:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-none hljs&quot;&gt;target/quarkus-app/
├── app-scc/              &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
├── quarkus-run.jar
├── lib/
└── quarkus/&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The Shared Classes Cache directory. Its contents are opaque to the user — OpenJ9 manages the internal structure.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;customizing-the-training-run&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#customizing-the-training-run&quot;&gt;&lt;/a&gt;Customizing the training run&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you need to pass additional JVM flags during the training run (for example, to increase heap size or enable specific JVM features), you can use:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.package.jar.aot.additional-recording-args=-Xmx512m&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;troubleshooting&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#troubleshooting&quot;&gt;&lt;/a&gt;Troubleshooting&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If the cache doesn&amp;#8217;t seem to improve startup, first verify it is actually being used.
Enable verbose output by replacing &lt;code&gt;readonly&lt;/code&gt; with &lt;code&gt;readonly,verboseIO&lt;/code&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;java -Xshareclasses:name=quarkus-app,cacheDir=app-scc,readonly,verboseIO -jar quarkus-run.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This prints detailed information about each class loaded from the cache versus the filesystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Also make sure you are using the exact same Semeru JVM version to run the application as was used to build the cache.
OpenJ9 uses internal generation numbers to detect incompatible caches; a version mismatch will cause the cache to be ignored.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-auto-detection-works&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-auto-detection-works&quot;&gt;&lt;/a&gt;How auto-detection works&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When &lt;code&gt;quarkus.package.jar.aot.enabled=true&lt;/code&gt; is set and no explicit type is configured, Quarkus picks the best strategy for the JVM it detects at build time:&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33.3333%;&quot;&gt;
&lt;col style=&quot;width: 33.3333%;&quot;&gt;
&lt;col style=&quot;width: 33.3334%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Build JVM&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Strategy&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;IBM Semeru&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Shared Classes Cache (&lt;code&gt;-Xshareclasses&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;app-scc/&lt;/code&gt; directory&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;HotSpot (25+)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Leyden AOT (&lt;code&gt;-XX:AOTCache&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;app.aot&lt;/code&gt; file&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Older HotSpot&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;AppCDS (&lt;code&gt;-XX:SharedArchiveFile&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;app-cds.jsa&lt;/code&gt; file&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The detection checks &lt;code&gt;java.runtime.name&lt;/code&gt; for the string &lt;code&gt;semeru&lt;/code&gt;. If it matches, the SCC path is chosen. Otherwise, Quarkus checks the Java version: 25 or higher selects Leyden, anything older falls back to AppCDS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you need to override the auto-detection (for example, to force AppCDS on Semeru for comparison), you can set the type explicitly:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.package.jar.aot.type=SCC&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Valid values are &lt;code&gt;AUTO&lt;/code&gt; (the default), &lt;code&gt;AOT&lt;/code&gt;, &lt;code&gt;AppCDS&lt;/code&gt;, and &lt;code&gt;SCC&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;one-flag-every-jvm&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#one-flag-every-jvm&quot;&gt;&lt;/a&gt;One flag, every JVM&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is the design decision we are most proud of in this work. Your build configuration, CI pipeline, and Dockerfile don&amp;#8217;t need to know which JVM will run the application. Set &lt;code&gt;quarkus.package.jar.aot.enabled=true&lt;/code&gt;, and the build adapts.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This matters in practice. Teams that standardize on Semeru for some services and HotSpot for others can use the same Quarkus build configuration everywhere. Switching JVMs doesn&amp;#8217;t require touching &lt;code&gt;application.properties&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It also means that the Quarkus documentation, guides, and examples work the same way regardless of the JVM.
When we write &quot;enable AOT for faster startup,&quot; that statement is true whether you run HotSpot, Semeru, or an older JDK.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;differences-from-project-leyden&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#differences-from-project-leyden&quot;&gt;&lt;/a&gt;Differences from Project Leyden&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While the user experience is intentionally identical, there are a few technical differences worth noting:&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33.3333%;&quot;&gt;
&lt;col style=&quot;width: 33.3333%;&quot;&gt;
&lt;col style=&quot;width: 33.3334%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Project Leyden (HotSpot)&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Shared Classes Cache (OpenJ9)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Cache format&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Single &lt;code&gt;app.aot&lt;/code&gt; file&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;app-scc/&lt;/code&gt; directory&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;What is cached&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Loaded/linked classes, method profiles (future: JIT code)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Class data, AOT-compiled native code, JIT profiling data and hints&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;AOT compilation&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Not yet included (planned for future JDK releases)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Included: startup methods are AOT-compiled and stored in the cache&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Training&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Two-step: record configuration, then create cache in a separate JVM invocation&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Single step: cache is populated during the training run itself&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;JVM requirement&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Version &amp;gt;=25&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Any IBM Semeru version&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Maturity&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;New (JDK 25, actively evolving)&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;Mature (production-hardened over many years in OpenJ9)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One notable difference is that the SCC already includes AOT-compiled native code for startup methods, whereas Leyden currently caches class loading and linking data plus method profiling information, with compiled code storage planned for future JDK versions.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;some-numbers&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#some-numbers&quot;&gt;&lt;/a&gt;Some numbers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To give you a sense of what the SCC brings in practice, we measured startup time and memory usage for the Quarkus REST JSON quickstart application on IBM Semeru 25, with and without the Shared Classes Cache.&lt;/p&gt;
&lt;/div&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 25%;&quot;&gt;
&lt;col style=&quot;width: 25%;&quot;&gt;
&lt;col style=&quot;width: 12.5%;&quot;&gt;
&lt;col style=&quot;width: 25%;&quot;&gt;
&lt;col style=&quot;width: 12.5%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Startup time&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;RSS&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Default (no SCC)&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;433 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;107 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;With Shared Classes Cache&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;206 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-52%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;87 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-19%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The SCC file is &lt;code&gt;25 MB&lt;/code&gt; in size — a reasonable cost for a 52% startup improvement.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These numbers were measured on a developer laptop, not in an isolated lab environment.
Your results will vary depending on your application&amp;#8217;s size and complexity.
The more classes and methods your application loads during startup, the more the SCC helps.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;We were able to start a Quarkus REST application on IBM Semeru in just &lt;code&gt;206 ms&lt;/code&gt;&lt;/strong&gt; — and this is on the JVM, with full JIT compilation, full debugging support, and no native image involved.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;container-images-and-future-work&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#container-images-and-future-work&quot;&gt;&lt;/a&gt;Container images and future work&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;manual-deployment-today&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#manual-deployment-today&quot;&gt;&lt;/a&gt;Manual deployment today&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, you can deploy a Quarkus application with a pre-built SCC by copying the &lt;code&gt;app-scc/&lt;/code&gt; directory into your container image:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-dockerfile hljs&quot; data-lang=&quot;dockerfile&quot;&gt;FROM icr.io/appcafe/ibm-semeru-runtimes:open-21-jre-ubi-minimal
COPY target/quarkus-app /deployments
WORKDIR /deployments
CMD [&quot;java&quot;, \
     &quot;-Xshareclasses:name=quarkus-app,cacheDir=app-scc,readonly&quot;, \
     &quot;-jar&quot;, &quot;quarkus-run.jar&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This works, but it has a limitation: the SCC must be generated on the same JVM version that will run in the container.
If your build JVM differs from the container&amp;#8217;s JVM, the cache will be ignored.
To ensure a match, generate the cache using the same Semeru image in your CI pipeline.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;automated-container-image-integration&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#automated-container-image-integration&quot;&gt;&lt;/a&gt;Automated container image integration&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The container image integration we described in the &lt;a href=&quot;https://quarkus.io/blog/leyden-2/&quot;&gt;Leyden post&lt;/a&gt; — where Quarkus produces an AOT-optimized container image in a single command — is currently specific to the Leyden AOT path.
Extending it to support SCC-based container images is on our roadmap.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;cache-layering-for-docker&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#cache-layering-for-docker&quot;&gt;&lt;/a&gt;Cache layering for Docker&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is where things get particularly interesting. OpenJ9&amp;#8217;s SCC supports &lt;a href=&quot;https://blog.openj9.org/2019/11/05/the-multi-layer-shared-class-cache-for-docker/&quot;&gt;multi-layer caches&lt;/a&gt;, a feature specifically designed for container environments.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The problem with a single monolithic cache in a container image is Docker&amp;#8217;s copy-on-write mechanism.
If a base image contains a populated SCC and a higher layer writes to it (to add application-specific data), Docker duplicates the entire cache into the new layer.
This defeats the purpose of layer sharing and inflates the image size.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;OpenJ9 solves this with the &lt;code&gt;-Xshareclasses:createLayer&lt;/code&gt; option. Instead of a single cache, you build a stack of cache layers that align with your container image layers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Layer 0 (JDK base image): cache populated with JDK and framework classes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Layer 1 (application image): a separate, smaller cache layer containing only the application-specific class data, AOT code, and JIT hints.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Each cache layer is sized individually for its content, and the JVM reads from all layers at startup.
Because lower layers are never modified by higher ones, Docker&amp;#8217;s layer sharing works correctly — teams using the same base image share the JDK cache layer across all their application images.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is the part we are most excited about for future work. We plan to integrate this layered approach into Quarkus&amp;#8217;s container image extensions (&lt;code&gt;quarkus-container-image-docker&lt;/code&gt;, &lt;code&gt;quarkus-container-image-podman&lt;/code&gt;, and &lt;code&gt;quarkus-container-image-jib&lt;/code&gt;).
The goal is the same one-command experience we built for Leyden:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;./mvnw verify -Dquarkus.package.jar.aot.enabled=true -Dquarkus.container-image.build=true -DskipITs=false&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This would produce a container image with a properly layered SCC — the framework cache in a shared base layer, the application-specific cache in the top layer — optimized for both startup time and image size.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In microservices architectures where multiple Quarkus services share the same base image and dependency set, this layering could significantly reduce the total storage and transfer cost across all service images.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#acknowledgements&quot;&gt;&lt;/a&gt;Acknowledgements&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We would like to thank the OpenJDK team at IBM for their collaboration. The discussions around Leyden and Semeru&amp;#8217;s shared classes technology were instrumental in shaping this integration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The beauty of this integration is its simplicity: one flag, multiple JVMs, optimal performance everywhere. Whether you&amp;#8217;re running HotSpot or Semeru, Quarkus has you covered, as Quarkus has always been about meeting developers where they are.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We will continue tracking developments in both Project Leyden and OpenJ9 to bring you the best performance on whatever platform you choose.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 06 May 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/semeru-scc/
            </guid>
            
            
            
            <author>Georgios Andrianakis (https://twitter.com/geoand86)</author>
            
        </item>
        
        <item>
            <title>Emergency releases to fix  CVE-2026-39852 in all supported streams</title>
            <link>
                https://quarkus.io/blog/CVE-2026-39852/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we published releases to fix a severe security vulnerability: &lt;a href=&quot;https://github.com/quarkusio/quarkus/security/advisories/GHSA-rc95-pcm8-65v9&quot;&gt;CVE-2026-39852&lt;/a&gt; in all supported streams. The patched versions are:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;3.20.6.1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.27.3.1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.33.1.1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.34.7&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.35.2&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Update&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Please make sure you update to one of these releases immediately.
To update, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 04 May 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/CVE-2026-39852/
            </guid>
            
            
            
            <author>Jan Martiška (https://twitter.com/janmartiska)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.35 - JAR tree-shaking, PGO for native, Semeru AOT, @Transactional for Hibernate Reactive, and more</title>
            <link>
                https://quarkus.io/blog/quarkus-3-35-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;re pleased to announce the release of Quarkus 3.35.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release brings several notable features:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/53295&quot;&gt;#53295&lt;/a&gt; - JAR tree-shaking to eliminate unused classes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/53278&quot;&gt;#53278&lt;/a&gt; - Profile-Guided Optimization (PGO) support for native builds&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/53339&quot;&gt;#53339&lt;/a&gt; - Semeru AOT support&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51063&quot;&gt;#51063&lt;/a&gt; - Support &lt;code&gt;@Transactional&lt;/code&gt; for Hibernate Reactive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/53432&quot;&gt;#53432&lt;/a&gt; - CORS support for the management interface&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52919&quot;&gt;#52919&lt;/a&gt; - Remove the use of System Properties to propagate configuration in tests&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;New snapshot distribution infrastructure&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Update&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.35, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.35.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.35&quot;&gt;Quarkus 3.35 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-new&quot;&gt;&lt;/a&gt;What&amp;#8217;s new?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;jar-tree-shaking&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#jar-tree-shaking&quot;&gt;&lt;/a&gt;JAR tree-shaking&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A new experimental &lt;code&gt;quarkus.package.jar.tree-shake.mode&lt;/code&gt; option enables build-time dependency tree-shaking.
When set to &lt;code&gt;classes&lt;/code&gt;, Quarkus performs bytecode reachability analysis to identify and exclude unused classes from runtime dependencies, reducing application JAR size.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The analysis traces references through supertypes, annotations, &lt;code&gt;ServiceLoader&lt;/code&gt; entries, reflective class loading, and more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As an example, running tree-shaking on the Quarkus CLI removes over 6,000 unreachable classes, saving around 18 MB (39.5%).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This feature supports &lt;code&gt;fast-jar&lt;/code&gt;, &lt;code&gt;uber-jar&lt;/code&gt;, &lt;code&gt;legacy-jar&lt;/code&gt;, and &lt;code&gt;aot-jar&lt;/code&gt; packaging types.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As mentioned, this new feature is experimental, and feedback is highly welcome!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;profile-guided-optimization-for-native-builds&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#profile-guided-optimization-for-native-builds&quot;&gt;&lt;/a&gt;Profile-guided optimization for native builds&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can now opt in to Profile-Guided Optimization (PGO) for native builds by setting &lt;code&gt;quarkus.native.pgo.enabled=true&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that PGO is a feature of Oracle GraalVM and is not available in GraalVM Community Edition.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When enabled, Quarkus uses your integration tests as the workload to profile the application.
The resulting PGO data is then fed into the native compilation for better runtime performance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The implementation follows a similar pattern to the Project Leyden AOT support introduced in Quarkus 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;semeru-aot-support&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#semeru-aot-support&quot;&gt;&lt;/a&gt;Semeru AOT support&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Building on the Project Leyden AOT integration from Quarkus 3.32, Quarkus now also supports IBM Semeru&amp;#8217;s AOT features.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In initial testing on the &lt;code&gt;rest-json&lt;/code&gt; quickstart with IBM Semeru Runtime Open Edition 25, startup time was cut roughly in half (from ~380 ms down to ~190 ms).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For now, this is limited to building JARs with Semeru AOT, automatic container image building (as available with Leyden) is not yet supported.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;transactional-for-hibernate-reactive&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#transactional-for-hibernate-reactive&quot;&gt;&lt;/a&gt;&lt;code&gt;@Transactional&lt;/code&gt; for Hibernate Reactive&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus now supports the &lt;code&gt;@Transactional&lt;/code&gt; annotation for Hibernate Reactive, thanks to a new &lt;code&gt;quarkus-reactive-transactions&lt;/code&gt; extension.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This means you can use the familiar &lt;code&gt;@Transactional&lt;/code&gt; annotation on methods that return &lt;code&gt;Uni&lt;/code&gt;, and the transaction lifecycle (begin, commit, rollback) will be managed within the reactive pipeline.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A few things to keep in mind:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Only &lt;code&gt;TxType.REQUIRED&lt;/code&gt; is currently supported.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mixing &lt;code&gt;@Transactional&lt;/code&gt; with &lt;code&gt;@WithTransaction&lt;/code&gt; or &lt;code&gt;@WithSessionOnDemand&lt;/code&gt; is not allowed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Methods annotated with &lt;code&gt;@Transactional&lt;/code&gt; are no longer automatically considered &lt;code&gt;@Blocking&lt;/code&gt;. If your method is blocking but returns &lt;code&gt;Uni&lt;/code&gt;, you now need an explicit &lt;code&gt;@Blocking&lt;/code&gt; annotation. See the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.35&quot;&gt;migration guide&lt;/a&gt; for details.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;cors-support-for-the-management-interface&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#cors-support-for-the-management-interface&quot;&gt;&lt;/a&gt;CORS support for the management interface&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The management interface now has its own dedicated CORS configuration, allowing you to set CORS policies independently from the main HTTP interface.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;testing-improvements&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#testing-improvements&quot;&gt;&lt;/a&gt;Testing improvements&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The test infrastructure no longer uses System Properties to propagate configuration from Dev Services, Test Resources, and Test Profiles.
This change opens the door for better parallel test execution (which we hope to achieve at some point in the future) and makes the Config system truly immutable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Tests using &lt;code&gt;QuarkusDevModeTest&lt;/code&gt;, &lt;code&gt;QuarkusIntegrationTest&lt;/code&gt;, or &lt;code&gt;QuarkusMainIntegrationTest&lt;/code&gt; can now declare a &lt;code&gt;Config&lt;/code&gt; field or method parameter to access the updated configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;new-snapshot-distribution&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#new-snapshot-distribution&quot;&gt;&lt;/a&gt;New snapshot distribution&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus snapshots are no longer published to Sonatype, which had reliability issues with the volume of artifacts involved.
Snapshots are now published daily as GitHub Releases in the &lt;a href=&quot;https://github.com/quarkusio/quarkus-ecosystem-ci/releases&quot;&gt;quarkusio/quarkus-ecosystem-ci&lt;/a&gt; repository, with version &lt;code&gt;999-SNAPSHOT&lt;/code&gt;.
Each release contains a &lt;code&gt;maven-repo.tar.gz&lt;/code&gt; asset with pre-built Maven artifacts that you can extract into your local Maven repository.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For CI setups, a dedicated &lt;a href=&quot;https://github.com/quarkusio/install-quarkus-snapshots-action/&quot;&gt;GitHub Action&lt;/a&gt; is also available.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;More details can be found in the &lt;a href=&quot;https://github.com/quarkusio/quarkus/blob/main/CONTRIBUTING.md#using-snapshots&quot;&gt;Using snapshots&lt;/a&gt; section of the contributing guide.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;jackson-reflection-free-serializers-for-quarkus-rest&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#jackson-reflection-free-serializers-for-quarkus-rest&quot;&gt;&lt;/a&gt;Jackson reflection-free serializers for Quarkus REST&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We initially planned to make Jackson reflection-free serializers the default for Quarkus REST in 3.35.
However, thanks to several community members who tested this feature and reported issues, we identified a number of edge cases that still need to be addressed.
We decided to postpone making it the default to 3.36, so that we can fix these issues first.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We are very grateful to everyone who took the time to report problems, your feedback is what makes Quarkus better.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the meantime, we very much welcome more testing from our community.
You can enable reflection-free serializers by adding the following property to your configuration:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Please report any issues you encounter on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;platform-updates&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#platform-updates&quot;&gt;&lt;/a&gt;Platform updates&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Various Platform components were upgraded including:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Camel Quarkus to 3.35.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus CXF to 3.35.1 - see release notes for &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-cxf/dev/release-notes/3.35.0.html&quot;&gt;3.35.0&lt;/a&gt; and &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-cxf/dev/release-notes/3.35.1.html&quot;&gt;3.35.1&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus Amazon Services to 3.18.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus MCP Server to 1.12.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus Flow to 0.9.0&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.35.0.CR1&quot;&gt;3.35.0.CR1&lt;/a&gt;, &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.35.0&quot;&gt;3.35.0&lt;/a&gt;, and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.35.1&quot;&gt;3.35.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1188 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.35 release, thanks to Ales Justin, Alexey Loubyansky, andreatp, Andy Damevin, anuragg-saxenaa, Arseni Buinitski, Aurea Munoz, Aurélien Pupier, Bruno Baptista, brunobat, Carles Arnal, Cesar M. Romero-Pedraza, Chris Laprun, Chris Ruffalo, Clement Escoffier, Cristiano Nicolai, DerFrZocker, Dmitri Bourlatchkov, Faisal Dilawar, Foivos Zakkak, George Gastaldi, Georgios Andrianakis, Guillaume Smet, Holly Cummins, Inaki Villar, Jakub Jedlicka, Jamal Dabari, Jan Martiska, Jens Teglhus Møller, Julien Ponge, Karm Michal Babacek, Katia Aresti, keshavprashatdeshpande, Ladislav Thon, lberrymage, Luca Molteni, marco sappe griot, mariofusco, marko-bekhta, Martin Kouba, Matej Novotny, Matej Vašek, Max Rydahl Andersen, Maximilian Zellhofer, Melloware, Michael Edgar, Michal Maléř, Michal Vavřík, Mihajlo Veljković, Nick Robison, Nico Hinrichs, Ozan Gunalp, Paramvir Jindal, Phillip Kruger, Phillip Krüger, PreetiYadav, Robert Toyonaga, Roberto Cortez, Rolfe Dlugy-Hegwer, Rostislav Svoboda, Sergey Beryozkin, Simon Scatton, Simon Scholz, Stéphane Épardaud, Teymur Babayev, Thomas Segismont, tiwari91, Tiziano Basile, tom, xstefank, Yoann Rodière, and Yoshikazu Nojima.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-35-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>A2A Java SDK 1.0.0.Beta1 Released</title>
            <link>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-beta1-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We are pleased to announce the release of A2A Java SDK 1.0.0.Beta1, our first release fully aligned with the &lt;a href=&quot;https://a2a-protocol.org/v1.0.0/specification/&quot;&gt;final A2A Specification 1.0.0&lt;/a&gt;. The A2A Protocol has reached stability as an open standard, and this release marks the Java SDK tracking that maturity: protocol conformance is the central focus, and the SDK coordinates now reflect the project&amp;#8217;s identity under the &lt;a href=&quot;https://github.com/a2aproject&quot;&gt;A2A Project organization&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As a sign of this maturity, two structural breaking changes accompany this release:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Java packages have been renamed from &lt;code&gt;io.a2a.&lt;strong&gt;&lt;/code&gt; to &lt;code&gt;org.a2aproject.sdk.&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Maven &lt;code&gt;groupId&lt;/code&gt; has changed from &lt;code&gt;io.github.a2asdk&lt;/code&gt; to &lt;code&gt;org.a2aproject.sdk&lt;/code&gt; (first introduced in 1.0.0.Alpha4)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-a2a&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-a2a&quot;&gt;&lt;/a&gt;What&amp;#8217;s A2A?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Agent2Agent (A2A) Protocol is an open standard that enables AI agents to communicate and collaborate with one another, regardless of each agent&amp;#8217;s underlying framework, language, or vendor. The A2A Java SDK makes it easy to build A2A-compliant agents in Java, with reference implementations based on Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;breaking-changes&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#breaking-changes&quot;&gt;&lt;/a&gt;Breaking Changes&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;new-maven-coordinates&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#new-maven-coordinates&quot;&gt;&lt;/a&gt;New Maven Coordinates&lt;/h3&gt;
&lt;div class=&quot;admonitionblock important&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-important&quot; title=&quot;Important&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Maven &lt;code&gt;groupId&lt;/code&gt; has changed from &lt;code&gt;io.github.a2asdk&lt;/code&gt; to &lt;code&gt;org.a2aproject.sdk&lt;/code&gt;. If you are upgrading from any previous release, you must update your build files accordingly.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The root artifact coordinates were renamed to reflect the project&amp;#8217;s new home under the &lt;a href=&quot;https://github.com/a2aproject&quot;&gt;A2A Project organization&lt;/a&gt; and its availability on Maven Central.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Update your &lt;code&gt;pom.xml&lt;/code&gt; dependencies accordingly:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.a2aproject.sdk&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;a2a-java-sdk-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.0.Beta1&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;

&amp;lt;!-- Client --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.a2aproject.sdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-client&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- For JSON-RPC transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.a2aproject.sdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-jsonrpc&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- For gRPC transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.a2aproject.sdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-grpc&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- For HTTP+JSON/REST transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.a2aproject.sdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-rest&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;new-java-package-names&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#new-java-package-names&quot;&gt;&lt;/a&gt;New Java Package Names&lt;/h3&gt;
&lt;div class=&quot;admonitionblock important&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-important&quot; title=&quot;Important&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All Java packages have been renamed from &lt;code&gt;io.a2a.&lt;strong&gt;&lt;/code&gt; to &lt;code&gt;org.a2aproject.sdk.&lt;/strong&gt;&lt;/code&gt;. You must update all import statements in your source code when upgrading from any previous release.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;// Before
import io.a2a.client.A2AClient;
import io.a2a.model.Task;

// After
import org.a2aproject.sdk.client.A2AClient;
import org.a2aproject.sdk.model.Task;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Most IDEs can automate this migration via a project-wide find-and-replace of &lt;code&gt;io.a2a&lt;/code&gt; → &lt;code&gt;org.a2aproject.sdk&lt;/code&gt; in import statements, or by using the &quot;Optimize Imports&quot; / &quot;Migrate&quot; refactoring tools.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;key-highlights-in-1-0-0-beta1&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#key-highlights-in-1-0-0-beta1&quot;&gt;&lt;/a&gt;Key Highlights in 1.0.0.Beta1&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;equal-transport-support&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#equal-transport-support&quot;&gt;&lt;/a&gt;Equal Transport Support&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All three transports — JSON-RPC, gRPC, and HTTP+JSON/REST — are now fully supported and considered equal. Simply add the dependency for the transport you need (&lt;code&gt;a2a-java-sdk-reference-jsonrpc&lt;/code&gt;, &lt;code&gt;a2a-java-sdk-reference-grpc&lt;/code&gt;, or &lt;code&gt;a2a-java-sdk-reference-rest&lt;/code&gt;) and the SDK will work seamlessly regardless of your choice.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;structured-error-codes-and-details&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#structured-error-codes-and-details&quot;&gt;&lt;/a&gt;Structured Error Codes and Details&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A2A error types now carry structured error codes and details, making error handling more precise and easier to integrate with observability tooling. Error responses also now use the correct &lt;code&gt;data&lt;/code&gt; field name (previously &lt;code&gt;details&lt;/code&gt;) in JSON/HTTP responses, in alignment with the specification.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;http-caching-headers-for-agent-card&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#http-caching-headers-for-agent-card&quot;&gt;&lt;/a&gt;HTTP Caching Headers for Agent Card&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Agent Card endpoint now returns proper HTTP caching headers, allowing clients and proxies to cache agent metadata efficiently and reduce unnecessary round trips.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;datapart-fromjson-factory-method&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#datapart-fromjson-factory-method&quot;&gt;&lt;/a&gt;&lt;code&gt;DataPart.fromJson()&lt;/code&gt; Factory Method&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A new &lt;code&gt;DataPart.fromJson()&lt;/code&gt; factory method makes it straightforward to construct a &lt;code&gt;DataPart&lt;/code&gt; from a raw JSON string, without requiring prior deserialization.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;flexible-http-client-support&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#flexible-http-client-support&quot;&gt;&lt;/a&gt;Flexible HTTP Client Support&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The SDK defaults to a &lt;code&gt;JdkA2AHttpClient&lt;/code&gt; backed by the standard JDK &lt;code&gt;HttpClient&lt;/code&gt;, suitable for any Java environment. The &lt;code&gt;HttpClient&lt;/code&gt; builder also supports constructing a &lt;code&gt;JdkA2AHttpClient&lt;/code&gt; from a prebuilt &lt;code&gt;HttpClient&lt;/code&gt; instance, enabling advanced configuration scenarios such as custom SSL contexts or connection pool tuning.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When running on Quarkus, you can instead use the &lt;code&gt;VertxA2AHttpClient&lt;/code&gt;, which is backed by the Vert.x HTTP client for better integration with Quarkus&amp;#8217;s reactive engine, connection management, and observability features.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;bug-fixes-and-stability&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#bug-fixes-and-stability&quot;&gt;&lt;/a&gt;Bug Fixes and Stability&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Terminal-state tasks now correctly reject further operations with &lt;code&gt;UnsupportedOperationError&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Race conditions in &lt;code&gt;EventConsumer&lt;/code&gt; and the SSE transport have been resolved&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;PushNotificationNotSupportedError&lt;/code&gt; now returns HTTP 501 as required by the specification&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;POST requests without a &lt;code&gt;Content-Type&lt;/code&gt; header are now accepted when the body is empty&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tenant and &lt;code&gt;protocolVersion&lt;/code&gt; are now correctly preserved in the &lt;code&gt;ClientBuilder&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-next-road-to-1-0-0-ga&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-next-road-to-1-0-0-ga&quot;&gt;&lt;/a&gt;What&amp;#8217;s Next: Road to 1.0.0.GA&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Before the 1.0.0.GA release, we plan to introduce the following:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cross-version protocol support&lt;/strong&gt;: the SDK will be able to handle both version 1.0.0 and 0.3.0 of the A2A Protocol simultaneously, making it easier to interoperate with agents built against earlier versions of the specification.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Specification micro-update tracking&lt;/strong&gt;: as the A2A Specification evolves with patch-level updates, the SDK will follow those changes promptly to remain fully conformant.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release was made possible by the work of seven contributors. A special thank you to our four first-time contributors:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/brucearctor&quot;&gt;@brucearctor&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/maff&quot;&gt;@maff&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Lirons01&quot;&gt;@Lirons01&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/yyy9942&quot;&gt;@yyy9942&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And to the returning contributors:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jmesnil&quot;&gt;@jmesnil&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/kabir&quot;&gt;@kabir&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ehsavoie&quot;&gt;@ehsavoie&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Thank you all for your code, reviews, and feedback!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;resources&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#resources&quot;&gt;&lt;/a&gt;Resources&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/a2aproject/a2a-java/releases/tag/1.0.0.Beta1&quot;&gt;Release Notes on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://central.sonatype.com/artifact/org.a2aproject.sdk/a2a-java-sdk-parent/1.0.0.Beta1&quot;&gt;Maven Central&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://javadoc.io/doc/org.a2aproject.sdk/&quot;&gt;JavaDoc&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://a2a-protocol.org/v1.0.0/specification/&quot;&gt;A2A Specification&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are an A2A Java SDK user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/a2aproject/a2a-java/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/a2aproject/a2a-java/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on &lt;a href=&quot;https://discord.com/channels/1362108044737253548/1384238827090219138&quot;&gt;Discord&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-beta1-released/
            </guid>
            
            
            
            <author>Emmanuel Hugonnet (https://twitter.com/ehsavoie)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.34.6 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-34-6-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.34.6, the last maintenance release for our 3.34 stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Update&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.34, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.34&quot;&gt;Quarkus 3.34 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.6&quot;&gt;3.34.6&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-34-6-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus Newsletter #67 - April</title>
            <link>
                https://quarkus.io/blog/quarkus-newsletter-67/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Read &quot;Build a Streaming AI Chat in Java with Quarkus, Vaadin, and LangChain4j&quot;, a hands-on guest post by Sebastian Kühnau showing how to stream LLM responses token by token in a pure Java UI with Vaadin Flow and Quarkus. Check out Mario Fusco&amp;#8217;s post to learn our reasoning behind enabling by default in the Quarkus 3.35 release. Scivics Lab wrote a post &quot;quarkus-chat-ui: A Web Front-End for LLMs, and a Real-World Case for POJO-actor&quot; that introduces a new Chat UI component built with Vaadin and designed to integrate seamlessly into a Quarkus application, simplifying the creation of conversational interfaces. They then follow with another &quot;quarkus-chat-ui (2): The Actor Design Behind LLM-to-LLM Conversation&quot; so you can see how to actually use POJO-actor in quarkus-chat-ui, a Quarkus-based LLM chat UI that connects to Claude Code CLI, vLLM, and other backends. Learn how to integrate Redis caching and data storage in a Quarkus Java application using the Quarkus Redis extension with reactive by reading &quot;How to Use Redis with Quarkus in Java&quot; by Nawaz Dhandala. Markus Eisele wrote &quot;AI Coding Tools in 2026: How to Work With Agents Without Losing Control&quot; a Java engineer’s operating model: Ask/Plan/Code flows, guardrails, and review discipline at scale.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You will also see the latest Quarkus Insights episodes, top tweets/discussions and upcoming Quarkus attended events.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://quarkus.io/newsletter/67/&quot;&gt;Newsletter #67: April&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want to get newsletters in your inbox? &lt;a href=&quot;https://quarkus.io/newsletter&quot;&gt;Sign up for the newsletter&lt;/a&gt; using the on page form.&lt;/p&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-newsletter-67/
            </guid>
            
            
            
            <author>James Cobb (https://twitter.com/insectengine)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.34.5 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-34-5-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.34.5, the third maintenance release for our 3.34 stream (we skipped 3.34.4, due to a regression detected late in the Platform, caused by a Kafka Clients update).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.34, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.34&quot;&gt;Quarkus 3.34 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.4&quot;&gt;3.34.4&lt;/a&gt; and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.5&quot;&gt;3.34.5&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-34-5-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Enabling reflection-free Jackson serializers by default</title>
            <link>
                https://quarkus.io/blog/reflection-free-jsckson-serializers/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Some time ago, we started experimenting on how to improve the efficiency of JSON serialization and deserialization offered by Jackson and extensively used in Quarkus applications. From a performance point of view, Jackson&amp;#8217;s main bottleneck is its heavy reliance on Java reflection to access or populate data objects at runtime. To address this issue, we developed a build-time metaprogramming approach that generates reflection-free serializers and deserializers for Jackson.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In &lt;a href=&quot;https://quarkus.io/blog/quarkus-metaprogramming/&quot;&gt;this article&lt;/a&gt; we explained how we implemented this feature in Quarkus and the performance improvements it brings. Since then, we have been continuously working to enhance this feature, fix bugs, and improve compatibility with various Jackson features.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;configuring-reflection-free-jackson-serialization&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#configuring-reflection-free-jackson-serialization&quot;&gt;&lt;/a&gt;Configuring reflection-free Jackson serialization&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Given the experimental nature of this feature, we initially made it opt-in. To enable reflection-free Jackson serializers and deserializers in your Quarkus application, it is necessary to add the following configuration to your &lt;code&gt;application.properties&lt;/code&gt; file:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.rest.jackson.optimization.enable-reflection-free-serializers=true&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the past months an increasing number of users have tried this feature, taking advantage of the performance benefits it offers, but also helping us to discover bugs, edge cases, and compatibility issues with various Jackson features that we have addressed one by one. Overall, we have received positive feedback from the community, so we have decided to make the obvious next step.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;enabling-by-default-in-the-quarkus-3-35-release&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#enabling-by-default-in-the-quarkus-3-35-release&quot;&gt;&lt;/a&gt;Enabling by default in the Quarkus 3.35 release&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At the moment the entire Quarkus test suite is passing with this feature enabled, and we have addressed all compatibility issues reported by users so far. Therefore, we have decided to enable this feature by default in the next Quarkus 3.35 release.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In order to cover the broadest possible range of use cases, we invite you to test your applications with this feature enabled, possibly also measuring its impact on performances. If you encounter any issues or have feedback, please report them on our GitHub repository or reach out to us on the Quarkus community channels. This will help us to be more confident about the stability of this feature and ensure a smooth transition for all users.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/reflection-free-jsckson-serializers/
            </guid>
            
            
            
            <author>Mario Fusco (https://twitter.com/mariofusco)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.34.3 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-34-3-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.34.3, the second maintenance release for our 3.34 stream (we skipped 3.34.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.34, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.34&quot;&gt;Quarkus 3.34 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.3&quot;&gt;3.34.3&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 08 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-34-3-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.34.2 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-34-2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.34.2, the first maintenance release for our 3.34 stream (we skipped 3.34.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.34, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.34&quot;&gt;Quarkus 3.34 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.2&quot;&gt;3.34.2&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-34-2-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.34 - Enhancements all around</title>
            <link>
                https://quarkus.io/blog/quarkus-3-34-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released both &lt;a href=&quot;https://quarkus.io/blog/quarkus-3-33-released/&quot;&gt;Quarkus 3.33 LTS&lt;/a&gt; and Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While Quarkus 3.33 is a Long Term Support (LTS) release, branched from Quarkus 3.32 and maintained for 12 months,
Quarkus 3.34 comes with a lot of enhancements across the board:
Dev UI, Panache Next, and a lot of other areas got improved.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release also includes internal changes and refactorings that will bear fruits in future versions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.34, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.34.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.34&quot;&gt;Quarkus 3.34 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.0.CR1&quot;&gt;3.34.0.CR1&lt;/a&gt;, &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.0&quot;&gt;3.34.0&lt;/a&gt;, and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.34.1&quot;&gt;3.34.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1173 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.34 release, thanks to Ales Justin, Alexey Loubyansky, Andy Damevin, Asger Askov Blekinge, Ashish Thakur, Aurea Munoz, Aurélien Pupier, Bruno Baptista, Carles Arnal, Char, Chris Ruffalo, Clement Escoffier, Clément de Tastes, Daniel Vergien, David M. Lloyd, Dennis Kniep, Dmitri Bourlatchkov, Erwin Oegema, Faisal Dilawar, Foivos Zakkak, Frank Eichfelder, g, Gaelle Fournier, Galder Zamarreño, George Gastaldi, Georgios Andrianakis, Guillaume Smet, Holly Cummins, Inaki Villar, Jakub Jedlicka, Jan Martiska, jcarranzan, JeffersonSantos29, Jens Teglhus Møller, Julien Ponge, Katia Aresti, Kristian Rickert, Ladislav Thon, Luca Molteni, Martin Kouba, Martin Panzer, María Arias de Reyna Domínguez, Matej Novotny, Matheus Andre, Matheus André, Michael Edgar, Michal Maléř, Michal Vavřík, Nico Hinrichs, Ozan Gunalp, Patrick Schaub, Peter Levart, Phillip Krüger, Roberto Cortez, Sanne Grinovero, Sergey Beryozkin, shjones, Stéphane Épardaud, Thomas McWork, tiwari91, Tom Jenkinson, Tom Schindl, Vincent Sevel, xstefank, and Yoann Rodière.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-34-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.33 LTS - new LTS version</title>
            <link>
                https://quarkus.io/blog/quarkus-3-33-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is our pleasure to announce the release of Quarkus 3.33, which is our new LTS (Long Term Support) version.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This version is built on the top of Quarkus 3.32.
New features landed in &lt;a href=&quot;https://quarkus.io/blog/quarkus-3-34-released/&quot;&gt;Quarkus 3.34&lt;/a&gt;, which was also released today.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you want to know more about our LTS policy, the &lt;a href=&quot;https://quarkus.io/blog/lts-releases/&quot;&gt;LTS announcement&lt;/a&gt; is a must read.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;LTS releases are supported for 12 months.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are coming from the previous LTS, Quarkus 3.27 LTS, there are a lot of exciting new features and we recommend reading the following announcements:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/quarkus-3-28-released/&quot;&gt;Quarkus 3.28 - More security features, custom Grafana dashboards, support for multiple clients in Liquibase MongoDB, and more&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/quarkus-3-29-released/&quot;&gt;Quarkus 3.29 - Multiple cache backends and Qute DAP debugger support&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/quarkus-3-30-released/&quot;&gt;Quarkus 3.30 - JsonView on REST Client, Hibernate Validator 9.1, CLI decrypt command, and more&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/quarkus-3-31-released/&quot;&gt;Quarkus 3.31 - Full Java 25 support, Quarkus Maven packaging, Panache Next, and more!&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/quarkus-3-32-released/&quot;&gt;Quarkus 3.32 - Project Leyden integration, more graceful shutdown, automatic Consul registration and more!&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.33 LTS, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.33 LTS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are upgrading from 3.32, there&amp;#8217;s nothing to do as 3.33 LTS is the direct continuation of 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are upgrading from the previous LTS, Quarkus 3.27 LTS, please refer to the following migration guides:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.28&quot;&gt;Migration guide for 3.28&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.29&quot;&gt;Migration guide for 3.29&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Migration guide for 3.30&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;Migration guide for 3.31&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.32&quot;&gt;Migration guide for 3.32&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.33&quot;&gt;Migration guide for 3.33&lt;/a&gt; - this one is empty as 3.33 is the continuation of 3.32&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; should handle most of the heavy lifting for you,
but there are still cases that should be handled manually and we recommend reading these migration guides carefully.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-new&quot;&gt;&lt;/a&gt;What&amp;#8217;s new?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;platform-component-upgrades&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#platform-component-upgrades&quot;&gt;&lt;/a&gt;Platform component upgrades&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Various Platform components were upgraded including:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Quarkus CXF to 3.33.0 - see &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-cxf/dev/release-notes/3.33.0.html&quot;&gt;release notes&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Camel Quarkus to 3.33.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus Operator SDK to 7.7.3&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus Vault to 4.7.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus Qpid JMS to 2.12.0&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The core part of Quarkus 3.33 LTS is based on Quarkus 3.32 with some additional fixes included in 3.33.1.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.33.1&quot;&gt;3.33.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1173 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.33 release, thanks to Ales Justin, Alexey Loubyansky, Andy Damevin, Asger Askov Blekinge, Aurea Munoz, Aurélien Pupier, brunobat, Clement Escoffier, Clément de Tastes, David M. Lloyd, Dmitri Bourlatchkov, Erwin Oegema, Faisal Dilawar, Foivos Zakkak, Gaelle Fournier, George Gastaldi, Georgios Andrianakis, Guillaume Smet, Holly Cummins, Jakub Jedlicka, jcarranzan, Jens Teglhus Møller, Julien Ponge, Katia Aresti, Kristian Rickert, Ladislav Thon, Luca Molteni, Martin Kouba, Martin Panzer, María Arias de Reyna Domínguez, Matej Novotny, Michal Maléř, Michal Vavřík, Nico Hinrichs, Ozan Gunalp, Patrick Schaub, Phillip Kruger, Roberto Cortez, Sanne Grinovero, Sergey Beryozkin, shjones, Stéphane Épardaud, Thomas McWork, tiwari91, Tom Schindl, and Yoann Rodière.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The list is a bit smaller than usual as 3.33 LTS only contains bugfixes on top of 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-33-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.27.3 released - LTS maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-27-3-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.27.3, our next maintenance release for the 3.27 LTS stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release contains bugfixes, documentation updates and fixes the following CVEs:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-1002&quot;&gt;CVE-2026-1002&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-33042&quot;&gt;CVE-2025-33042&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It should be a safe upgrade for anyone already using 3.27.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.27, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update --stream=3.27&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.27.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.27.3&quot;&gt;the full changelog of 3.27.3 on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-27-3-released/
            </guid>
            
            
            
            <author>Jan Martiška (https://twitter.com/janmartiska)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.20.6 released - LTS maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-20-6-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.20.6, our next maintenance release for the 3.20 LTS stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release contains bugfixes, documentation updates and fixes the following CVEs:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-1002&quot;&gt;CVE-2026-1002&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-33042&quot;&gt;CVE-2025-33042&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It should be a safe upgrade for anyone already using 3.20.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.20, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update --stream=3.20&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.20.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.20.6&quot;&gt;the full changelog of 3.20.6 on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-20-6-released/
            </guid>
            
            
            
            <author>Jan Martiška (https://twitter.com/janmartiska)</author>
            
        </item>
        
        <item>
            <title>Apache Polaris is powered by Quarkus</title>
            <link>
                https://quarkus.io/blog/quarkus-polaris/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://polaris.apache.org/&quot;&gt;Apache Polaris&lt;/a&gt;, an open-source catalog for &lt;a href=&quot;https://iceberg.apache.org/&quot;&gt;Apache Iceberg&lt;/a&gt; has officially graduated to become a Top-Level Project (TLP), capping its incubation with a pivotal technical decision: adopting Quarkus as its cloud-native foundation. The fusion of an Iceberg catalog with Supersonic Subatomic Java delivers not only cloud-native efficiency and extensibility but also community collaboration, positioning Polaris as the leading solution for multi-engine data lakehouse architectures.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock text-center&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/polaris/polaris-quarkus.jpg&quot; alt=&quot;Quarkus + Polaris&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;the-journey-to-top-level-project&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-journey-to-top-level-project&quot;&gt;&lt;/a&gt;The Journey to Top-Level Project&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Apache Polaris has achieved a major milestone: graduating from the Apache Incubator to become a new Top-Level Project (TLP) within the Apache Software Foundation (ASF). This graduation signifies not only the maturity and community adoption of the project but also its successful integration into the &lt;em&gt;Apache Way&lt;/em&gt; of governance and operation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;understanding-the-apache-incubator&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#understanding-the-apache-incubator&quot;&gt;&lt;/a&gt;Understanding the Apache Incubator&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://incubator.apache.org/&quot;&gt;Apache Incubator&lt;/a&gt; is the entry point for projects, known as &quot;podlings,&quot; seeking to join the ASF. It guides them through the adoption of meritocratic, consensus-based governance, with experienced mentors acting as liaisons between the podling and the foundation&amp;#8217;s teams. Polaris successfully completed this mentored incubation process, demonstrating both community maturity and operational readiness.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;technical-evolution-during-incubation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#technical-evolution-during-incubation&quot;&gt;&lt;/a&gt;Technical Evolution During Incubation&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Polaris, the incubation period was not merely an exercise in governance; it also spurred significant technical development and strategic pivots. The project demonstrated its adaptability and commitment to robust architecture by implementing several important changes, including:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A New JDBC Persistence Layer: Enhancing the reliability and flexibility of catalog metadata storage and configuration management.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Advanced Security Features: Integrating new security capabilities, notably through the implementation of the Open Policy Agent (OPA) for policy-based catalog access control, and a sophisticated authorizer framework.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Robust Policy Management: Developing comprehensive frameworks for defining and enforcing catalog access policies and permissions, a core capability for multi-tenant catalog deployments.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Crucially, the team recognized that a successful TLP required a future-proof technical core, which led to one of its most pivotal architectural decisions: adopting Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;quarkus-adoption&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#quarkus-adoption&quot;&gt;&lt;/a&gt;Quarkus Adoption&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Among these technical advancements, one of the most pivotal and forward-looking decisions made during the incubation phase was the &lt;strong&gt;adoption of Quarkus&lt;/strong&gt; to power Apache Polaris. This strategic shift recognized that a modern Iceberg catalog serving multiple query engines requires more than traditional Java frameworks could efficiently deliver. The team needed a technology stack that could meet the demanding requirements of cloud-native deployments while maintaining the developer productivity essential for rapid innovation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus represents a fundamental shift in how Java applications are built for modern cloud environments. For Apache Polaris, an Iceberg catalog designed to serve multiple query engines, Quarkus provides the ideal combination of performance, developer productivity, and architectural flexibility.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;container-first-architecture&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#container-first-architecture&quot;&gt;&lt;/a&gt;Container-First Architecture&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus was designed from the ground up with a container-first philosophy. Unlike traditional frameworks that were retrofitted for containers, Quarkus optimizes applications specifically for containerized environments by shifting heavy computational work, such as classpath scanning, configuration loading, and dependency injection, from runtime to build time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Polaris, this means:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Faster Horizontal Scaling&lt;/strong&gt;: When deploying additional catalog instances to handle traffic spikes, containers start in milliseconds rather than seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Higher Density&lt;/strong&gt;: Lower memory footprint allows more Polaris instances per node, reducing infrastructure costs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Efficient Resource Use&lt;/strong&gt;: Minimal CPU and memory consumption directly lowers operational cloud costs and provides sustainability benefits by reducing resource consumption.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;performance-characteristics&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#performance-characteristics&quot;&gt;&lt;/a&gt;Performance Characteristics&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus delivers performance through four key dimensions:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fast Startup Times:&lt;/strong&gt; By performing application initialization work at build time, Quarkus enables Polaris to start rapidly, critical for auto-scaling scenarios where catalog instances must spin up quickly to handle bursts of metadata requests from Spark, Trino, Flink, or other query engines. To give some numbers, canonical Quarkus applications start in 10ms in native mode, in ~100ms using AOT (Leyden), and in 1 to 3s in plain JVM mode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced Memory Footprint&lt;/strong&gt;: The reactive core uses a small number of event loops instead of maintaining large thread pools, dramatically reducing memory usage and enabling higher deployment density.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;High Throughput&lt;/strong&gt;: The reactive, non-blocking engine based on Netty and Eclipse Vert.x enables Polaris to efficiently process numerous concurrent catalog operations, minimizing blocking during I/O to metadata stores or object storage. This non-blocking, reactive architecture allows Polaris to handle thousands of concurrent client connections, such as metadata requests from Spark or Trino, without dedicating a thread per request, thus avoiding thread-contention bottlenecks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimized Resource Consumption&lt;/strong&gt;: The combination of build-time optimization and reactive architecture results in lower CPU requirements, directly reducing cloud costs for organizations running Polaris at scale.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;developer-productivity-and-versatility&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#developer-productivity-and-versatility&quot;&gt;&lt;/a&gt;Developer Productivity and Versatility&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus provides a cohesive, full-stack framework with a rich ecosystem of extensions, enabling the Polaris community to focus on catalog features rather than assembling infrastructure plumbing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Frictionless Development Experience:&lt;/em&gt; The live coding feature provides instant feedback during development, dramatically accelerating the inner development loop and enabling faster iteration on catalog capabilities and security enhancements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Programming Model Flexibility:&lt;/em&gt; Quarkus supports three execution approaches: plain imperative code, reactive programming using the Mutiny API, and virtual threads (JDK 21+), allowing developers to choose the right model for each component. This versatility means Polaris developers can use familiar imperative patterns for simple management endpoints (such as health checks) while fully leveraging the reactive/non-blocking approach (with Mutiny or virtual threads) for high-concurrency, I/O-intensive catalog operations (such as metadata lookups and commits).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Protocol Diversity:&lt;/em&gt; Native support for REST, gRPC, GraphQL, and message brokers (Kafka, RabbitMQ, Pulsar, Apache ActiveMQ) gives Polaris flexibility in how it exposes catalog APIs and integrates with the broader data ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;the-power-of-the-quarkiverse-ecosystem&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-power-of-the-quarkiverse-ecosystem&quot;&gt;&lt;/a&gt;The Power of the Quarkiverse Ecosystem&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Beyond the core framework, Quarkus offers access to the &lt;strong&gt;Quarkiverse&lt;/strong&gt;, an ecosystem of hundreds of community-driven and vendor-supported extensions. Rather than building custom integrations, the Polaris team leverages battle-tested extensions for persistence (PostgreSQL, MongoDB), security (OIDC, OPA), and observability (OpenTelemetry, Micrometer), as the next section illustrates with concrete examples from the codebase.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-polaris-leverages-quarkus&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-polaris-leverages-quarkus&quot;&gt;&lt;/a&gt;How Polaris Leverages Quarkus&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The true power of the Quarkus foundation becomes evident when examining how Apache Polaris leverages specific Quarkus features in its implementation. The catalog service integrates over 15 specialized extensions to deliver a production-ready, cloud-native Iceberg catalog. Here are a few examples of integration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;reactive-request-processing-with-quarkus-rest&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#reactive-request-processing-with-quarkus-rest&quot;&gt;&lt;/a&gt;Reactive Request Processing with Quarkus REST&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Polaris implements the Iceberg REST API using Quarkus REST, leveraging the Quarkus Reactive Core and SmallRye Mutiny to process thousands of concurrent metadata requests asynchronously without blocking threads.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here&amp;#8217;s the actual realm context resolver from the Polaris codebase:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@ServerRequestFilter(preMatching = true)
public Uni&amp;lt;Response&amp;gt; resolveRealmContext(ContainerRequestContext rc) {
   return realmContextResolver.resolveRealmContext(
                   rc.getUriInfo().getRequestUri().toString(),
                   rc.getMethod(),
                   rc.getUriInfo().getPath(),
                   rc.getHeaders()::getFirst)
           .invoke(realmContext -&amp;gt; realmContextHolder.set(realmContext))
           .invoke(realmContext -&amp;gt; ContextLocals.put(REALM_CONTEXT_KEY, realmContext));
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With just a few lines of reactive code, Polaris achieves multi-tenant request routing that would typically require significantly more boilerplate in traditional frameworks.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;resilience-with-smallrye-fault-tolerance&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#resilience-with-smallrye-fault-tolerance&quot;&gt;&lt;/a&gt;Resilience with SmallRye Fault Tolerance&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For critical operations such as persisting catalog events, Polaris uses Quarkus Fault Tolerance (which relies on SmallRye Fault Tolerance) to ensure reliability. Here is an example of how Polaris implements a resilient flush operation to the metadata store:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Retry(maxRetries = 5, delay = 1000, jitter = 100)
@Fallback(fallbackMethod = &quot;onFlushError&quot;)
protected void flush(String realmId, List&amp;lt;PolarisEvent&amp;gt; events) {
   var metaStoreManager =
        metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext);
   metaStoreManager.writeEvents(callContext, events);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This declarative approach to resilience means Polaris automatically retries failed writes to the metadata store, with configurable backoff and jitter to prevent thundering herd problems. Note that all the configured values can be overridden in the application configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;using-cdi-beans-as-extension-points-selecting-the-persistence-layer&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#using-cdi-beans-as-extension-points-selecting-the-persistence-layer&quot;&gt;&lt;/a&gt;Using CDI beans as extension points: selecting the persistence layer&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Polaris supports multiple persistence backends (PostgreSQL via the Quarkus JDBC PostgreSQL extension, MongoDB via the Quarkus MongoDB Client extension, and in-memory for testing) using Quarkus&amp;#8217;s CDI qualifier mechanism:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Produces
@ApplicationScoped
Backend backend(BackendConfiguration config, @Any Instance&amp;lt;BackendBuilder&amp;gt; builders) {
   var backendName = config.backend()
           .orElseThrow(() -&amp;gt; new IllegalStateException(
               &quot;Configuration polaris.persistence.nosql.backend is missing!&quot;)
           );
   var builder = builders.select(BackendType.Literal.of(backendName));
   return builder.get().buildBackend();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This architecture allows operators to deploy Polaris with the persistence layer that matches their infrastructure requirements, simply by changing the &lt;code&gt;polaris.persistence.nosql.backend&lt;/code&gt; configuration property.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;comprehensive-observability&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#comprehensive-observability&quot;&gt;&lt;/a&gt;Comprehensive Observability&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Polaris leverages Quarkus Micrometer with Prometheus registry and Quarkus OpenTelemetry for complete observability. The catalog automatically tracks:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HTTP metrics&lt;/strong&gt; for all Iceberg REST API requests, tagged by realm, operation, and status code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom gauges and counters&lt;/strong&gt; for catalog-specific metrics like table count, namespace count, and metadata operation latency&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Distributed traces&lt;/strong&gt; that follow requests across catalog operations, from initial metadata request through to storage access&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The metrics endpoint is exposed on a separate management port (8182), isolated from the main API port (8181), following Kubernetes best practices:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.http.port=8181
quarkus.management.enabled=true
quarkus.management.port=8182
quarkus.micrometer.enabled=true
quarkus.micrometer.export.prometheus.enabled=true&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;collaboration-between-quarkus-and-polaris-communities&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#collaboration-between-quarkus-and-polaris-communities&quot;&gt;&lt;/a&gt;Collaboration between Quarkus and Polaris Communities&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The adoption of Quarkus has created a productive feedback loop between the two communities. Engineers from both projects have worked closely together to ensure Quarkus is used effectively within Polaris, reporting bugs and identifying possible enhancements along the way. This hands-on collaboration benefits both sides: Polaris gets a solid, well-understood foundation, while Quarkus gains real-world feedback from a demanding, high-throughput Apache TLP deployment, driving stability and performance improvements that benefit the entire Quarkus ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;looking-ahead&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#looking-ahead&quot;&gt;&lt;/a&gt;Looking Ahead&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The successful graduation of Apache Polaris as a Top-Level Project, combined with the power and efficiency gained from its foundation on Quarkus, is merely the launchpad for a significant, forward-looking technical agenda. Polaris is positioned not just for growth, but to actively shape the future of cloud-native data lakehouse architectures.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The community is already aligning its development with the cutting edge of the Quarkus roadmap, including the forthcoming Quarkus 4 major release. This alignment guarantees that Polaris will continually benefit from performance gains, new cloud-native APIs, and the most advanced capabilities for its reactive core.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our vision extends to embracing new networking and security standards to meet the demands of the most critical deployments:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Next-Generation Networking:&lt;/strong&gt; We are exploring the adoption of HTTP/3, leveraging its multiplexing and reduced head-of-line blocking to further minimize latency and boost the throughput of metadata requests, which is crucial for query engines managing thousands of concurrent operations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Future-Proof Security:&lt;/strong&gt; Looking beyond today&amp;#8217;s standards, the project is investigating quantum-safe TLS and encryption. By integrating modern cryptographic practices, Polaris aims to provide a catalog that is secure not just for the present, but against the computational challenges of the future.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This commitment to continuous innovation, driven by an active community, ensures that Apache Polaris is ready to become the industry standard for high-performance, secure, and multi-engine Iceberg catalog interoperability. We welcome contributors, users, and organizations to join us in defining this next era of the data ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-polaris/
            </guid>
            
            
            
            <author></author>
            
        </item>
        
        <item>
            <title>Quarkus Newsletter #66 - March</title>
            <link>
                https://quarkus.io/blog/quarkus-newsletter-66/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In order to provide a transparent and comprehensive performance picture, Quarkus rebuilt its benchmark. Learn more in &quot;Quarkus has great performance – and we have new evidence&quot; by Holly Cummins. Read &quot;How Project Leyden brought a new perspective&quot; by Guillaume Smet to see how Project Leyden gave us a new perspective on how we think about startup performance in Quarkus. Check out Juarez Junior&amp;#8217;s post &quot;Unleash the Power of AI Agents with Java: Building Intelligent Applications with Quarkus, LangChain4j, and Oracle AI Database&quot; to learn how to build a Quarkus-based AI support agent that handles customer support for Oracle database error codes. See how executable architecture tests with Taikai replace diagrams, reviews, and tribal knowledge in modern Java systems in &quot;Your Java Architecture Is Lying to You: Enforcing Real Boundaries with Quarkus&quot; by Markus Eisele. Nowadays, Java enterprise applications often default to Angular, React, or Vue for the frontend. But for this kind of applications, the most natural UI framework already exists in the Java ecosystem: Jakarta Faces. Learn more in &quot;Rethinking Java Web UIs with Jakarta Faces and Quarkus&quot; by Nicolas Duminil. See how Markus Eisele built a streaming ingestion pipeline with SSE, batching, and PostgreSQL to track Java-related conversations in &quot;Listening to the Fediverse with Java: A Real-Time Quarkus Experiment&quot;. Read &quot;DPoP: What It Is, How It Works, and Why Bearer Tokens Aren’t Enough&quot; by Hüseyin Akdoğan to learn what DPoP (Demonstration of Proof-of-Possession) is, what problem it solves, and walk through a working implementation with Keycloak and Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You will also see the latest Quarkus Insights episodes, top tweets/discussions and upcoming Quarkus attended events.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://quarkus.io/newsletter/66/&quot;&gt;Newsletter #66: March&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want to get newsletters in your inbox? &lt;a href=&quot;https://quarkus.io/newsletter&quot;&gt;Sign up for the newsletter&lt;/a&gt; using the on page form.&lt;/p&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-newsletter-66/
            </guid>
            
            
            
            <author>James Cobb (https://twitter.com/insectengine)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.32.3 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-32-3-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.32.3, the second maintenance release for our 3.32 stream (we skipped 3.32.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We encourage you to test it, even if you track LTS releases, as 3.32 will be the foundation for 3.33 LTS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.32, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.32&quot;&gt;Quarkus 3.32 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.32.3&quot;&gt;3.32.3&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 11 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-32-3-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.32.2 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-32-2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.32.2, the first maintenance release for our 3.32 stream (we skipped 3.32.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We encourage you to test it, even if you track LTS releases, as 3.32 will be the foundation for 3.33 LTS.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.32, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.32&quot;&gt;Quarkus 3.32 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.32.2&quot;&gt;3.32.2&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-32-2-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>How we integrated Project Leyden into Quarkus</title>
            <link>
                https://quarkus.io/blog/leyden-2/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus has long supported both JVM and native image modes, each optimized for different trade-offs.
Native image delivers unmatched startup and footprint.
JVM mode offers peak throughput, dynamic capabilities, and a mature tooling ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus continues to improve and work well with native-image,
and lately Project Leyden enabled us to strengthen the JVM side of that equation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We shared our excitement about Project Leyden and how it gave us a new perspective on Java application startup performance in a previous &lt;a href=&quot;https://quarkus.io/blog/leyden-1/&quot;&gt;blog post&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this post, we want to share our journey integrating Project Leyden into Quarkus, and how we made this integration both efficient and easy to use for our users.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#acknowledgements&quot;&gt;&lt;/a&gt;Acknowledgements&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;First, we would like to thank the OpenJDK team at IBM for their work on Project Leyden and for the many discussions we had with them,
which were instrumental in helping us understand Leyden and determine how best to integrate it into Quarkus,
namely (in alphabetical order), Maria Arias de Reyna Dominguez, Andrew Dinn, and Ashutosh Mehra.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;More broadly, we would like to thank everyone contributing to Project Leyden.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden is still evolving, and we look forward to seeing what they are preparing for Java 27 and beyond.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Finally, special thanks to Sanne Grinovero for introducing us to the Leyden team at just the right time, and for his insights and valuable feedback on our work.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-is-project-leyden&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-is-project-leyden&quot;&gt;&lt;/a&gt;What is Project Leyden?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;graalvm&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#graalvm&quot;&gt;&lt;/a&gt;GraalVM and the popularization of AOT in Java&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the Java world, Ahead-of-Time (AOT) compilation rose to prominence with the introduction of GraalVM native image, which compiles Java applications into native executables.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It made a huge impact on the Java ecosystem and was a game changer for Java application startup performance:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Startup time and memory footprint are significantly reduced.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is no warmup phase, as the code is already compiled to native code. Performance is effectively at its peak from the start.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The resulting executable is small, leading to much smaller container images.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Resident Set Size (RSS) memory usage is much smaller compared to a regular JVM application.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But this comes with some drawbacks:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Not all Java features and libraries are supported out of the box as they are on OpenJDK.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It relies on a closed-world assumption and removes most runtime dynamism (at least in its current form - work on the GraalVM side could change this in the future). Note: This was not and is not an issue for Quarkus as it makes the same assumption; it can be problematic for third-party libraries.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It introduces specific constraints, the most common being the need to provide explicit reflection configuration. These requirements add effort during development and testing, although they are minimized for Quarkus supported extensions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Native image builds are significantly slower. This typically does not affect the inner development loop (except when debugging native-specific issues), but it can have a noticeable impact on CI resources.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Debugging native executables is hard. It has improved, but it is still a lot harder than debugging in the JVM as it requires the use of GDB and the presence of debug symbols in the build.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And since everything is AOT-compiled, there is no JIT compiler to optimize code at runtime, which can lead to suboptimal peak performance in some cases.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All in all, native image is an excellent option when startup time and footprint are the primary goals.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;However, not all applications optimize for those dimensions.
Some prioritize peak throughput, development velocity, debuggability, and compatibility with existing tooling.
This is where Leyden becomes interesting, aiming to improve startup and footprint while staying closer to the traditional JVM model.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;project-leydens-approach-to-aot&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#project-leydens-approach-to-aot&quot;&gt;&lt;/a&gt;Project Leyden&amp;#8217;s approach to AOT&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden addresses the same fundamental problem as GraalVM native image, but takes a different approach:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It is still &quot;pure&quot; Java, it is part of OpenJDK: your application runs on the JVM, with full access to Java features and libraries, without special configuration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;During a training phase, it records application behavior and gathers information such as loaded and linked classes, and in more recent versions also starts recording some JIT output - increasing scope and optimization potentials in each JVM version.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This information is stored in an AOT cache file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At startup, you configure the JVM with this AOT cache file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Because the application still runs on the JVM, you continue to benefit from the JIT compiler, your preferred garbage collector, and all other JVM optimizations, preserving the high throughput typically associated with the JVM.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The AOT cache is exactly that: a cache. If a class is not present in the cache, it is loaded and linked as usual.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden reduces startup time by optimizing class loading and linking.
It reduces warmup time by providing the JVM with profiling information, and will reduce it even further once compiled code itself is stored in the cache.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-2/leyden.png&quot; alt=&quot;How Leyden works&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. How Leyden works&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That said, Project Leyden is not magic either. In its current form:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Startup and warmup time improvements are significant, but not as substantial as with GraalVM/Mandrel native image.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You must train your application and generate the AOT cache. In practice, this is not difficult, and in Quarkus, we have made it as seamless as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You still need to ship a JVM with your application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You also need to ship the AOT cache, which means container images will be significantly larger than with native executables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You don&amp;#8217;t get any memory footprint benefit yet: in most cases, it&amp;#8217;s comparable to a regular JVM.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our take is that Project Leyden offers a compelling balance between performance and compatibility, at a very reasonable cost,
and could become part of the default deployment workflow for many Java applications running on the JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;project-leyden-status&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#project-leyden-status&quot;&gt;&lt;/a&gt;Project Leyden status&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In OpenJDK 25, the following Project Leyden-related JEPs are available:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://openjdk.org/jeps/483&quot;&gt;JEP 483 - Ahead-of-Time Class Loading &amp;amp; Linking&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://openjdk.org/jeps/514&quot;&gt;JEP 514 - Ahead-of-Time Command-Line Ergonomics&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://openjdk.org/jeps/515&quot;&gt;JEP 515 - Ahead-of-Time Method Profiling&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Together, these JEPs make Project Leyden fully usable starting with OpenJDK 25.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Additional JEPs are planned for OpenJDK 26 and beyond.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;project-leyden-in-quarkus&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#project-leyden-in-quarkus&quot;&gt;&lt;/a&gt;Project Leyden in Quarkus&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus is a highly specialized framework, with extensive build-time processing and optimizations.
Project Leyden is a specialized technology as well, with its own constraints and requirements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our goal was to integrate Project Leyden into Quarkus in a way that preserves what Quarkus does best, while also maximizing the benefits of Leyden.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.32 includes the first version of our end-to-end Leyden integration. Let&amp;#8217;s take a closer look at how it works.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;aot-jar-packaging&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#aot-jar-packaging&quot;&gt;&lt;/a&gt;AOT JAR packaging&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You may be used to seeing your Quarkus application packaged in a &lt;code&gt;target/quarkus-app/&lt;/code&gt; directory, but that wasn&amp;#8217;t always the case.
In the early days of Quarkus, we built a traditional runner JAR in &lt;code&gt;target/&lt;/code&gt;, with dependencies placed in a &lt;code&gt;lib/&lt;/code&gt; directory, much like most other Java frameworks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The current default packaging in Quarkus is called &lt;code&gt;fast-jar&lt;/code&gt;.
One of its primary goals is to optimize class loading.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We achieved this by introducing our own class loader, which, for example, keeps a &lt;code&gt;package name&lt;/code&gt; &amp;#8594; &lt;code&gt;jar file&lt;/code&gt; mapping in memory.
It also includes additional optimizations, such as maintaining a full directory index for specific locations like &lt;code&gt;META-INF/services&lt;/code&gt;.
These are just a few examples of what this packaging does, but they should give you some context.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This packaging performs very well in the traditional JVM world, but it doesn&amp;#8217;t play nicely with Project Leyden.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden takes a conservative approach: it only caches classes loaded by the standard JDK class loaders.
In other words, no custom class loaders are allowed if you want to fully benefit from AOT caching.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We hope that, at some point, this limitation will be lifted by the Leyden team.
If that happens, we will return to the &lt;code&gt;fast-jar&lt;/code&gt; packaging, or an evolution of it.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To be precise: you cannot use custom class loaders to load &lt;strong&gt;classes&lt;/strong&gt; if you want to fully benefit from AOT caching.
However, you can still use a custom class loader for loading &lt;strong&gt;resources&lt;/strong&gt; only.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is why we developed a dedicated packaging for Project Leyden: &lt;code&gt;aot-jar&lt;/code&gt;.
It is automatically selected when AOT is enabled, making the transition completely transparent.
It uses the same file layout as the &lt;code&gt;fast-jar&lt;/code&gt; packaging.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In addition to delegating all &lt;strong&gt;class&lt;/strong&gt; loading to the JDK class loader, this packaging has a few specific characteristics:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It collects service descriptors from &lt;code&gt;META-INF/services&lt;/code&gt;, aggregates them, and keeps them in memory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It applies the same approach to Quarkus configuration files (e.g., &lt;code&gt;application.properties&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It maintains a full index of specific directories (e.g., the root directory, &lt;code&gt;META-INF&lt;/code&gt;, and &lt;code&gt;META-INF/services&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It introduces a pre-initialization phase, during which selected elements are preloaded in parallel (e.g., the time zone database).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As this packaging format is new, we hope to gather feedback from real-world usage.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s be clear: &lt;code&gt;aot-jar&lt;/code&gt; performs worse than &lt;code&gt;fast-jar&lt;/code&gt; when Project Leyden is not used.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It does not include all the optimizations of &lt;code&gt;fast-jar&lt;/code&gt; and is intended to be used only in conjunction with Project Leyden.
So it should not be used outside of this specific use case.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;training-and-aot-cache-generation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#training-and-aot-cache-generation&quot;&gt;&lt;/a&gt;Training and AOT cache generation&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The AOT cache is only as good as the training data used to generate it.
During the training phase, the JVM records which classes are loaded and linked, and collects method profiling data.
The more representative the training workload, the more effective the resulting cache.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We wanted training to be as seamless as possible for Quarkus users.
The natural fit was to leverage the existing integration test infrastructure:
if you already have &lt;code&gt;@QuarkusIntegrationTest&lt;/code&gt; tests, they can serve as the training workload.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When AOT training is enabled, the flow is as follows:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Quarkus builds the application with the &lt;code&gt;aot-jar&lt;/code&gt; packaging.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The application starts with AOT training enabled.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integration tests run against the application, exercising its endpoints and features.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The JVM captures profiling data during the entire test execution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An optimized &lt;code&gt;app.aot&lt;/code&gt; cache file is generated from the recorded data.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is both practical and effective: you already write integration tests to validate your application,
and they also happen to produce somewhat realistic training data for the AOT cache.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Integration tests that use &lt;code&gt;@QuarkusIntegrationTest&lt;/code&gt; make it very easy to run the target application as they use Dev Services.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;integration-with-the-build-system&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#integration-with-the-build-system&quot;&gt;&lt;/a&gt;Integration with the build system&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We wanted enabling Leyden in Quarkus to be a one-flag operation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Setting &lt;code&gt;quarkus.package.jar.aot.enabled=true&lt;/code&gt; is all it takes.
Quarkus automatically switches to the &lt;code&gt;aot-jar&lt;/code&gt; packaging and sets up the entire AOT pipeline.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With Maven, the full flow is a single command:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;./mvnw verify -Dquarkus.package.jar.aot.enabled=true -DskipITs=false&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This builds the application, runs integration tests with AOT training, and generates the &lt;code&gt;app.aot&lt;/code&gt; cache file in &lt;code&gt;target/quarkus-app/&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are using a project generated by our tooling, integration tests are disabled by default.
Adding &lt;code&gt;-DskipITs=false&lt;/code&gt; makes sure they will be run.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Running the application with the AOT cache is just as straightforward:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;cd target/quarkus-app
java -XX:AOTCache=app.aot -jar quarkus-run.jar&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We also integrated AOT with the container image extensions (Jib, Docker, and Podman).
When building a container image with AOT enabled, Quarkus:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Builds the application with &lt;code&gt;aot-jar&lt;/code&gt; packaging.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Creates a base container image.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Runs integration tests against the container to train the AOT cache.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Produces a final container image (with an &lt;code&gt;-aot&lt;/code&gt; suffix in its version) that includes the AOT cache and is pre-configured to use it at startup.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This end-to-end integration means going from source code to an AOT-optimized container image in a single command.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;some-numbers&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#some-numbers&quot;&gt;&lt;/a&gt;Some numbers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ve described the benefits of Project Leyden in theory, but how does it perform in practice?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To find out, we collected some numbers for two different Quarkus applications:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A simple REST application, the one you get when you run &lt;code&gt;quarkus create app&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A very large REST CRUD application: 1,000 entities, 1,000 repositories, 1,000 services, 1,000 REST endpoints&amp;#8230;&amp;#8203; &lt;code&gt;9,000&lt;/code&gt; .java files in total. This is an extreme case, don&amp;#8217;t try this at home!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The container image sizes were measured using our default images, which are based on Red Hat&amp;#8217;s UBI 9 Minimal and use JDK 25.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;raw-numbers&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#raw-numbers&quot;&gt;&lt;/a&gt;Raw numbers&lt;/h3&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These numbers were obtained using a full recording of all classes loaded during startup.
They were measured on our laptops rather than in an isolated lab environment.
We plan to run a more comprehensive set of benchmarks in our lab soon.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Your results may vary for several reasons:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Not all classes required at startup were recorded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your application performs actual work during startup, Leyden only optimizes class loading, not application logic.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In any case, if you see unexpected results, we&amp;#8217;re very interested in your feedback.
Please reach out to us, and we&amp;#8217;ll guide you on how to gather useful profiling information.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock tip&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-tip&quot; title=&quot;Tip&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;RSS is for Resident Set Size memory usage.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;small-rest-application&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#small-rest-application&quot;&gt;&lt;/a&gt;Small REST application&lt;/h4&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.0909%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.0909%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.091%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Startup time&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Container image size&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;RSS&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Default fast-jar&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;370 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;456 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;122 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Project Leyden and aot-jar&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;80 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-78%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;495 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;+9%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;103 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-16%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Mandrel native executable&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;17 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-95%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;155 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-66%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;37 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-70%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The AOT cache file is &lt;code&gt;39 MB&lt;/code&gt; in size,
the minimum you can expect for a Quarkus REST application.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;large-rest-crud-application&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#large-rest-crud-application&quot;&gt;&lt;/a&gt;Large REST CRUD application&lt;/h4&gt;
&lt;table class=&quot;tableblock frame-all grid-all stretch&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.0909%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.0909%;&quot;&gt;
&lt;col style=&quot;width: 18.1818%;&quot;&gt;
&lt;col style=&quot;width: 9.091%;&quot;&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Startup time&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Container image size&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;RSS&lt;/th&gt;
&lt;th class=&quot;tableblock halign-left valign-top&quot;&gt;Diff&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Default fast-jar&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;3,189 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;517 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;580 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;Reference&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Project Leyden and aot-jar&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;924 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-71%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;715 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;+38%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;580 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;0%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&quot;tableblock halign-left valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;strong&gt;Mandrel native executable&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;242 ms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-92%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;244 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-53%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;210 MB&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td class=&quot;tableblock halign-right valign-top&quot;&gt;&lt;p class=&quot;tableblock&quot;&gt;&lt;code&gt;-64%&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The AOT cache file is &lt;code&gt;198 MB&lt;/code&gt;, not surprising, given that the application contains 9,000 &lt;code&gt;.java&lt;/code&gt; files.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;startup-time&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#startup-time&quot;&gt;&lt;/a&gt;Startup time&lt;/h3&gt;
&lt;script src=&quot;/assets/javascript/chart.min.js&quot;&gt;&lt;/script&gt;
&lt;div class=&quot;chart-container&quot;&gt;
  &lt;canvas id=&quot;startup-time-graph&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
const startupTime = document.getElementById(&apos;startup-time-graph&apos;);
new Chart(startupTime, {
     type: &apos;bar&apos;,
     data: {
     labels: [&apos;Small REST app&apos;, &apos;Large REST CRUD app&apos;],
     datasets: [
     {
          label: &apos;Default&apos;,
          data: [370, 3189],
          backgroundColor: &apos;rgba(54, 162, 235, 0.7)&apos;,
          borderColor: &apos;rgba(54, 162, 235, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Project Leyden&apos;,
          data: [80, 924],
          backgroundColor: &apos;rgba(255, 206, 86, 0.7)&apos;,
          borderColor: &apos;rgba(255, 206, 86, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Native&apos;,
          data: [17, 242],
          backgroundColor: &apos;rgba(75, 192, 192, 0.7)&apos;,
          borderColor: &apos;rgba(75, 192, 192, 1)&apos;,
          borderWidth: 1
     }
     ]
     },
     options: {
     responsive: true,
     plugins: {
     title: {
          display: true,
          text: &apos;Startup time comparison&apos;
     },
     legend: {
          position: &apos;top&apos;,
     }
     },
     scales: {
     y: {
          beginAtZero: true,
          title: {
          display: true,
          text: &apos;Startup time (ms)&apos;
          }
     }
     }
     }
});
&lt;/script&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Startup time is greatly improved by Leyden, both for small and very large applications.
While it doesn&amp;#8217;t quite match the startup speed of a native executable, the results are still impressive.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s pause for a moment.
&lt;strong&gt;We were able to start a Quarkus REST application in the JVM in just &lt;code&gt;80 ms&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-2/quarkus-startup.png&quot; alt=&quot;Starting fast&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. Quarkus starting fast!&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Granted, it&amp;#8217;s a simple REST application with a single endpoint,
but it still relies on a full-featured REST implementation.
And it runs in the JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For very large applications, the results are just as impressive:
&lt;strong&gt;we were able to reduce startup time by &lt;code&gt;71%&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;container-image-size&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#container-image-size&quot;&gt;&lt;/a&gt;Container image size&lt;/h3&gt;
&lt;div class=&quot;chart-container&quot;&gt;
  &lt;canvas id=&quot;container-image-size-graph&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
const containerImageSize = document.getElementById(&apos;container-image-size-graph&apos;);
new Chart(containerImageSize, {
     type: &apos;bar&apos;,
     data: {
     labels: [&apos;Small REST app&apos;, &apos;Large REST CRUD app&apos;],
     datasets: [
     {
          label: &apos;Default&apos;,
          data: [456, 517],
          backgroundColor: &apos;rgba(54, 162, 235, 0.7)&apos;,
          borderColor: &apos;rgba(54, 162, 235, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Project Leyden&apos;,
          data: [495, 715],
          backgroundColor: &apos;rgba(255, 206, 86, 0.7)&apos;,
          borderColor: &apos;rgba(255, 206, 86, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Native&apos;,
          data: [155, 244],
          backgroundColor: &apos;rgba(75, 192, 192, 0.7)&apos;,
          borderColor: &apos;rgba(75, 192, 192, 1)&apos;,
          borderWidth: 1
     }
     ]
     },
     options: {
     responsive: true,
     plugins: {
     title: {
          display: true,
          text: &apos;Container image size comparison&apos;
     },
     legend: {
          position: &apos;top&apos;,
     }
     },
     scales: {
     y: {
          beginAtZero: true,
          title: {
          display: true,
          text: &apos;Container image size (MB)&apos;
          }
     }
     }
     }
});
&lt;/script&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It won&amp;#8217;t come as a surprise: you also need to include the AOT cache file in your container image, so Leyden increases the image size.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For a Quarkus REST application, the minimum is around &lt;code&gt;40 MB&lt;/code&gt;.
The cache size grows as your application becomes larger.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;On the other hand, going native significantly reduces the container image size, since you no longer need to include the full JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;memory-footprint&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#memory-footprint&quot;&gt;&lt;/a&gt;Memory footprint&lt;/h3&gt;
&lt;div class=&quot;chart-container&quot;&gt;
  &lt;canvas id=&quot;rss-graph&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;script&gt;
const rss = document.getElementById(&apos;rss-graph&apos;);
new Chart(rss, {
     type: &apos;bar&apos;,
     data: {
     labels: [&apos;Small REST app&apos;, &apos;Large REST CRUD app&apos;],
     datasets: [
     {
          label: &apos;Default&apos;,
          data: [122, 580],
          backgroundColor: &apos;rgba(54, 162, 235, 0.7)&apos;,
          borderColor: &apos;rgba(54, 162, 235, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Project Leyden&apos;,
          data: [103, 580],
          backgroundColor: &apos;rgba(255, 206, 86, 0.7)&apos;,
          borderColor: &apos;rgba(255, 206, 86, 1)&apos;,
          borderWidth: 1
     },
     {
          label: &apos;Native&apos;,
          data: [37, 210],
          backgroundColor: &apos;rgba(75, 192, 192, 0.7)&apos;,
          borderColor: &apos;rgba(75, 192, 192, 1)&apos;,
          borderWidth: 1
     }
     ]
     },
     options: {
     responsive: true,
     plugins: {
     title: {
          display: true,
          text: &apos;RSS comparison&apos;
     },
     legend: {
          position: &apos;top&apos;,
     }
     },
     scales: {
     y: {
          beginAtZero: true,
          title: {
          display: true,
          text: &apos;RSS (MB)&apos;
          }
     }
     }
     }
});
&lt;/script&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In terms of RSS, Project Leyden does not significantly change the picture,
while native executables offer a substantially lower memory footprint.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Reducing memory usage has not been a primary goal of Project Leyden so far,
though this may evolve in the future.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;lets-take-a-step-back&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#lets-take-a-step-back&quot;&gt;&lt;/a&gt;Let&amp;#8217;s take a step back&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At this point, you might be thinking: &quot;Why not just go native for everything?&quot;.
For all the reasons &lt;a href=&quot;#graalvm&quot;&gt;we&amp;#8217;ve outlined&lt;/a&gt;, use native when it makes sense for you.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There&amp;#8217;s also the question of throughput.
We haven&amp;#8217;t collected throughput numbers ourselves, as we didn&amp;#8217;t have the proper setup,
but some of our colleagues are running tests in an isolated environment,
and recently published &lt;a href=&quot;https://quarkus.io/blog/new-benchmarks/&quot;&gt;new benchmark results&lt;/a&gt;.
Native executables usually result in lower throughput,
at least with what is available as Open Source today in Mandrel and GraalVM CE.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is where Project Leyden really shines: you get significantly faster startup times compared to a regular JVM,
while still retaining all the benefits of running on the JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-next-for-leyden-in-quarkus&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-next-for-leyden-in-quarkus&quot;&gt;&lt;/a&gt;What&amp;#8217;s next for Leyden in Quarkus?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden is actively evolving, and we are closely tracking its developments,
in particular via the premain branch of the OpenJDK Leyden repository,
where experimental features are developed before being integrated into mainline JDK releases.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There are several areas where we expect things to improve:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Storage of JIT-compiled code in the AOT cache, which would further reduce warmup time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Potential support for custom class loaders, which would allow us to return to the more optimized &lt;code&gt;fast-jar&lt;/code&gt; packaging.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;On the Quarkus side, we are also working on:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Testing and validating on additional platforms, including Windows.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As Project Leyden matures, we will continue to integrate new features into Quarkus.
We are looking forward to what Java 27 and beyond will bring.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;After a month of experimenting and working on the integration of Project Leyden into Quarkus, we are very excited about the results and the potential of this technology.
And we are very happy we were able to integrate it into Quarkus 3.32 so that you can play with it already.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden is being continuously improved and is likely to figure prominently in the future of the Java platform.
As part of our quest in Quarkus to provide the best development platform, with the help of the OpenJDK team at IBM,
we are actively monitoring the progress made upstream (in the &lt;code&gt;premain&lt;/code&gt; branch of &lt;a href=&quot;https://github.com/openjdk/leyden/tree/premain&quot;&gt;&lt;code&gt;git@github.com:openjdk/leyden.git&lt;/code&gt;&lt;/a&gt;)
and plan to continue shaping the Quarkus + Leyden experience accordingly.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With AOT support, Quarkus expands its runtime flexibility: plain JVM, Leyden-optimized JVM, and native image.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Rather than replacing one another, these modes form a spectrum of trade-offs.
Native image remains unmatched for startup and minimal footprint.
Leyden strengthens the JVM startup story.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Which works best depends on your priorities, constraints, and application workload.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our commitment is unchanged: give developers the best option for their workload and keep improving each path.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/leyden-2/
            </guid>
            
            
            
            <author></author>
            
        </item>
        
        <item>
            <title>Quarkus has great performance – and we have new evidence</title>
            <link>
                https://quarkus.io/blog/new-benchmarks/
            </link>
            <description>
                &lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;tldr&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#tldr&quot;&gt;&lt;/a&gt;tl;dr&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Performance is important to Quarkus, but our published performance graphics were outdated and missing important information (such the fact that we have fantastic throughput).
To fix that, we built a new benchmark that is transparent, reproducible, and measures the full performance picture.
In our experiments, Quarkus can handle 2.7 times more transactions per second than Spring Boot, as well as starting 2.3 times faster, all in half the memory.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;the-start-of-the-story&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-start-of-the-story&quot;&gt;&lt;/a&gt;The start of the story&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you&amp;#8217;ve ever visited the &lt;a href=&quot;https://quarkusio&quot;&gt;quarkus.io&lt;/a&gt; site (and of course you have, because you&amp;#8217;re here), you&amp;#8217;ll probably have spotted the performance charts near the bottom of the front page.
The Quarkus team are proud of our performance, because good performance means high scalability, low latency, low resource usage, lower costs, and better sustainability. Basically, performance matters. This is what we used to show:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/new-benchmarks/old-benchmark-light.png&quot; alt=&quot;The previous performance graphic&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But despite the importance of performance, our performance charts had a few problems.
Firstly, the numbers are out of date. How out of date? Well, it&amp;#8217;s hard to say, because there&amp;#8217;s no date on the chart.
In fact, there&amp;#8217;s no information at all about how the numbers were measured, and no link to the benchmark source code. This means no one can reproduce it, which means no one can validate.
If it&amp;#8217;s not reproducible, it&amp;#8217;s not trustworthy.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Why didn&amp;#8217;t we just link to the benchmark source code?
Historically, we&amp;#8217;ve been deliberately vague about what we were comparing against (manners!). Sharing the source code would have made it totally obvious what the other framework was.
As well as preventing us from the sharing of the benchmark source, anonymizing the other framework had its own problems. Not sharing the framework name is polite, but it means we&amp;#8217;re not giving readers useful information to make an informed choice of framework.
Is Quarkus better? Oh yes, definitely. Better than what? Shhh, that&amp;#8217;s a secret.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But there&amp;#8217;s an even bigger problem with our old graphics, in my view. We show Quarkus starts fast, and we show it has a small footprint.
We do not show anything about throughput. There&amp;#8217;s a classic performance tradeoff between throughput and memory footprint or startup time.
It&amp;#8217;s easy for people looking at the charts to assume that if Quarkus doesn&amp;#8217;t show its throughput figures, they must be terrible, right?
Wrong! For Quarkus, &lt;em&gt;there is no trade-off&lt;/em&gt;. Quarkus is more efficient than alternatives across the board. (Want to know where a trade-off strikes back? &lt;a href=&quot;#native-tradeoffs&quot;&gt;Read on&lt;/a&gt;.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But this misconception that Quarkus must have bad throughput turns up all over the place.
It keeps popping up in external blogs, and if you ask your favourite AI service about the advantages of Quarkus, it&amp;#8217;s unlikely to mention throughput.
Instead, it will focus on startup time or memory. Those are important, but so is throughput.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There&amp;#8217;s another, more subtle, omission in our charts that also contributes to misunderstanding about Quarkus.
We show the performance of Quarkus in native mode, but we don&amp;#8217;t show the performance of the other framework in native mode.
Some people take this to mean that Quarkus is all about native mode, and if they&amp;#8217;re using Quarkus, they should be using native mode.
We often see blogs which compare Quarkus in native mode to other frameworks in JVM mode, which is just silly.
Quarkus in JVM mode should be compared to other frameworks in JVM mode, and Quarkus in native mode should be compared to other frameworks in native mode.
Quarkus happens to be very good at native mode, but whether you want to use native mode is an orthogonal choice to what framework you choose.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Because of all these problems, several members of the Quarkus community have ended up rolling their own benchmarks to use in conference talks, or for demos.
I&amp;#8217;ve done it myself, in fact. Having members of the same team re-doing similar work is wasteful. What&amp;#8217;s more, benchmarking is hard!
Getting numbers is trivially easy, but getting numbers which are actually measuring what you think you&amp;#8217;re measuring is hard.
Doing it really really right needs the sorts of skills performance specialists have.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;ok-so-we-definitely-needed-a-new-benchmark&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#ok-so-we-definitely-needed-a-new-benchmark&quot;&gt;&lt;/a&gt;Ok, so we definitely needed a new benchmark&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Something had to be done. Luckily, my colleague Eric Deandrea had been working on this exact problem for several years.
Eric had a benchmark, based on an earlier one from John O&amp;#8217;Hara, and he&amp;#8217;d built up a set of automations which allowed measurements to be run in our performance lab, under controlled conditions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Eric and I set up a &lt;a href=&quot;https://github.com/quarkusio/spring-quarkus-perf-comparison&quot;&gt;new repository&lt;/a&gt;, moved Eric&amp;#8217;s benchmark code into there, and refined the automations to push results out past the lab&amp;#8217;s firewall to &lt;a href=&quot;https://github.com/quarkusio/benchmarks&quot;&gt;another repository&lt;/a&gt;, acting as a data store. We got numbers, and (after a bit of work with &lt;a href=&quot;https://quarkus.io/extensions/io.quarkiverse.batik/quarkus-batik/&quot;&gt;Apache Batik&lt;/a&gt;), pictures!
Notice how great Quarkus&amp;#8217;s throughput is. Quarkus can handle 2.7 times (19255 vs 7238 tps) more transactions per second than Spring Boot, as well as starting 2.3 times (2.919s vs 6.569s) faster, all in half the memory (269 MB instead of 583 MB).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://quarkus.io/benchmarks/spring-quarkus-perf-comparison/2026-02-05_12-30-36/metrics-ootb-composite-for-main-comparison-dark.svg&quot; alt=&quot;A chart showing Quarkus throughput&quot; width=&quot;as compared to Spring Boot&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This was when the real work began.
With the benchmark now open sourced, it was open to scrutiny in a way it hadn&amp;#8217;t been before. (This, of course, is part of the magic of open source.)
Francesco Nigro, one of our Quarkus performance experts, spotted some areas where measurements could be made more robust.
For example, our setup used cgroups with cpuset to pin processes to specific CPU cores — which is the right approach — but both the application under test and the load generator ended up in the same cgroup, competing for those same cores. With the load generator configured to use 16 threads, this introduced significant noise in the measurements. Switching to &lt;a href=&quot;https://github.com/quarkusio/spring-quarkus-perf-comparison/issues/55&quot;&gt;separate core assignments&lt;/a&gt; fixed that, though other sources of interference remained, such as the database not having its own dedicated cores and a cache-drop step that was inadvertently affecting every process on the host.
Once proper isolation was in place, the throughput results shifted — and in a subtle way. Before the fix, slower frameworks appeared competitive because their lower load left more breathing room for the other processes. They were being flattered by the very contention they were causing less of. The chart above reflects the improved setup.
This is what I meant earlier about benchmarking requiring skill — these mistakes are easy to make and subtle to detect.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But the best help came from outside the Quarkus community. Our intention with the benchmark was to replicate the experience of a normal user, not to tune each framework to within an inch of its life. (There&amp;#8217;s &lt;a href=&quot;https://www.techempower.com/benchmarks/#section=data-r23&quot;&gt;TechEmpower&lt;/a&gt; for that.) Measuring the &quot;out of the box&quot; performance seemed like the best route, partly because the sort of performance most people will experience by default, and also because it was most fair. Fairness was a strong goal, because otherwise, what&amp;#8217;s the point in comparing? Our team have the skills to tune Quarkus applications to razor-sharp performance, but most of us don&amp;#8217;t have those same skills for Spring. It&amp;#8217;s just not in our job description. Tuning Quarkus but not Spring would clearly &lt;em&gt;not&lt;/em&gt; be fair.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But after we&amp;#8217;d started publishing the first set of results, we were approached by people who used Spring Boot every day. They &lt;a href=&quot;https://github.com/quarkusio/spring-quarkus-perf-comparison/issues/108&quot;&gt;pointed out that there were differences&lt;/a&gt; in how the two frameworks handled open-session-in-view settings, and connection pool sizes. These differences were significant enough that we started to evaluate whether comparing the out-of-the-box behaviour actually &lt;em&gt;was&lt;/em&gt; the fairest option. It turns out that open-session-in-view settings and fixing the N+1 problem didn&amp;#8217;t make much difference to the numbers, but adjusting connection pool sizes did.
In its default configuration, the Spring application was suffering from serious connection errors. If the client can&amp;#8217;t connect, there&amp;#8217;s no throughput, so the errors were lowering throughput. Eric, Francesco, and Sanne Grinovero spent a lot of time digging into the logs and profiling to work out configuration tweaks to ensure the Spring application could handle the load without errors.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our Spring friends told us that these sorts of adjustments would be completely standard. We still wanted to measure out of the box performance, so we settled on a compromise. We measured both out of the box, and a lightly tuned version. In the graphics we show on the front page, we&amp;#8217;re showing the tuned version. Here&amp;#8217;s the tuned equivalent of the out of the box results above, for the same code level and scripts:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://quarkus.io/benchmarks/spring-quarkus-perf-comparison/2026-02-16_17-11-38/metrics-tuned-composite-for-main-comparison-dark.svg&quot; alt=&quot;A chart showing Quarkus throughput&quot; width=&quot;time to first response&quot; height=&quot;and memory footprint&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can see that the effect of the tuning was pretty modest, overall. Notice, as well, that there was a bit of a trade-off between throughput and memory footprint; for both frameworks, the tuning optimisations ended up sacrificing some memory to improve speed.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;guiding-principles&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#guiding-principles&quot;&gt;&lt;/a&gt;Guiding principles&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In trying to decide how to handle the question of tuning, we ended up referring back to the guiding principles for the whole exercise. They were:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;parity&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#parity&quot;&gt;&lt;/a&gt;Parity&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The application code in the Spring and Quarkus versions of the application should be as equivalent as possible to perform the same function. This means the domain models should be identical, and the underlying persistence mechanisms should be identical (in our case, JPA with Hibernate).
Performance differences should come from architecture differences and library-integration optimisations in the frameworks themselves.
If a change is made that changes the architecture of an application (i.e. moving blocking to reactive, using virtual threads, etc), then these changes should be applied to all the versions of the applications.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;normal-ness&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#normal-ness&quot;&gt;&lt;/a&gt;Normal-ness&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Realism is more important than squeezing out every last bit of performance.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;high-quality&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#high-quality&quot;&gt;&lt;/a&gt;High quality&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Applications should model best practices.
Although we want the application to represent a typical usage, someone who copies it shouldn&amp;#8217;t ever be copying &apos;wrong&apos; or bad code.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;testing-the-framework-not-the-infrastructure&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#testing-the-framework-not-the-infrastructure&quot;&gt;&lt;/a&gt;Testing the framework, not the infrastructure&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Measurements should be measuring the performance of the frameworks, rather than supporting infrastructure like the database. In practice this means we want the experimental setup to be CPU-bound.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;exploring-our-performance&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#exploring-our-performance&quot;&gt;&lt;/a&gt;Exploring our performance&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One of the nice things about this work is that it&amp;#8217;s allowed us to explore various performance-related questions, beyond just &quot;does Quarkus have awesome performance?&quot; For example, would running with virtual threads affect the results? Yes! Virtual threads added about 6k transactions per second, for all frameworks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://quarkus.io/benchmarks/spring-quarkus-perf-comparison/2026-02-16_17-11-38/metrics-tuned-throughput-for-virtual-threads-dark.svg&quot; alt=&quot;A chart showing Quarkus throughput with and without virtual threads&quot; width=&quot;as compared to Spring Boot&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And we had more questions, too. Was there a performance difference between Spring Boot 3 and Spring Boot 4? It turns out things got better in some ways, and worse in others. Spring 4 gives higher throughput than Spring 3, but at the expense of a slower time to first response, and a higher memory footprint.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;https://quarkus.io/benchmarks/spring-quarkus-perf-comparison/2026-02-16_17-11-38/metrics-tuned-composite-for-java-and-native-frameworks-dark.svg&quot; alt=&quot;A chart showing Quarkus throughput&quot; width=&quot;as compared to Spring Boot 3 and 4&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;What would Quarkus&apos; new &lt;a href=&quot;/guides/aot&quot;&gt;AOT packaging&lt;/a&gt; do for startup times? (We&amp;#8217;re still working on that one, but I&amp;#8217;m excited to see the answer.)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;native-tradeoffs&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#native-tradeoffs&quot;&gt;&lt;/a&gt;The throughput vs startup tradeoff, revisited&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I mentioned that with Quarkus, there was no trade-off between startup time and performance. When compared to other frameworks, this is definitely true. The internal efficiencies of Quarkus, like the build-time principle, improve both startup time &lt;em&gt;and&lt;/em&gt; throughput. But if you compare Quarkus on JVM against Quarkus native, the trade-off is back! When using GraalVM to compile Quarkus applications to native, Quarkus starts faster than a lightbulb, and has a pretty small memory footprint. But there &lt;em&gt;is&lt;/em&gt; a throughput penalty. Going native cuts throughput in half. (For Spring Boot, the native penalty is similar.) For most applications, this trade-off isn&amp;#8217;t worth it, especially when combined with the longer build times and extra constraints of native. But sometimes, the trade-off is worth it: if your application gets started and stopped super-often or has very low workloads, use native.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;want-to-try-the-benchmarks-at-home&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#want-to-try-the-benchmarks-at-home&quot;&gt;&lt;/a&gt;Want to try the benchmarks at home?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can! All of the source code and scripts are available at &lt;a href=&quot;https://github.com/quarkusio/spring-quarkus-perf-comparison&quot; class=&quot;bare&quot;&gt;https://github.com/quarkusio/spring-quarkus-perf-comparison&lt;/a&gt;.
Easy reproducibility for everyone was an important guiding principle when we designed the benchmark, but it does get kind of complicated. In the performance world, &quot;rigorous&quot; and &quot;easy&quot; do not go in the same sentence. As someone who always wants to make hard things accessible, this &lt;em&gt;really&lt;/em&gt; frustrates me. In the end, we&amp;#8217;ve ended up with a compromise. If you happen to have a performance lab handy, this is of course ideal. All of the scripts are available for you to run the jobs on your own hardware. If you don&amp;#8217;t have that kind of setup, but do have a Linux machine, you can still use the expert-approved scripts we use. Under the covers, they use tools like &lt;a href=&quot;https://github.com/Hyperfoil/qDup&quot;&gt;qDup&lt;/a&gt; for orchestration and &lt;a href=&quot;https://hyperfoil.io/&quot;&gt;Hyperfoil&lt;/a&gt; to drive load without risking coordinated omission, and ensure process isolation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But what if you want something &lt;em&gt;really&lt;/em&gt; easy? At this point, things get harder. We created a second version of the scripts which are optimised for simplicity. They use only familiar tools, and don&amp;#8217;t attempt process isolation. Because of this, they can be run on both Mac and Linux, and, with the right terminal, Windows. The results need to be treated with caution; laptop power management can cause all sorts of wild effects, and if the load is too much or too little, you might end up measuring a bottleneck which has nothing to do with Quarkus or Spring. We&amp;#8217;re planning another blog (or six!) on how to avoid the most common problems, and how to tell if you&amp;#8217;re measuring what you think you are.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 02 Mar 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/new-benchmarks/
            </guid>
            
            
            
            <author>Holly Cummins (https://twitter.com/holly_cummins)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.32 - Project Leyden integration, more graceful shutdown, automatic Consul registration and more!</title>
            <link>
                https://quarkus.io/blog/quarkus-3-32-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;re pleased to announce the release of Quarkus 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is an important milestone: 3.32 marks the feature freeze for our next LTS release, Quarkus 3.33 LTS.
The upcoming LTS will be branched from the 3.32 line, making this release the foundation on which 3.33 LTS will be built.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.32 also delivers several significant improvements and new features:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52376&quot;&gt;#52376&lt;/a&gt; and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52224&quot;&gt;#52224&lt;/a&gt; - Project Leyden integration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50975&quot;&gt;#50975&lt;/a&gt; - Rework graceful shutdown to be more graceful with respect to HTTP&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/47997&quot;&gt;#47997&lt;/a&gt; - Automatic Consul Registration for Quarkus Applications&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52090&quot;&gt;#52090&lt;/a&gt; - OIDC: Support for custom DPoP nonce providers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52353&quot;&gt;#52353&lt;/a&gt; - OIDC: Add basic support for rich authorization requests&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52175&quot;&gt;#52175&lt;/a&gt; - Make built-in authentication mechanism order customizable&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52537&quot;&gt;#52537&lt;/a&gt; - Introduce OIDC AuthenticationCompletionAction&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52380&quot;&gt;#52380&lt;/a&gt; - Upgrade to Google Cloud Function framework 2.0&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We strongly recommend upgrading to 3.32 soon so we can gather feedback and ensure the upcoming 3.33 LTS is as solid as possible.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are currently running 3.27 LTS, now is the right time to validate your upgrade path to 3.33 LTS, and let us know if you encounter any issues.
Your feedback at this stage is especially valuable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.32, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.32.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.32&quot;&gt;Quarkus 3.32 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-new&quot;&gt;&lt;/a&gt;What&amp;#8217;s new?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;project-leyden-integration&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#project-leyden-integration&quot;&gt;&lt;/a&gt;Project Leyden integration&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden brings Ahead-of-Time (AOT) compilation to the JVM.
By recording class loading, class linking, and method profiling during a training run, you can generate an AOT cache file that the JVM can use for subsequent runs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The result is a significant improvement in JVM startup time, with very few constraints or drawbacks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Project Leyden is available starting with OpenJDK 25 (counting only LTS releases).
We&amp;#8217;ll explore it in detail in a dedicated blog post very soon.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus, we&amp;#8217;ve integrated Project Leyden AOT so that:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The training run can be triggered either at build time (minimal training) or through your integration tests.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The generated AOT cache file can be included directly in your container image.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While the improvements aren&amp;#8217;t quite as substantial as with native executables,
and the container image size is a bit larger due to the AOT cache file,
the results are impressive given the minimal effort required:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A minimal REST application created with quarkus create app sees startup drop from &lt;strong&gt;370 ms&lt;/strong&gt; to &lt;strong&gt;80 ms&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A large REST CRUD application with 9,000 classes goes from &lt;strong&gt;3 seconds&lt;/strong&gt; to &lt;strong&gt;900 ms&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can learn more in the &lt;a href=&quot;https://quarkus.io/guides/aot&quot;&gt;Quarkus AOT guide&lt;/a&gt;, and we&amp;#8217;ll share a detailed walkthrough in the upcoming blog post.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;graceful-shutdown&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#graceful-shutdown&quot;&gt;&lt;/a&gt;Graceful shutdown&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Several improvements were made to our HTTP graceful shutdown, thanks to some work from the Keycloak team.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;stork&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#stork&quot;&gt;&lt;/a&gt;Stork&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus applications can now automatically register to Consul, using the Stork extension.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This new feature is explained in detail in the &lt;a href=&quot;https://quarkus.io/guides/stork-registration&quot;&gt;Automatic service registration with SmallRye Stork for Quarkus&lt;/a&gt; guide.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;security&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#security&quot;&gt;&lt;/a&gt;Segurança&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As usual, this version comes with new security features and enhancements:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52090&quot;&gt;#52090&lt;/a&gt; - OIDC: Support for custom DPoP nonce providers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52353&quot;&gt;#52353&lt;/a&gt; - OIDC: Add basic support for rich authorization requests&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52175&quot;&gt;#52175&lt;/a&gt; - Make built-in authentication mechanism order customizable&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/52537&quot;&gt;#52537&lt;/a&gt; - Introduce OIDC AuthenticationCompletionAction&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;google-cloud-function&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#google-cloud-function&quot;&gt;&lt;/a&gt;Google Cloud Function&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Google Cloud Function framework has been updated to 2.0.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;platform-updates&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#platform-updates&quot;&gt;&lt;/a&gt;Platform updates&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We updated Camel Quarkus to Camel Quarkus 3.32.
For more information, see the &lt;a href=&quot;https://camel.apache.org/blog/2026/02/camel-quarkus-3.32.0/&quot;&gt;announcement&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus CXF was also updated to 3.32.
Since we forgot to include the 3.31.1 release notes in previous Quarkus announcements, you can now read both sets of notes:
&lt;a href=&quot;https://docs.quarkiverse.io/quarkus-cxf/dev/release-notes/3.31.1.html&quot;&gt;3.31.1&lt;/a&gt; and
&lt;a href=&quot;https://docs.quarkiverse.io/quarkus-cxf/dev/release-notes/3.32.0.html&quot;&gt;3.32.0&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.32.0.CR1&quot;&gt;3.32.0.CR1&lt;/a&gt;, &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.32.0&quot;&gt;3.32.0&lt;/a&gt;, and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.32.1&quot;&gt;3.32.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1163 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.32 release, thanks to Ales Justin, Alexander Schwartz, Alexandre Dutra, Alexey Loubyansky, andreatp, Asger Askov Blekinge, Aurea Munoz, Aurélien Pupier, azerr, Bruno Baptista, Carles Arnal, cfitzw, Chris Laprun, Clement Escoffier, Daniel Vergien, David M. Lloyd, Dennis Kniep, Erwin Oegema, Foivos Zakkak, Fouad Almalki, Frank Eichfelder, George Gastaldi, Georgios Andrianakis, Guillaume Smet, Holly Cummins, Jakub Jedlicka, James Netherton, Jerome Prinet, Jiri Ondrusek, jtama, Julien Ponge, Karm Michal Babacek, Katia Aresti, Kristian Rickert, Ladislav Thon, lberrymage, lloydmeta, Loïc Mathieu, Marc Nuri, Marco Belladelli, marco sappe griot, mariofusco, marko-bekhta, Martin Kouba, Martin Panzer, Matej Novotny, Matheus Cruz, melloware, Michael Edgar, Michal Vavřík, Nejc Tomažič, Nicola Concetti, Olivier V, osoohynn, Ozan Gunalp, Patrick Schaub, Peter Levart, Peter Palaga, Phillip Krüger, Robert Stupp, Robert Toyonaga, Roberto Cortez, Sanne Grinovero, Sergey Beryozkin, shjones, sNiXx, Steve Hawkins, Stéphane Épardaud, Teymur Babayev, Victor Dalosto, Vincent Sevel, vincent-duluth, xstefank, and Yoann Rodière.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 26 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-32-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>How Project Leyden brought a new perspective</title>
            <link>
                https://quarkus.io/blog/leyden-1/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is a story about Project Leyden.
And this is not a story about Project Leyden.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is a story about how Project Leyden gave us a new perspective on how we think about startup performance in Quarkus, and, more broadly, in Java.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is a story with flamegraphs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;quoteblock&quot;&gt;
&lt;blockquote&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Isn&amp;#8217;t it the best kind of story?&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;acknowledgments&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#acknowledgments&quot;&gt;&lt;/a&gt;Acknowledgments&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I shared this journey with my dear colleague Georgios Andrianakis, who was also instrumental in making this happen.
And this is exactly the kind of journey you want to share with someone.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-the-story-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-the-story-started&quot;&gt;&lt;/a&gt;How the story started&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It all started with me complaining, more than once, that improving startup performance in Quarkus had become really hard.
Startup was cluttered with class loading noise.
Which means that every time you looked at a startup profile, you clicked on something suspicious and realized:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;quoteblock&quot;&gt;
&lt;blockquote&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Oh well, that&amp;#8217;s just us loading a class for the first time&amp;#8230;&amp;#8203; bummer.&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I&amp;#8217;m a patient person.
But you only get so many mouse clicks per day.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Then, one day, I took a shower, and I had this idea:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;quoteblock&quot;&gt;
&lt;blockquote&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Isn&amp;#8217;t Project Leyden supposed to improve the class loading story, among other things?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Maybe we could use it to get rid of the class loading noise and get a clearer picture of what&amp;#8217;s really going on during startup?&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As it turns out, this was a bit of a rabbit hole.
Project Leyden delivered results that were far better than expected, and we ended up working with Georgios on integrating it tightly in Quarkus
(you can see another blog post coming, right?).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But today, I promised you flamegraphs. I know you&amp;#8217;re all excited about them.
Let&amp;#8217;s get to it!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;changing-the-perspective&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#changing-the-perspective&quot;&gt;&lt;/a&gt;Changing the perspective&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ll explore this in more detail in a future blog post, but for now, suffice it to say that Project Leyden caches classes in a loaded and linked state, along with additional metadata such as method profiling information and, soon, compiled code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In practice, Project Leyden improves Java startup performance by shifting expensive work, like class loading and linking, into a dedicated training phase.
By capturing that state ahead of time, the application can skip much of the redundant setup normally performed at runtime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In other words, if everything is recorded properly, class loading can be almost entirely taken out of the startup path.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And suddenly, you&amp;#8217;re in brand-new territory: the Quarkus REST application you get from a simple &lt;code&gt;quarkus create app&lt;/code&gt; starts in 130 milliseconds.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That&amp;#8217;s already pretty good, right? But what&amp;#8217;s even more interesting is that we were able to do much better (see you in the next blog post, remember?).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And this is where the perspective shifts significantly: when you start in ~ 100 milliseconds, every dozen milliseconds you save becomes a meaningful improvement.
You can no longer afford to ignore a 5-millisecond cost.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I can hear someone in the room shouting:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;quoteblock&quot;&gt;
&lt;blockquote&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Stop with the words! I want my flamegraphs!&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Fine, fine.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-can-we-improve-as-an-ecosystem&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-can-we-improve-as-an-ecosystem&quot;&gt;&lt;/a&gt;How can we improve as an ecosystem?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One extremely important note before we begin: &lt;strong&gt;we&amp;#8217;re not trying to criticize any library or framework here&lt;/strong&gt;.
We also found some low-hanging fruits in Quarkus itself, &lt;strong&gt;we&amp;#8217;re all in the same boat here&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The goal of this blog post is to show how Project Leyden helped us uncover things that had been hidden for far too long.
And hopefully, this will give other library and framework authors a few useful ideas, and ultimately help improve the Java ecosystem as a whole.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And in the worst case, at least you got your flamegraphs \o/.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;compatibility-layers&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#compatibility-layers&quot;&gt;&lt;/a&gt;Compatibility layers&lt;/h3&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-compatibility-layer.png&quot; alt=&quot;Netty trying to determine whether virtual threads are available&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. Netty trying to determine whether virtual threads are available&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Many libraries include compatibility layers to support multiple JDK versions.
Typically, they rely on reflection to determine whether features like virtual threads are available.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the Quarkus ecosystem, this is common in low-level libraries such as Netty or Vert.x.
But in reality, we see this pattern everywhere.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We should avoid this. It has a cost, and that cost is paid at &lt;strong&gt;every single&lt;/strong&gt; startup of every application using these libraries.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Multi-release JARs are not perfect.
They&amp;#8217;re harder to maintain, harder to test, and not always well supported by IDEs.
But they do solve this problem.
And I would argue that, as library and framework authors, it&amp;#8217;s our responsibility to ensure the cost is paid once at build time, not at every application startup.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Together with Georgios, we decided to experiment with rewriting the bytecode of some of these libraries at build time to remove the reflective calls and replace them with direct invocations,
when the application was targeting a Java version that supports the feature.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s a bit of a hack, and definitely not something we want to maintain long term, but it was a great way to validate the idea and score a few quick wins.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;reading-annotations&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#reading-annotations&quot;&gt;&lt;/a&gt;Reading annotations&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This one isn&amp;#8217;t new to us: one of the reasons we wrote Quarkus in the first place was to avoid reading annotations at runtime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For most of our use cases, we can process annotations at build time and generate the necessary bytecode so there&amp;#8217;s no need to inspect them at runtime.
Jandex, our annotation indexer, is a fantastic tool for this, and we use it extensively in Quarkus.
But&amp;#8230;&amp;#8203; there are still cases where annotations are read at runtime, even in Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Why is reading annotations so costly?
Because parsing them has a cost. It happens the first time you try to access them at runtime, and the JDK then creates proxy instances to expose the annotation values.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;netty-and-marker-annotations&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#netty-and-marker-annotations&quot;&gt;&lt;/a&gt;Netty and marker annotations&lt;/h4&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-marker-annotation.png&quot; alt=&quot;Netty trying to determine if a ChannelHandler is sharable&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. Netty trying to determine if a &lt;code&gt;ChannelHandler&lt;/code&gt; is sharable&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Netty case is particularly interesting because it reads annotations to determine the capabilities of interface implementations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For this kind of use case, we recommend using marker interfaces or methods instead of annotations.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Georgios once again resorted to bytecode rewriting to eliminate the annotation lookup.
Again, this isn&amp;#8217;t something we want to maintain in the long term.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;hibernate-orm&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#hibernate-orm&quot;&gt;&lt;/a&gt;Hibernate ORM&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Hibernate ORM is also extremely interesting in this context.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The first important point is that, with Hibernate ORM, in Quarkus, we still build the metadata at runtime.
That means we end up reading a lot of annotations at runtime.
A long-term effort has already started to improve this situation,
but it&amp;#8217;s a significant undertaking and will take time before we can move metadata building to build time instead.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s set that aside for now.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;What&amp;#8217;s also interesting is that Hibernate ORM collects metadata about its own annotations at runtime, both Hibernate-specific annotations and JPA annotations.
And that&amp;#8217;s a lot of annotations, and a lot of metadata to process.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-hibernate-annotations.png&quot; alt=&quot;Hibernate ORM collecting metadata about its own annotations&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 3. Hibernate ORM collecting metadata about its own annotations&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example, for each JPA or Hibernate annotation, it determines the annotation target (class, method, field), or whether it is inherited.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the end, this results in a substantial amount of annotation processing for something that changes very rarely.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I identified this issue some time ago, and our colleague Luca Molteni from the Hibernate team will be looking into it soon.
We&amp;#8217;re not yet sure how easy it will be to fix, but you get the idea.
Whenever possible, this kind of metadata should be resolved once and for all.
And you should be able to enforce its correctness with tests to ensure it remains accurate and up to date.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Hopefully, we&amp;#8217;ll be able to improve this soon.
And the nice part is that any improvement here will benefit all applications using Hibernate ORM, not just Quarkus applications.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;the-new-cost-of-loading&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-new-cost-of-loading&quot;&gt;&lt;/a&gt;The new cost of loading&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When not using Leyden, you load a gazillion classes.
JAR files are opened anyway, that&amp;#8217;s &lt;em&gt;&quot;fine&quot;&lt;/em&gt;.
Well, depending on your definition of &lt;em&gt;&quot;fine&quot;&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When using Leyden, you can reach a point where no classes are loaded at startup at all.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Which means that anything attempting to load something from the classpath will trigger JAR files to be opened (the first time they are accessed), and then read from disk.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And you can be sure that some resources will be loaded from your classpath:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ServiceLoader&lt;/code&gt; service files (the ones in &lt;code&gt;META-INF/services/&lt;/code&gt;), used by the JDK and many libraries and frameworks to discover interface implementations;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Configuration files;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And probably many other things.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;non-existing-classes-and-resources&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#non-existing-classes-and-resources&quot;&gt;&lt;/a&gt;Non-existing classes and resources&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Why would you try to load a non-existing class?
That&amp;#8217;s a good question.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-packageinfo.png&quot; alt=&quot;Hibernate ORM trying to load non-existing package-info&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 4. Hibernate ORM trying to load non-existing &lt;code&gt;package-info&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Remember &lt;code&gt;package-info.java&lt;/code&gt; files?
Hibernate ORM, for instance, tries to load them to inspect package-level annotations.
In a lot of cases, these files don&amp;#8217;t exist, and that&amp;#8217;s perfectly normal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Caching class loading is within the scope of Leyden, but Leyden does not cache negative lookups.
Why? Because Leyden, while AOT, is still true Java.
Java is a dynamic language:
even if a class wasn&amp;#8217;t present when you recorded the cache, it might be added later.
Now, in practice, that&amp;#8217;s often not the case, especially in Quarkus, where we assume a closed world, but Leyden cannot rely on that assumption.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus, when using Leyden, we decided to generate empty &lt;code&gt;package-info&lt;/code&gt; classes for all packages containing entities that don&amp;#8217;t already have one.
This way, Hibernate ORM doesn&amp;#8217;t have to attempt to load non-existing classes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-non-existing-class.png&quot; alt=&quot;JBoss Logging loading a non-existing class&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 5. JBoss Logging loading a non-existing class&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Another example is JBoss Logging internationalization: it attempts to load a class for the current locale, and if that class doesn&amp;#8217;t exist, it falls back to the default class.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You see similar patterns with resources.
An application might try to load a configuration file or a service descriptor that doesn&amp;#8217;t exist. That&amp;#8217;s perfectly normal, the only way to know it&amp;#8217;s missing is to try.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus, we have a few class loader tricks to mitigate this.
But in the general case, you have to deal with it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And here&amp;#8217;s the catch: for all these cases, the runtime will walk the entire classpath (remember, it won&amp;#8217;t find anything), trying to locate the class or resource.
In doing so, it may open a large number of JAR files and read from them, just to conclude that the class or resource doesn&amp;#8217;t exist.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Granted, it doesn&amp;#8217;t read the entire JAR, each archive has an index, but still.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;serviceloader&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#serviceloader&quot;&gt;&lt;/a&gt;ServiceLoader&lt;/h4&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-serviceloader-storm.png&quot; alt=&quot;A ServiceLoader storm&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 6. A &lt;code&gt;ServiceLoader&lt;/code&gt; storm&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s look at the &lt;code&gt;ServiceLoader&lt;/code&gt; case in more detail, it&amp;#8217;s particularly interesting.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once class loading is out of the picture, it becomes clear that a significant portion of startup time is spent loading service descriptors from JAR files.
We managed to improve this for some services using a class loader trick, but that only works for services loaded through the thread context class loader.
We don&amp;#8217;t yet have a good solution for services loaded by the JDK class loaders.
At least not for now.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ll go into more detail in the next blog post, where we&amp;#8217;ll talk more about Project Leyden itself and how we integrated it into Quarkus.
Stay tuned.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;some-other-fun-facts&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#some-other-fun-facts&quot;&gt;&lt;/a&gt;Some other &lt;em&gt;fun&lt;/em&gt; facts&lt;/h3&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;uuid-generation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#uuid-generation&quot;&gt;&lt;/a&gt;UUID generation&lt;/h4&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-uuid.png&quot; alt=&quot;Generating a UUID for the first time&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 7. Generating a UUID for the first time&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This one is easy: whenever you generate a &lt;code&gt;UUID&lt;/code&gt;, the JDK will initialize a &lt;code&gt;SecureRandom&lt;/code&gt; instance.
And initializing a &lt;code&gt;SecureRandom&lt;/code&gt; instance doesn&amp;#8217;t come for free, oh no.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Sure, if your application ends up needing a &lt;code&gt;SecureRandom&lt;/code&gt; anyway, you don&amp;#8217;t care.
But if it doesn&amp;#8217;t, having your favorite framework generate &lt;code&gt;UUID&lt;/code&gt;s for internal use is not ideal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Obviously, if your application genuinely needs &lt;code&gt;UUID&lt;/code&gt; generation, go ahead and use it.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;bigdecimal&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#bigdecimal&quot;&gt;&lt;/a&gt;BigDecimal&lt;/h4&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-bigdecimal.png&quot; alt=&quot;Initialization of BigDecimal&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 8. Initialization of &lt;code&gt;BigDecimal&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the same vein, the &lt;code&gt;BigDecimal&lt;/code&gt; class has a static initializer that actually performs a fair amount of work.
Initializing &lt;code&gt;BigDecimal&lt;/code&gt; can take a noticeable amount of time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We stumbled upon this because we were using &lt;code&gt;BigDecimal&lt;/code&gt; to perform some calculations when printing the Quarkus startup time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;D&amp;#8217;oh.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We replaced that code, only to discover another issue:
&lt;code&gt;BigDecimal&lt;/code&gt; was also being eagerly initialized in Hibernate ORM for a very narrow use case in the &lt;code&gt;DurationJavaType&lt;/code&gt; class.
That has since been fixed as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Just like with &lt;code&gt;UUID&lt;/code&gt;s, if your application genuinely needs &lt;code&gt;BigDecimal&lt;/code&gt;, you should use it and pay the cost.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is about avoiding the cost when you don&amp;#8217;t actually need it.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;time-zones&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#time-zones&quot;&gt;&lt;/a&gt;Time zones&lt;/h4&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-timezone.png&quot; alt=&quot;Loading the time zone database&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 9. Loading the time zone database&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We all know time zones are hard.
But now we also know that loading them is slow.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The time zone database is quite large, and loading it, for example when calling &lt;code&gt;TimeZone.getDefault()&lt;/code&gt;, can take a noticeable amount of time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Who would need a time zone in a server application, right?
For instance, your logging layer, which wants to print timestamps in the local time zone.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/leyden-1/flamegraph-zoneid.png&quot; alt=&quot;Loading the zone rules&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 10. Loading the zone rules&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And what&amp;#8217;s also interesting is that there&amp;#8217;s an additional cost for transforming the time zone to a &lt;code&gt;ZoneId&lt;/code&gt;, as you also have to load the zone rules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These two issues still exist and I have no idea if we can even solve them,
but we were able to mitigate their cost somewhat in Quarkus when using the specific packaging we developed for AOT.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This post is about the work we did in Quarkus and the libraries Quarkus relies on.
But I would argue that the lessons we learned are applicable across the entire Java ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I hope that by sharing our experience, we can inspire other projects, especially library and framework authors, to take a similar approach and improve their startup performance.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And to be honest, this isn&amp;#8217;t just about improving startup performance, it&amp;#8217;s also about reducing the resources wasted during startup.
We often talk about Green IT; let&amp;#8217;s make our libraries and frameworks greener, especially in cases where it&amp;#8217;s simple to achieve.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ve shared some of our findings and recipes, but I&amp;#8217;m sure there are others that are specific to each library and framework.
Now is a great time to look at your own startup profiles and see if you can spot some low-hanging fruit to boost performance.
And with Quarkus 3.32 and our new AOT integration coming soon, this is going to be easier than ever.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you have questions, you know &lt;a href=&quot;https://quarkusio.zulipchat.com/#narrow/channel/187038-dev&quot;&gt;where to find us&lt;/a&gt;, and if you find something interesting, please share it with us, we&amp;#8217;d love to hear about it!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Onwards!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/leyden-1/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>A Go CEL Policy Engine in Java, with Quarkus Chicory</title>
            <link>
                https://quarkus.io/blog/k8s-style-CEL-with-quarkus-chicory/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A few days ago, we released the &lt;a href=&quot;https://github.com/quarkiverse/quarkus-chicory/releases/tag/0.0.1&quot;&gt;first version
of Quarkus Chicory&lt;/a&gt;, an extension that brings the power of the
&lt;a href=&quot;https://github.com/dylibso/chicory&quot;&gt;Chicory WebAssembly runtime&lt;/a&gt; to Quarkus applications.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;While iterating on development, we felt the need to implement an integration test based on a real world use case.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;After some research and experiments on popular scenarios we finally landed on a tasty one :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;a-kubernetes-style-cel-policy-engine&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#a-kubernetes-style-cel-policy-engine&quot;&gt;&lt;/a&gt;A Kubernetes-style CEL Policy Engine&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;CEL allows expression based policy validation of Kubernetes resources, and this requirement is implemented by
operators&amp;#8230;&amp;#8203; which are &lt;em&gt;generally&lt;/em&gt; written in Go :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But Quarkus Java based operators exist too - like the Keycloak operator - so what?
Are we forced to implement a CEL policy validation engine in Java, from scratch?
Or should we find a suitable Java library, for example &lt;a href=&quot;https://github.com/projectnessie/cel-java&quot; class=&quot;bare&quot;&gt;https://github.com/projectnessie/cel-java&lt;/a&gt;?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;None of the above: this is where Chicory, a WebAssembly runtime for Java, comes to help.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s just re-use a broadly used and well tested Go library, calling exported functions from Java, in a sandboxed,
secure way, and be happy with it!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;no rewrites&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;low maintenance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1:1 behavior&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;a-chicory-extension-for-quarkus-applications&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#a-chicory-extension-for-quarkus-applications&quot;&gt;&lt;/a&gt;A Chicory extension for Quarkus applications&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Chicory is an open-source, 100% native Java WebAssembly (Wasm) runtime.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Its primary goal is to allow Java developers to run Wasm modules within the JVM,
without relying on native libraries, JNI (Java Native Interface) usage, or unsafe code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Unlike other Wasm runtimes that require platform-specific binaries, Chicory is pure Java.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It executes Wasm code within the JVM&amp;#8217;s memory space, providing a &quot;double sandbox&quot; effect (Wasm isolation + JVM
security).
It also provides WASI (WebAssembly System Interface) support, that allows Wasm modules to interact with system
resources safely.
Finally, it includes both an &lt;em&gt;interpreter&lt;/em&gt; and a &lt;em&gt;runtime compiler&lt;/em&gt; for quick execution, in addition to a &lt;em&gt;build-time
compiler&lt;/em&gt; that converts Wasm into Java bytecode for optimal performance, see
&lt;a href=&quot;https://chicory.dev/docs/usage/execution_modes/&quot;&gt;Chicory execution modes&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is ideal for plugin systems, allowing users to write safe plugins in any language (Rust, C++, Go, etc.) that compiles
to Wasm, and running them inside a Java app.
It can be used for Serverless/Edge Computing cases, as it provides a mean to run lightweight logic on Java-based
infrastructure without the overhead of application containers.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And for something that never gets old, i.e. cross-platform portability, your application remains &lt;em&gt;&quot;Write Once, Run
Anywhere&quot;&lt;/em&gt;, without managing different &lt;code&gt;.so&lt;/code&gt; or &lt;code&gt;.dll&lt;/code&gt; files for different architectures.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can learn more about &lt;a href=&quot;https://chicory.dev/docs/&quot;&gt;Chicory&lt;/a&gt;, but from now on let&amp;#8217;s focus on its Quarkus
extension, here. :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;Quarkus Chicory brings Chicory to Quarkus application developers, integrating its features into the
Quarkus ecosystem and applications build-time and runtime peculiarities, for a natural developer experience.
It just&amp;#8230;&amp;#8203; works!&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;features&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#features&quot;&gt;&lt;/a&gt;Características&lt;/h3&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Build-Time Code Generation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Generates Java bytecode from WebAssembly modules, thus replacing the Chicory Maven plugin.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dependency Management&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Automatically handles version alignment between Quarkus and Chicory’s ASM dependencies.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Multi WASM Module Support&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Configure and manage multiple WebAssembly modules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dynamic Loading&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Manage runtime-loaded WASM modules.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Intelligent Execution Mode Selection&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Configures the &lt;code&gt;MachineFactory&lt;/code&gt; and &lt;code&gt;WasmModule&lt;/code&gt; instances based on the environment.
&lt;code&gt;MachineFactory&lt;/code&gt; can leverage build-time generated bytecode for optimal performance in production/native,
and use runtime or interpreter mode during development or test.
Similarly, &lt;code&gt;WasmModule&lt;/code&gt; instances can be initialized with WASM metadata rather than pure WASM payload,
again for better performance and memory footprint, by leveraging the build-time code generation process.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Live Reload in Development&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Static modules are automatically watched and reloaded. Think of everyone&amp;#8217;s favorite &lt;code&gt;quarkus:dev&lt;/code&gt;, but with Rust and
Go modules&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Native Image Compatibility&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WASM/WASI support&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With such potential in our hands, we chose the popular &lt;a href=&quot;https://github.com/google/cel-go&quot;&gt;Google CEL&lt;/a&gt;, a Go library/API
adopted by several Go operators, and decided to integrate it in our application.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;application-setup-and-configuration&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#application-setup-and-configuration&quot;&gt;&lt;/a&gt;Application setup and configuration&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Creating the application is straightforward using the Quarkus Maven plugin.
Note that Quarkus 3.x requires Java 17 or higher (we used Java 21 for this example):&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;mvn io.quarkus.platform:quarkus-maven-plugin:create \
    -DprojectGroupId=io.quarkiverse.chicory.demo \
    -DprojectArtifactId=quarkus-cel-k8s-validator \
    -Dextensions=&apos;rest&apos;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Next, we add the Quarkus Chicory extension to our pom.xml:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;    &amp;lt;properties&amp;gt;
        &amp;lt;dylibso.version&amp;gt;1.6.1&amp;lt;/dylibso.version&amp;gt;
        &amp;lt;quarkus-chicory.version&amp;gt;0.0.1&amp;lt;/quarkus-chicory.version&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;dependencyManagement&amp;gt;
        &amp;lt;dependencies&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;${quarkus.platform.group-id}&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;${quarkus.platform.artifact-id}&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;${quarkus.platform.version}&amp;lt;/version&amp;gt;
                &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
                &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
            &amp;lt;/dependency&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;com.dylibso.chicory&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;wasi&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;${dylibso.version}&amp;lt;/version&amp;gt;
            &amp;lt;/dependency&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;io.quarkiverse.chicory&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;quarkus-chicory&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;${quarkus-chicory.version}&amp;lt;/version&amp;gt;
            &amp;lt;/dependency&amp;gt;
        &amp;lt;/dependencies&amp;gt;
    &amp;lt;/dependencyManagement&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;quarkus-rest&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;quarkus-rest-jackson&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;quarkus-arc&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.quarkiverse.chicory&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;quarkus-chicory&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;com.dylibso.chicory&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;wasi&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;!-- more dependencies here... --&amp;gt;
    &amp;lt;/dependencies&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Finally, the WASM module configuration goes in application.properties:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.chicory.modules.go-cel.name=io.quarkiverse.chicory.demo.GoCelModule
quarkus.chicory.modules.go-cel.wasm-file=src/main/resources/wasm/go-cel.wasm&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This tells Quarkus Chicory to generate a &lt;code&gt;GoCelModule&lt;/code&gt; class at build time from the specified WASM file.
The extension will automatically generate Java bytecode from the WebAssembly module, configure the appropriate
&lt;code&gt;MachineFactory&lt;/code&gt; based on the runtime environment, and  - in development mode - watch the WASM file for changes to
trigger live reload.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;One last step, now. We will use the
&lt;a href=&quot;https://chicory.dev/docs/usage/annotations#wasmmoduleinterface&quot;&gt;&lt;code&gt;WasmModuleInterface&lt;/code&gt; annotation&lt;/a&gt; and configure the
&lt;a href=&quot;https://chicory.dev/docs/usage/annotations#enabling-the-annotation-processor&quot;&gt;annotation processor&lt;/a&gt;,
for Chicory to generate a Java class containing methods mapping 1:1 to Go exported functions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;First, let&amp;#8217;s create a &lt;code&gt;K8sCel&lt;/code&gt; Java class where to place our annotation:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;package io.quarkiverse.chicory.demo;

import com.dylibso.chicory.annotations.WasmModuleInterface;

@WasmModuleInterface(WasmResource.absoluteFile)
public class K8sCel {

    private K8sCel() {}

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;At build-time, the Chicory annotation processor will discover such annotation and generate a &lt;code&gt;K8sCel_ModuleExports&lt;/code&gt;
class, which provides the exported methods:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;package io.quarkiverse.chicory.demo;

import com.dylibso.chicory.runtime.ExportFunction;
import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.runtime.Memory;

public class K8sCel_ModuleExports {
    private final ExportFunction field__start;
    private final ExportFunction field_malloc;
    private final ExportFunction field_free;
    private final ExportFunction field_evalPolicy;
    private final Memory field_memory;

    public K8sCel_ModuleExports(Instance instance) {
        this.field__start = instance.exports().function(&quot;_start&quot;);
        this.field_malloc = instance.exports().function(&quot;malloc&quot;);
        this.field_free = instance.exports().function(&quot;free&quot;);
        this.field_evalPolicy = instance.exports().function(&quot;evalPolicy&quot;);
        this.field_memory = instance.exports().memory(&quot;memory&quot;);
    }

    public void _start() {
        this.field__start.apply(new long[0]);
    }

    public int malloc(int arg0) {
        long result = this.field_malloc.apply(new long[]{(long)arg0})[0];
        return (int)result;
    }

    public void free(int arg0) {
        this.field_free.apply(new long[]{(long)arg0});
    }

    public int evalPolicy(int arg0, int arg1, int arg2, int arg3) {
        long result = this.field_evalPolicy.apply(new long[]{(long)arg0, (long)arg1, (long)arg2, (long)arg3})[0];
        return (int)result;
    }

    public Memory memory() {
        return this.field_memory;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And that&amp;#8217;s enough!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;the-wasmquarkuscontext-api&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-wasmquarkuscontext-api&quot;&gt;&lt;/a&gt;The &lt;code&gt;WasmQuarkusContext&lt;/code&gt; API&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The example application follows a clean architecture pattern with separated concerns:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K8sCelValidatorService&lt;/strong&gt; - Manages WASM integration and business logic&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;K8sCelValidatorResource&lt;/strong&gt; - Provides REST API endpoint&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus Chicory extension provides the &lt;code&gt;WasmQuarkusContext&lt;/code&gt; API for injection, to access configured WASM modules.
Here&amp;#8217;s how we use it in our service:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@ApplicationScoped
public class K8sCelValidatorService {

    @Inject
    @Named(&quot;go-cel&quot;)
    WasmQuarkusContext wasmQuarkusContext;

    Instance instance;
    K8sCel_ModuleExports exports;

    @PostConstruct
    public void init() throws IOException {
        WasmModule wasmModule = wasmQuarkusContext.getWasmModule();
        if (wasmModule == null) {
            throw new IllegalStateException(&quot;Wasm module &quot; + wasmQuarkusContext.getName() + &quot; not found!&quot;);
        }

        // Create WASI support for stdout/stderr
        WasiOptions options = WasiOptions.builder()
                .withStdout(new ByteArrayOutputStream())
                .withStderr(new ByteArrayOutputStream())
                .build();
        WasiPreview1 wasi = WasiPreview1.builder()
                .withOptions(options)
                .build();
        Store store = new Store().addFunction(wasi.toHostFunctions());

        instance = Instance.builder(wasmModule) &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
                .withMachineFactory(wasmQuarkusContext.getMachineFactory())
                .withImportValues(store.toImportValues())
                // Don&apos;t auto-run _start(), we&apos;ll call it manually
                .withStart(false)
                .build();

        // Get exported functions BEFORE calling _start
        exports = new K8sCel_ModuleExports(instance);   &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;

        // Initialize Go runtime by calling _start()
        // This is required to perform initialization, i.e. to run main(), which indeed should exit with 0,
        // so we catch the expected WasiExitException accordingly.
        try {
            exports.start();    &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
        } catch (com.dylibso.chicory.wasi.WasiExitException e) {
            // Expected - Go main() exits after completing
            if (e.exitCode() != 0) {
                throw new RuntimeException(&quot;Go runtime initialization failed with exit code: &quot; + e.exitCode());
            }
            // Exit code 0 is success - runtime is now initialized and exported functions are ready
        }
    }

    public ValidationResult validate(final String resourceJson, final String celPolicy) {

        byte[] policyBytes = celPolicy.getBytes(StandardCharsets.UTF_8);
        byte[] inputBytes = resourceJson.getBytes(StandardCharsets.UTF_8);

        // Allocate memory for policy string in WASM
        int policyPtr = exports.malloc(policyBytes.length);
        if (policyPtr == 0) {
            throw new IllegalStateException(&quot;Failed to allocate memory for policy&quot;);
        }

        // Allocate memory for input JSON in WASM
        int inputPtr = exports.malloc(inputBytes.length);
        if (inputPtr == 0) {
            throw new IllegalStateException(&quot;Failed to allocate memory for input&quot;);
        }

        try {
            // Write policy and input to WASM memory
            exports.memory().write(policyPtr, policyBytes);
            exports.memory().write(inputPtr, inputBytes);

            // Call evalPolicy(policyPtr, policyLen, inputPtr, inputLen)
            int returnCode = exports.evalPolicy(policyPtr, policyBytes.length, inputPtr, inputBytes.length);

            // Interpret result
            if (returnCode == 11) {
                return new ValidationResult(VALIDATION_RESULT_ALLOWED, &quot;Policy ALLOWS the request&quot;, celPolicy);
            } else if (returnCode == 0) {
                return new ValidationResult(VALIDATION_RESULT_DENIED, &quot;Policy DENIES the request&quot;, celPolicy);
            } else {
                // Negative values are errors
                String errorMsg = switch (returnCode) {
                    case -1 -&amp;gt; &quot;JSON parse error&quot;;
                    case -2 -&amp;gt; &quot;CEL environment creation error&quot;;
                    case -3 -&amp;gt; &quot;CEL compilation error&quot;;
                    case -4 -&amp;gt; &quot;CEL program creation error&quot;;
                    case -5 -&amp;gt; &quot;CEL runtime error&quot;;
                    default -&amp;gt; &quot;Unknown error: &quot; + returnCode;
                };
                return new ValidationResult(VALIDATION_RESULT_ERROR, &quot;CEL evaluation failed: &quot; + errorMsg, celPolicy);
            }
        } finally {
            // Free allocated memory in WASM
            exports.free(policyPtr);
            exports.free(inputPtr);
        }
    }

    public static final String VALIDATION_RESULT_ALLOWED = &quot;allowed&quot;;
    public static final String VALIDATION_RESULT_DENIED = &quot;denied&quot;;
    public static final String VALIDATION_RESULT_ERROR = &quot;error&quot;;

    public record ValidationResult(String status, String message, String policy) {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The injected &lt;code&gt;WasmQuarkusContext&lt;/code&gt; bean configures &lt;code&gt;Instance.Builder&lt;/code&gt; to use &lt;code&gt;MachineFactory&lt;/code&gt; and &lt;code&gt;WasmModule&lt;/code&gt;
instances, which are created dynamically, based on the application configuration and execution environment.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Once &lt;code&gt;instance&lt;/code&gt; is built, &lt;code&gt;export&lt;/code&gt; is initialized with a &lt;code&gt;K8sCel_ModuleExports&lt;/code&gt; instance, providing exported functions
which are called later in the &lt;code&gt;validate()&lt;/code&gt; method.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The exported &quot;_start&quot; function is called, to initialize the Go runtime. This executes the Go program &lt;code&gt;main()&lt;/code&gt;
function. As it&amp;#8217;s empty in our implementation, it will exit immediately, so we catch &lt;code&gt;WasiExitExcpetion&lt;/code&gt; to check for
a 0 (no errors) exit code.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;a-note-about-multi-user-and-thread-safety&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#a-note-about-multi-user-and-thread-safety&quot;&gt;&lt;/a&gt;A note about multi-user and thread safety&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;code&gt;WasmQuarkusContext&lt;/code&gt; instances are injected as &lt;code&gt;@ApplicationScoped&lt;/code&gt; beans. This means that a unique application instance
can be used by several clients (or user requests) and threads.
That being said, the API implementation is &lt;em&gt;stateless&lt;/em&gt;, i.e. &lt;code&gt;getMachineFactory()&lt;/code&gt; and &lt;code&gt;getWasmModule()&lt;/code&gt; always return
new instances.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The way such instances are dealt with, and how their lifecycle is orchestrated, is something that pertains to the
application domain. For example, the above implementation doesn&amp;#8217;t take concurrency into account. If multiple
threads are going to consume the same &lt;code&gt;Memory&lt;/code&gt; instance, a thread-safe implementation would be required in order to
avoid corrupting the shared &lt;code&gt;WasmModule&lt;/code&gt; linear memory.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Back to our application code, the REST resource is then a simple delegation layer:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Path(&quot;/k8s&quot;)
public class K8sCelValidatorResource {

    @Inject
    K8sCelValidatorService validatorService;

    @POST
    @Path(&quot;/validate&quot;)
    public Response validate(@RestForm String resourceJson, @RestForm String celPolicy) {
        ValidationResult result = validatorService.validate(resourceJson, celPolicy);

        Response.Status status = switch (result.status()) {
            case &quot;allowed&quot; -&amp;gt; Response.Status.OK;
            case &quot;denied&quot; -&amp;gt; Response.Status.FORBIDDEN;
            default -&amp;gt; Response.Status.BAD_REQUEST;
        };

        return Response.status(status).entity(result).build();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;WasmQuarkusContext&lt;/code&gt; API provides two key methods:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;getWasmModule()&lt;/code&gt;: returns the parsed WebAssembly module&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;getMachineFactory()&lt;/code&gt;: returns the appropriate &lt;code&gt;MachineFactory&lt;/code&gt; based on environment
(interpreter for dev, build-time compilation for production/native)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;@Named&lt;/code&gt; qualifier matches the module name from application.properties.
The extension handles all the complexity of WASM module lifecycle, allowing us to focus on the business logic.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-it-works-go-wasm-java-bytecode&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-it-works-go-wasm-java-bytecode&quot;&gt;&lt;/a&gt;How it works: Go &amp;#8594; Wasm &amp;#8594; Java bytecode&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The heart of our application is the Go CEL implementation, compiled to WebAssembly.
The Go code implements three key exported functions:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-go hljs&quot; data-lang=&quot;go&quot;&gt;//go:wasmexport evalPolicy
func evalPolicy(policyPtr, policyLen, inputPtr, inputLen uint32) int32 {
    // Convert pointers to Go types
    policy := unsafe.String((*byte)(unsafe.Pointer(uintptr(policyPtr))), policyLen)
    inputJSON := unsafe.Slice((*byte)(unsafe.Pointer(uintptr(inputPtr))), inputLen)

    // Parse the JSON input
    var input map[string]any
    if err := json.Unmarshal(inputJSON, &amp;amp;input); err != nil {
        return -1  // JSON parse error
    }

    // Create CEL environment
    env, err := cel.NewEnv(
        cel.Declarations(
            decls.NewVar(&quot;object&quot;, decls.NewMapType(decls.String, decls.Dyn)),
        ),
    )
    if err != nil {
        return -2  // CEL environment creation error
    }

    // Compile and evaluate the CEL expression
    ast, iss := env.Compile(policy)
    if iss.Err() != nil {
        return -3  // Compilation error
    }

    prg, err := env.Program(ast)
    if err != nil {
        return -4  // Program creation error
    }

    out, _, err := prg.Eval(map[string]any{&quot;object&quot;: input})
    if err != nil {
        return -5  // CEL runtime error
    }

    // Return 1 for allow, 0 for deny
    if b, ok := out.Value().(bool); ok &amp;amp;&amp;amp; b {
        return 1
    }
    return 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This Go code is compiled to WASM using the WASI target:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;GOOS=wasip1 GOARCH=wasm go build -o go-cel.wasm main.go&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In our service implementation:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;Java allocates WASM memory for the policy string and input resource manifest (JSON), and writes the data to WASM
memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Java calls &lt;code&gt;evalPolicy()&lt;/code&gt; with pointers to arguments and their size&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go code reads from its memory space, and evaluates the CEL expression using the Google CEL library&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go returns an integer result code (1=allow, 0=deny, negative=error)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Java interprets the result and performs clean up&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;em&gt;This demonstrates the power of WebAssembly: we can use the mature, battle-tested Google CEL-Go library
from Java without reimplementing CEL from scratch.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The WASM boundary provides a clean and safe interface between the two languages.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In production, we can write CEL policies that validate Kubernetes resources just like Go operators do:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-cel hljs&quot; data-lang=&quot;cel&quot;&gt;// Require production label
has(object.metadata.labels.env) &amp;amp;&amp;amp; object.metadata.labels.env == &quot;production&quot;

// Deny privileged containers
!(has(object.spec.containers) &amp;amp;&amp;amp; object.spec.containers.exists(c,
  has(c.securityContext) &amp;amp;&amp;amp; c.securityContext.privileged == true))

// Require resource limits
has(object.spec.containers) &amp;amp;&amp;amp; object.spec.containers.all(c,
  has(c.resources) &amp;amp;&amp;amp; has(c.resources.limits))&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;By combining Quarkus Chicory with Google CEL-Go compiled to WebAssembly, we&amp;#8217;ve created a
Kubernetes-style CEL policy engine that runs entirely in Java.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This approach offers several benefits:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reuse existing Go libraries: No need to reimplement CEL in Java, 1:1 mapping with original Go code&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Type safety and performance: Quarkus Chicory generates Java bytecode from WASM modules&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Production ready: The same CEL library used by Go operators, now available in Java&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Developer experience: Live reload, build-time code generation, and native image support&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ecosystem compatibility: Works seamlessly with
&lt;a href=&quot;https://github.com/operator-framework/java-operator-sdk&quot;&gt;Java-based Kubernetes operators&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This demonstrates that WebAssembly is not just a browser technology,
but rather a powerful tool for cross-language interoperability in cloud-native applications, and
showcases how to integrate this workflow easily in Quarkus applications, thanks to Quarkus Chicory.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Java developers building Kubernetes operators, this approach opens up a large part of the Go ecosystem
without leaving the JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can find the complete working example at: &lt;a href=&quot;https://github.com/fabiobrz/quarkus-cel-k8s-validator&quot; class=&quot;bare&quot;&gt;https://github.com/fabiobrz/quarkus-cel-k8s-validator&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;references&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#references&quot;&gt;&lt;/a&gt;Referências&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.quarkiverse.io/quarkus-chicory/dev&quot;&gt;Quarkus Chicory Extension&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dylibso/chicory&quot;&gt;Chicory WebAssembly Runtime&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/google/cel-go&quot;&gt;Google CEL&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://kubernetes.io/docs/reference/using-api/cel/&quot;&gt;Kubernetes CEL Validation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://wasi.dev/&quot;&gt;WebAssembly System Interface (WASI)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/k8s-style-CEL-with-quarkus-chicory/
            </guid>
            
            
            
            <author>Fabio Burzigotti</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.31.4 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-31-4-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.31.4, the third maintenance release for our 3.31 stream (we skipped 3.31.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.31, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.31.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;Quarkus 3.31 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.4&quot;&gt;3.31.4&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 18 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-31-4-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus Newsletter #65 - February</title>
            <link>
                https://quarkus.io/blog/quarkus-newsletter-65/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Although focused on microservices, Quarkus is also perfectly suited for large monoliths, whether you are migrating existing applications to a more modern runtime or building new ones from scratch. Quarkus has always been able to handle large applications, but we have recently made significant improvements in this area, particularly when it comes to build times. Read &quot;Towards faster builds&quot; by Guillaume Smet to learn more about these improvements. Read &quot;Implementing an arXiv MCP Server with Quarkus in Java&quot; by Guillaume Laforge to learn about building an MCP server to access the arXiv research paper website where pre-print versions are published and shared with the community. The author&amp;#8217;s goal was to shed light on some lesser-known aspects of the Model Context Protocol, tools, resources and prompts. Learn the details of why Anand Jaisy chose to switch frameworks in &quot;Micronaut vs Quarkus: Why I Switched After Two Years&quot;. Check out &quot;How to Trace Quarkus Reactive Messaging with OpenTelemetry&quot; by Nawaz Dhandala to learn how to implement distributed tracing for Quarkus Reactive Messaging applications using OpenTelemetry to track messages across Kafka and other messaging systems. Make sure you try this realistic Java walkthrough showing validation, retries, idempotency, and Kafka-backed workflows with Quarkus in &quot;Your Second Reactive Messaging App: What Production Systems Actually Need&quot; by Markus Eisele. Then you can learn about using graph-based analysis to detect and prevent architectural decay in Java applications in his second blog post, &quot;Your Quarkus Architecture Is Drifting. JQAssistant Can Prove It.&quot;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You will also see the latest Quarkus Insights episodes, top tweets/discussions and upcoming Quarkus attended events.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://quarkus.io/newsletter/65/&quot;&gt;Newsletter #65: February&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want to get newsletters in your inbox? &lt;a href=&quot;https://quarkus.io/newsletter&quot;&gt;Sign up for the newsletter&lt;/a&gt; using the on page form.&lt;/p&gt;
&lt;/div&gt;
            </description>
            <pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-newsletter-65/
            </guid>
            
            
            
            <author>James Cobb (https://twitter.com/insectengine)</author>
            
        </item>
        
        <item>
            <title>A2A Java SDK 1.0.0.Alpha2 Released</title>
            <link>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-alpha2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We are pleased to announce the release of A2A Java SDK 1.0.0.Alpha2. This release brings significant new features and improvements as we continue to align with the &lt;a href=&quot;https://a2a-protocol.org/latest/specification/&quot;&gt;A2A 1.0 specification&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-a2a&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-a2a&quot;&gt;&lt;/a&gt;What&amp;#8217;s A2A?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Agent2Agent (A2A) Protocol is an open standard that enables AI agents to communicate and collaborate with one another, regardless of each agent&amp;#8217;s underlying framework, language, or vendor. The A2A Java SDK makes it easy to build A2A-compliant agents in Java, with reference implementations based on Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;key-highlights-in-1-0-0-alpha2&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#key-highlights-in-1-0-0-alpha2&quot;&gt;&lt;/a&gt;Key Highlights in 1.0.0.Alpha2&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release includes several important enhancements and breaking changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;new-features&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#new-features&quot;&gt;&lt;/a&gt;New Features&lt;/h3&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;telemetry-support&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#telemetry-support&quot;&gt;&lt;/a&gt;Telemetry Support&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The A2A Java SDK now includes built-in support for telemetry using OpenTelemetry. This allows you to monitor and trace your agent&amp;#8217;s operations, making it easier to diagnose issues and understand performance characteristics.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To use the telemetry features, add the OpenTelemetry extras to your project:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-extras-opentelemetry-client&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.Alpha2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-extras-opentelemetry-server&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.Alpha2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;push-notifications&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#push-notifications&quot;&gt;&lt;/a&gt;Push Notifications&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ve implemented full support for push notifications as specified in the A2A 1.0 specification. This allows agents to receive notifications about task updates without polling.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Server agents can now:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Configure push notification endpoints&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manage push notification configurations per task&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Receive notifications when task states change&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Clients can:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Get, set, list, and delete push notification configurations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Subscribe to task updates via push notifications&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;protocol-updates&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#protocol-updates&quot;&gt;&lt;/a&gt;Protocol Updates&lt;/h3&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;breaking-changes&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#breaking-changes&quot;&gt;&lt;/a&gt;Breaking Changes&lt;/h4&gt;
&lt;div class=&quot;admonitionblock important&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-important&quot; title=&quot;Important&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release includes breaking changes to align with the latest A2A specification.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AgentEmitter API&lt;/strong&gt;: The &lt;code&gt;AgentExecutor&lt;/code&gt; methods now use &lt;code&gt;AgentEmitter&lt;/code&gt; instead of the previous &lt;code&gt;EventQueue&lt;/code&gt; + &lt;code&gt;TaskUpdater&lt;/code&gt; combination, providing a more streamlined and intuitive API. This enhancement allows sending Messages for simple Agent interactions directly through the &lt;code&gt;AgentEmitter&lt;/code&gt;, eliminating the need to interact with the EventQueue directly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Protocol Alignment&lt;/strong&gt;: Updated the A2A protocol implementation to align with the latest specification revision, including updates to the gRPC protocol definitions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;additional-improvements&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#additional-improvements&quot;&gt;&lt;/a&gt;Additional Improvements&lt;/h3&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Null-Safety&lt;/strong&gt;: Migrated the spec module to use JSpecify annotations for better null-safety guarantees&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Jakarta CDI Compatibility&lt;/strong&gt;: Added no-args constructors for improved Jakarta CDI compatibility&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;HTTP+JSON/REST Transport&lt;/strong&gt;: Replaced &lt;code&gt;quarkus-rest-jackson&lt;/code&gt; with &lt;code&gt;quarkus-rest&lt;/code&gt; for better integration&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Event Processing&lt;/strong&gt;: Implemented the MainEventBus architecture for more robust event queue processing&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MicroProfile Config&lt;/strong&gt;: Added missing &lt;code&gt;META-INF/beans.xml&lt;/code&gt; to the microprofile-config integration&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;migration-guide&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#migration-guide&quot;&gt;&lt;/a&gt;Migration Guide&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you&amp;#8217;re upgrading from 1.0.0.Alpha1, you&amp;#8217;ll need to make the following changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;update-agentexecutor-implementation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update-agentexecutor-implementation&quot;&gt;&lt;/a&gt;Update AgentExecutor Implementation&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;execute&lt;/code&gt; and &lt;code&gt;cancel&lt;/code&gt; methods now receive an &lt;code&gt;AgentEmitter&lt;/code&gt; parameter instead of &lt;code&gt;EventQueue&lt;/code&gt;:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;// Before (1.0.0.Alpha1)
@Override
public void execute(RequestContext context, EventQueue eventQueue) throws JSONRPCError {
    final TaskUpdater updater = new TaskUpdater(context, eventQueue);
    updater.submit();
    updater.startWork();
    // ...
}

// After (1.0.0.Alpha2)
@Override
public void execute(RequestContext context, AgentEmitter agentEmitter) throws JSONRPCError {
    agentEmitter.submit();
    agentEmitter.startWork();
    // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;AgentEmitter&lt;/code&gt; interface provides the same functionality with a cleaner API.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#getting-started&quot;&gt;&lt;/a&gt;Primeiros passos&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To use A2A Java SDK 1.0.0.Alpha2, add the appropriate dependencies to your project:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;a2a-java-sdk-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.0.Alpha1&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;

&amp;lt;!-- For JSON-RPC transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-jsonrpc&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.Alpha2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- For gRPC transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-grpc&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.Alpha2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;!-- For HTTP+JSON/REST transport --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-rest&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.Alpha2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;resources&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#resources&quot;&gt;&lt;/a&gt;Resources&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/a2aproject/a2a-java/releases/tag/v1.0.0.Alpha2&quot;&gt;Release Notes on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/a2aproject/a2a-samples/tree/main/samples/java/agents&quot;&gt;A2A Java SDK Samples&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/a2aproject/a2a-java/blob/main/README.md&quot;&gt;A2A Java SDK Documentation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://a2a-protocol.org/latest/specification/&quot;&gt;A2A Specification&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A2A Java SDK 1.0.0.Alpha2 represents a significant step forward in our journey toward full A2A 1.0 specification compliance. The addition of telemetry support and push notifications makes it easier to build production-ready agents, while the protocol updates ensure compatibility with the latest specification.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We encourage you to try out this release and provide feedback through our &lt;a href=&quot;https://github.com/a2aproject/a2a-java/issues&quot;&gt;GitHub issue tracker&lt;/a&gt;. Your input helps shape the future of the A2A Java SDK.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 12 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-alpha2-released/
            </guid>
            
            
            
            <author>Emmanuel Hugonnet (https://twitter.com/ehsavoie)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.31.3 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-31-3-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.31.3, the second maintenance release for our 3.31 stream (we skipped 3.31.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.31, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.31.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;Quarkus 3.31 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.3&quot;&gt;3.31.3&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-31-3-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Closing the Gap: Test Coverage for Quarkus Extensions</title>
            <link>
                https://quarkus.io/blog/quarkus-test-coverage-extensions/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Test coverage is usually defined as a metric that measures the percentage of code executed by tests.
Some developers doubt its usefulness but I agree with &lt;a href=&quot;https://martinfowler.com/bliki/TestCoverage.html&quot;&gt;Martin Fowler&amp;#8217;s&lt;/a&gt; opinion that &lt;em&gt;&quot;Test coverage is a useful tool for finding untested parts of a codebase&quot;&lt;/em&gt;.
I don&amp;#8217;t think the resulting number itself is important.
After all, writing a test for a generated getter makes no sense at all.
However, if it&amp;#8217;s possible to identify poorly tested code in a hot path of your extension, then you can improve the test suite and spot bugs before the release, which always pays off.
Just as importantly, you can increase the ability to catch regressions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For a long time, there has been the &lt;code&gt;io.quarkus:quarkus-jacoco&lt;/code&gt; extension that integrates the &lt;a href=&quot;https://www.jacoco.org/jacoco/index.html&quot;&gt;JaCoCo code coverage library&lt;/a&gt;.
Nevertheless, until recently, it was not possible to measure the coverage of runtime modules for an extension project.
In other words, it was possible to measure the coverage in your `@QuarkusTest`s but not in `QuarkusUnitTest`s, which typically constitute the majority of tests in extensions.
Without adequate coverage support, developers were flying blind, uncertain whether their bytecode enhancements and recording logic were being effectively tested.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;technical-overview&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#technical-overview&quot;&gt;&lt;/a&gt;Technical overview&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;JaCoCo instruments classes to record execution coverage data.
By default, the classes are instrumented on-the-fly by a Java agent.
However, in Quarkus we use &lt;a href=&quot;https://www.jacoco.org/jacoco/trunk/doc/offline.html&quot;&gt;offline instrumentation&lt;/a&gt; to modify the bytecode of classes &lt;em&gt;during build&lt;/em&gt;.
By default, all classes in all &lt;em&gt;application archives&lt;/em&gt; are instrumented.
An &lt;em&gt;application archive&lt;/em&gt; is an archive that provides components to the application.
It&amp;#8217;s indexed via Jandex, and extensions can analyze its content.
For example, Quarkus is analyzing the application archives during CDI bean discovery.
However, a runtime module of an extension is usually &lt;em&gt;not&lt;/em&gt; an application archive.
Therefore, the extension classes were never instrumented.
Until now.
In Quarkus 3.31.2, we introduced new configuration properties that specify the artifacts to be instrumented: &lt;code&gt;quarkus.jacoco.instrument-artifacts.&quot;dependency-name&quot;.group-id&lt;/code&gt; and &lt;code&gt;quarkus.jacoco.instrument-artifacts.&quot;dependency-name&quot;.artifact-id&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;basic-setup&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#basic-setup&quot;&gt;&lt;/a&gt;Basic setup&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you want to measure the test coverage of the runtime module of an extension, specific JaCoCo configuration is needed in the deployment module:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;profiles&amp;gt;
    &amp;lt;profile&amp;gt;
        &amp;lt;id&amp;gt;test-coverage&amp;lt;/id&amp;gt;
        &amp;lt;activation&amp;gt;
            &amp;lt;property&amp;gt;
                &amp;lt;name&amp;gt;jacoco&amp;lt;/name&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
            &amp;lt;/property&amp;gt;
        &amp;lt;/activation&amp;gt;
        &amp;lt;dependencies&amp;gt;
            &amp;lt;dependency&amp;gt;
                &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;quarkus-jacoco-deployment&amp;lt;/artifactId&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
                &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
            &amp;lt;/dependency&amp;gt;
        &amp;lt;/dependencies&amp;gt;
        &amp;lt;build&amp;gt;
            &amp;lt;plugins&amp;gt;
                &amp;lt;plugin&amp;gt;
                    &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;configuration&amp;gt;
                        &amp;lt;systemPropertyVariables&amp;gt;
                            &amp;lt;quarkus.jacoco.instrument-artifacts.runtime.group-id&amp;gt;io.quarkus&amp;lt;/quarkus.jacoco.instrument-artifacts.runtime.group-id&amp;gt;
                            &amp;lt;quarkus.jacoco.instrument-artifacts.runtime.artifact-id&amp;gt;quarkus-runtime-module-name&amp;lt;/quarkus.jacoco.instrument-artifacts.runtime.artifact-id&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
                        &amp;lt;/systemPropertyVariables&amp;gt;
                    &amp;lt;/configuration&amp;gt;
                &amp;lt;/plugin&amp;gt;
            &amp;lt;/plugins&amp;gt;
        &amp;lt;/build&amp;gt;
    &amp;lt;/profile&amp;gt;
&amp;lt;/profiles&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This profile is activated with the &lt;code&gt;jacoco&lt;/code&gt; property.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Add the &lt;code&gt;quarkus-jacoco-deployment&lt;/code&gt; dependency with the test scope.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Instruct the JaCoCo plugin to instrument the &lt;code&gt;io.quarkus:quarkus-runtime-module-name`&lt;/code&gt; artifact.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;By default, the JaCoCo data will be saved in the &lt;code&gt;target/jacoco-quarkus.exec&lt;/code&gt; file and a coverage report is generated automatically in the &lt;code&gt;target/jacoco-report&lt;/code&gt; directory.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;multi-module-setup&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#multi-module-setup&quot;&gt;&lt;/a&gt;Multi-module setup&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For multi-module projects, more config properties might be needed.
Typically, when an extension project contains multiple extensions that depend on each other, a more complex configuration is required.
In the following project we have two extensions submodules: &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;/my-extension-project
   ├── /foo
   │  ├── runtime
   │  ├── deployment
   │  └── pom.xml
   ├── /bar (depends on foo)
   │  ├── runtime
   │  ├── deployment
   │  └── pom.xml
   └── pom.xml&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Submodule &lt;code&gt;bar&lt;/code&gt; depends on &lt;code&gt;foo&lt;/code&gt; and extends its functionality.
The &lt;code&gt;foo/deployment&lt;/code&gt; submodule contains &lt;code&gt;QuarkusUnitTest`s that test classes from `foo/runtime&lt;/code&gt;.
The &lt;code&gt;bar/deployment&lt;/code&gt; submodule contains &lt;code&gt;QuarkusUnitTest`s that test classes from both `bar/runtime&lt;/code&gt; and &lt;code&gt;foo/runtime&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our goal is to measure the coverage for both &lt;code&gt;foo/runtime&lt;/code&gt; and &lt;code&gt;bar/runtime&lt;/code&gt;.
How do we proceed?
First, we need to apply some configuration to the parent project.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;&lt;code&gt;my-extension-project/pom.xml&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;profiles&amp;gt;
    &amp;lt;profile&amp;gt;
        &amp;lt;id&amp;gt;test-coverage&amp;lt;/id&amp;gt;
        &amp;lt;activation&amp;gt;
            &amp;lt;property&amp;gt;
                &amp;lt;name&amp;gt;jacoco&amp;lt;/name&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
            &amp;lt;/property&amp;gt;
        &amp;lt;/activation&amp;gt;
        &amp;lt;build&amp;gt;
            &amp;lt;plugins&amp;gt;
                &amp;lt;plugin&amp;gt;
                    &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;configuration&amp;gt;
                        &amp;lt;systemPropertyVariables&amp;gt;
                           &amp;lt;quarkus.jacoco.data-file&amp;gt;${maven.multiModuleProjectDirectory}/target/jacoco.exec&amp;lt;/quarkus.jacoco.data-file&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
                           &amp;lt;quarkus.jacoco.reuse-data-file&amp;gt;true&amp;lt;/quarkus.jacoco.reuse-data-file&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
                           &amp;lt;quarkus.jacoco.report-location&amp;gt;${maven.multiModuleProjectDirectory}/target/coverage&amp;lt;/quarkus.jacoco.report-location&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
                           &amp;lt;quarkus.jacoco.aggregate-report-data&amp;gt;true&amp;lt;/quarkus.jacoco.aggregate-report-data&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;(5)&lt;/b&gt;
                        &amp;lt;/systemPropertyVariables&amp;gt;
                    &amp;lt;/configuration&amp;gt;
                &amp;lt;/plugin&amp;gt;
            &amp;lt;/plugins&amp;gt;
        &amp;lt;/build&amp;gt;
    &amp;lt;/profile&amp;gt;
&amp;lt;/profiles&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This profile is activated with the &lt;code&gt;jacoco&lt;/code&gt; property.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The shared JaCoCo data file will be: &lt;code&gt;my-extension-project/target/jacoco.exec&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The shared JaCoCo data will be reused for all tests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The generated coverage report will be in the &lt;code&gt;my-extension-project/target/coverage&lt;/code&gt; directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;5&quot;&gt;&lt;/i&gt;&lt;b&gt;5&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The report data (source directories and class files) are aggregated so that a single report can be generated.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Afterwards, we will modify the deployment modules of &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;title&quot;&gt;&lt;code&gt;my-extension-project/bar/pom.xml&lt;/code&gt;&lt;/div&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;profiles&amp;gt;
   &amp;lt;profile&amp;gt;
      &amp;lt;id&amp;gt;test-coverage&amp;lt;/id&amp;gt;
      &amp;lt;activation&amp;gt;
         &amp;lt;property&amp;gt;
            &amp;lt;name&amp;gt;jacoco&amp;lt;/name&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
         &amp;lt;/property&amp;gt;
      &amp;lt;/activation&amp;gt;
      &amp;lt;dependencies&amp;gt;
         &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;quarkus-jacoco-deployment&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
         &amp;lt;/dependency&amp;gt;
      &amp;lt;/dependencies&amp;gt;
      &amp;lt;build&amp;gt;
         &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
               &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
               &amp;lt;configuration&amp;gt;
                  &amp;lt;systemPropertyVariables&amp;gt;
                     &amp;lt;quarkus.jacoco.instrument-artifacts.foo.group-id&amp;gt;org.acme&amp;lt;/quarkus.jacoco.instrument-artifacts.foo.group-id&amp;gt;
                     &amp;lt;quarkus.jacoco.instrument-artifacts.foo.artifact-id&amp;gt;foo&amp;lt;/quarkus.jacoco.instrument-artifacts.foo.artifact-id&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
                     &amp;lt;quarkus.jacoco.instrument-artifacts.bar.group-id&amp;gt;org.acme&amp;lt;/quarkus.jacoco.instrument-artifacts.bar.group-id&amp;gt;
                     &amp;lt;quarkus.jacoco.instrument-artifacts.bar.artifact-id&amp;gt;bar&amp;lt;/quarkus.jacoco.instrument-artifacts.bar.artifact-id&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
                  &amp;lt;/systemPropertyVariables&amp;gt;
               &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
         &amp;lt;/plugins&amp;gt;
      &amp;lt;/build&amp;gt;
   &amp;lt;/profile&amp;gt;
&amp;lt;/profiles&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This profile is activated with the &lt;code&gt;jacoco&lt;/code&gt; property.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Instrument &lt;code&gt;org.acme:foo&lt;/code&gt; when running tests in &lt;code&gt;bar/deployment&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Instrument &lt;code&gt;org.acme:bar&lt;/code&gt; when running tests in &lt;code&gt;bar/deployment&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Similarly, we can modify the &lt;code&gt;my-extension-project/foo/pom.xml&lt;/code&gt; and then simply run &lt;code&gt;mvn clean test -Djacoco&lt;/code&gt;.
When the build is finished, we can analyze the code coverage reports in the &lt;code&gt;my-extension-project/target/coverage&lt;/code&gt; directory.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
The Quarkus JaCoCo config only works for tests that are annotated with &lt;code&gt;@QuarkusTest&lt;/code&gt; and &lt;code&gt;@QuarkusUnitTest&lt;/code&gt;. If you want to check the coverage of other tests as well then you will need to fall back to the JaCoCo maven plugin, see &lt;a href=&quot;https://quarkus.io/guides/tests-with-coverage#coverage-for-tests-not-using-quarkustest&quot;&gt;the docs&lt;/a&gt; for more information.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Since Quarkus 3.31.2 you can measure and analyze the code coverage for the runtime modules of Quarkus extensions.
Improve the test suite, spot more bugs before the release, catch more regressions!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-test-coverage-extensions/
            </guid>
            
            
            
            <author>Martin Kouba (https://twitter.com/martunek)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.31.2 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-31-2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.31.2, the first maintenance release for our 3.31 stream (we skipped 3.31.0).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.31, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.31.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;Quarkus 3.31 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.2&quot;&gt;3.31.2&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 04 Feb 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-31-2-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.31 - Full Java 25 support, Quarkus Maven packaging, Panache Next, and more!</title>
            <link>
                https://quarkus.io/blog/quarkus-3-31-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It has been two months since our last feature release, and we are excited to announce the availability of Quarkus 3.31!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.31 comes with a LOT of new features and improvements:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Full Java 25 support&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51587&quot;&gt;#51587&lt;/a&gt; - Introduce a quarkus Maven packaging and an assorted lifecycle&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50058&quot;&gt;#50058&lt;/a&gt; - Introduce Panache Next, our next generation of Panache with improved developer experience and new features for both Hibernate ORM and Hibernate Reactive&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50519&quot;&gt;#50519&lt;/a&gt; - Upgrade to Hibernate ORM 7.2, Reactive 3.2, Search 8.2, Elasticsearch 9.2 / OpenSearch 3.3 for clients / server (dev services)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51586&quot;&gt;#51586&lt;/a&gt; - Hibernate Spatial support&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51314&quot;&gt;#51314&lt;/a&gt; - Upgrade to Testcontainers 2&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51412&quot;&gt;#51412&lt;/a&gt; - Upgrade to JUnit 6&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50987&quot;&gt;#50987&lt;/a&gt; - Support security annotations on Jakarta Data repositories&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51188&quot;&gt;#51188&lt;/a&gt; - Support &lt;code&gt;@PermissionsAllowed&lt;/code&gt; security annotation on REST Data Panache endpoints&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51220&quot;&gt;#51220&lt;/a&gt; - Encrypt OIDC tokens for custom TokenStateManager implementations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51383&quot;&gt;#51383&lt;/a&gt; - Allow to configure OIDC DB token state manager column sizes for tokens&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51743&quot;&gt;#51743&lt;/a&gt; - Allow to select OIDC client for individual dynamic GraphQL clients&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51679&quot;&gt;#51679&lt;/a&gt; - Allow to assign a user and roles to a scheduled task&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51799&quot;&gt;#51799&lt;/a&gt; - Add support for OAuth 2.0 Pushed Authorization Requests to OIDC extension&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50603&quot;&gt;#50603&lt;/a&gt; - Enable headless AWT on Windows for native images&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51736&quot;&gt;#51736&lt;/a&gt; - Require Maven 3.9.0+ for Quarkus projects&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51049&quot;&gt;#51049&lt;/a&gt; - Add i18n to Dev UI&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As usual, this release also includes many bug fixes, including fixes for some &lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51891&quot;&gt;very old issues created in 2020&lt;/a&gt;, thanks to our amazing community!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We highly recommend to have a look at the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;migration guide&lt;/a&gt; as this version comes with some important changes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.31, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.31.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31&quot;&gt;Quarkus 3.31 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-new&quot;&gt;&lt;/a&gt;What&amp;#8217;s new?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;full-support-for-java-25&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-support-for-java-25&quot;&gt;&lt;/a&gt;Full support for Java 25&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.31 adds full support for Java 25, including Java 25 runtime images and native image builds with Mandrel.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you create new projects with Java 25, the projects will fully target Java 25 by default.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We were hard at work to ensure compatibility and avoid as many warnings as possible when running Quarkus applications on Java 25.
If you encounter any issues, including warnings that shouldn&amp;#8217;t be there, please report them on our &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;bug tracker&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;new-quarkus-maven-packaging-and-lifecycle&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#new-quarkus-maven-packaging-and-lifecycle&quot;&gt;&lt;/a&gt;New quarkus Maven packaging and lifecycle&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A few months ago, we started working on making our builds faster (see this &lt;a href=&quot;https://quarkus.io/blog/building-large-applications/&quot;&gt;blog post&lt;/a&gt; for all the gory details).
With Quarkus 3.31, we are introducing a new Maven packaging type called &lt;code&gt;quarkus&lt;/code&gt;, designed to provide a more integrated and significantly more efficient build lifecycle.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In other words, we move away from the default Maven &lt;code&gt;jar&lt;/code&gt; lifecycle and introduce a Quarkus-specific lifecycle optimized for Quarkus applications, avoiding the execution of goals that are unnecessary in most cases.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is the default for newly created Quarkus projects and it can also be used for existing projects (see the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.31#new-quarkus-packaging-and-maven-lifecycle&quot;&gt;migration guide&lt;/a&gt; for more details).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;larger-applications&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#larger-applications&quot;&gt;&lt;/a&gt;Larger applications&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This &quot;faster builds&quot; effort is particularly beneficial for larger applications and we alleviated one of the latest bottleneck for creating VERY large applications:
the number of CDI beans in the application could hit some class file limits during the build.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;With Quarkus 3.31, you shouldn&amp;#8217;t be limited by the number of CDI beans anymore.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;panache-next&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#panache-next&quot;&gt;&lt;/a&gt;Panache Next&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you use Hibernate ORM with Quarkus, you are probably already familiar with Hibernate ORM with Panache.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Panache Next is our next generation of Panache that brings a better developer experience and new features.
While relying on the same underlying concepts as the current Panache implementation, Panache Next introduces a more intuitive API, improved type safety, and enhanced query capabilities.
It also unifies the programming model between Hibernate ORM and Hibernate Reactive, stateful and stateless sessions, making it easier for developers to switch between them.
Finally, it integrates seamlessly with Jakarta Data.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;There would be a lot more to say but the best is to have a look at the &lt;a href=&quot;https://quarkus.io/guides/hibernate-panache-next&quot;&gt;documentation&lt;/a&gt;, and give it a try.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It is still experimental and we are very looking forward to your feedback.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;hibernate&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#hibernate&quot;&gt;&lt;/a&gt;Hibernate&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.31 upgrades Hibernate ORM to 7.2, Hibernate Reactive to 3.2, Hibernate Search to 8.2, and the Elasticsearch/OpenSearch clients and servers to 9.2/3.3 respectively.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It also brings support for Hibernate Spatial, allowing developers to work with spatial data types and perform spatial queries in their Quarkus applications.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;junit-6-and-testcontainers-2&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#junit-6-and-testcontainers-2&quot;&gt;&lt;/a&gt;JUnit 6 and Testcontainers 2&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We upgraded to JUnit 6 (the update is relatively straightforward) and Testcontainers 2 (which comes with a lot more breaking changes).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;-junit5&lt;/code&gt; extensions have been renamed to &lt;code&gt;-junit&lt;/code&gt;, with relocations in place to avoid breaking existing projects.
Use &lt;code&gt;quarkus update&lt;/code&gt; to get them updated automatically.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;security&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#security&quot;&gt;&lt;/a&gt;Segurança&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;What would be a Quarkus release without security improvements?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release comes with a lot of improvements to our security extensions, including:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50987&quot;&gt;#50987&lt;/a&gt; - Support security annotations on Jakarta Data repositories&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51188&quot;&gt;#51188&lt;/a&gt; - Support &lt;code&gt;@PermissionsAllowed&lt;/code&gt; security annotation on REST Data Panache endpoints&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51220&quot;&gt;#51220&lt;/a&gt; - Encrypt OIDC tokens for custom TokenStateManager implementations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51383&quot;&gt;#51383&lt;/a&gt; - Allow to configure OIDC DB token state manager column sizes for tokens&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51743&quot;&gt;#51743&lt;/a&gt; - Allow to select OIDC client for individual dynamic GraphQL clients&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51679&quot;&gt;#51679&lt;/a&gt; - Allow to assign a user and roles to a scheduled task&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51799&quot;&gt;#51799&lt;/a&gt; - Add support for OAuth 2.0 Pushed Authorization Requests to OIDC extension&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;maven-3-9-required&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#maven-3-9-required&quot;&gt;&lt;/a&gt;Maven 3.9 required&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Maven 3.9 is now required to build Quarkus applications.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;headless-awt-on-windows-for-native-images&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#headless-awt-on-windows-for-native-images&quot;&gt;&lt;/a&gt;Headless AWT on Windows for native images&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We added support for headless AWT on Windows for native images to our AWT extension.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;i18n-for-dev-ui&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#i18n-for-dev-ui&quot;&gt;&lt;/a&gt;I18N for Dev UI&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Dev UI is now internationalized.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Contributions are welcome to improve the translations and add new languages.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.0.CR1&quot;&gt;3.31.0.CR1&lt;/a&gt;, &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.0&quot;&gt;3.31.0&lt;/a&gt;, and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.31.1&quot;&gt;3.31.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1153 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.31 release, thanks to Ales Justin, Alexandre Dutra, Alexey Loubyansky, Andrea Boriero, Andy Damevin, Anis Da Silva Campos, Aurea Munoz, Aurélien Pupier, Bastian, Brian Setz, Bruno Baptista, cfitzw, Chihiro Ito, Chris Laprun, Christian Pieczewski, Clement Escoffier, dancer13, David M. Lloyd, Dione de Souza Silva, Evgeny Potapov, Fedor Dudinsky, Foivos Zakkak, Fouad Almalki, Francesco Nigro, Galder Zamarreño, George Gastaldi, Georgios Andrianakis, Guillaume Smet, Holly Cummins, Jakub Pietrzak, James Netherton, Jan Martiska, Jan Schatteman, Jeff Mesnil, Jens Teglhus Møller, Jiri Ondrusek, Julien Ponge, Karm Michal Babacek, Katia Aresti, Ladislav Thon, Lars, Lars Andringa, lloydmeta, Luca Molteni, Lucas, Lucas Pottersky, Lukas Lowinger, Maciej Lisowski, Marco Belladelli, Marco Sappé Griot, mariofusco, marko-bekhta, Martin Bartoš, Martin Kouba, Martin Ocenas, Martin Panzer, Matheus Cruz, matthaios.stavrou, Melloware, Michael Edgar, Michal Vavřík, Nicolo Pietro Belcastro, Olivier V, Ozan Gunalp, Phillip Krüger, Quark, Roberto Cortez, Rolf Thorup, Rolfe Dlugy-Hegwer, Rostislav Svoboda, Sanne Grinovero, Sergey Beryozkin, Severin Gehwolf, shjones, sNiXx, staillebois, Stefan Oehme, Steve Hawkins, Stéphane Épardaud, Teymur Babayev, Thomas Segismont, Thorsten Meinl, Victor Dalosto, Wei Huang, Willem Jan Glerum, xstefank, and Yoann Rodière.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 28 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-31-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.8 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-8-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.8, a new maintenance release for our 3.30 stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It fixes a regression impacting OpenTelemetry and MDC data propagation introduced in 3.30.7.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.8&quot;&gt;3.30.8&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Fri, 23 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-8-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Retiring community UBI 8 images for Quarkus</title>
            <link>
                https://quarkus.io/blog/retiring-ubi8-images/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As you may know, Quarkus provides container images based on Red Hat Universal Base Image (UBI) both for building applications and for running them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Since Quarkus 3.19, Quarkus is using UBI 9 as the default base image for container images.
Given the oldest version we maintain in the community is 3.20 LTS, we have decided to retire the community UBI 8 images for Quarkus in March 2026.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We won&amp;#8217;t drop the images from our community Quay repository but they won&amp;#8217;t be updated anymore.
Which means that CVE issues affecting UBI 8 won&amp;#8217;t be fixed in the community Quarkus UBI 8 images anymore.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are still using UBI 8 images for building or running your Quarkus applications, we strongly recommend you to migrate to the UBI 9-based images as soon as possible.
If you have a very specific need to stay on UBI 8, please reach out to us.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/retiring-ubi8-images/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.7 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-7-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.7, a new maintenance release for our 3.30 stream, containing a couple additional fixes and a Vert.x micro update.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.31 will be released next week.
It comes with two months of work so expect many new features and improvements!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.7&quot;&gt;3.30.7&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-7-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.27.2 released - LTS maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-27-2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.27.2, our next maintenance release for the 3.27 LTS stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release contains bugfixes, documentation updates and fixes the following CVEs:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-66560&quot;&gt;CVE-2025-66560&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-59432&quot;&gt;CVE-2025-59432&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-67735&quot;&gt;CVE-2025-67735&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-14969&quot;&gt;CVE-2025-14969&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It should be a safe upgrade for anyone already using 3.27.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.27, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update --stream=3.27&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.27.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.27.2&quot;&gt;the full changelog of 3.27.2 on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-27-2-released/
            </guid>
            
            
            
            <author>Jan Martiška (https://twitter.com/janmartiska)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.20.5 released - LTS maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-20-5-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.20.5, our next maintenance release for the 3.20 LTS stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This release contains bugfixes, documentation updates and fixes the following CVEs:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-66560&quot;&gt;CVE-2025-66560&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-59432&quot;&gt;CVE-2025-59432&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2025-67735&quot;&gt;CVE-2025-67735&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It should be a safe upgrade for anyone already using 3.20.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.20, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update --stream=3.20&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.20.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.20.5&quot;&gt;the full changelog of 3.20.5 on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-20-5-released/
            </guid>
            
            
            
            <author>Jan Martiška (https://twitter.com/janmartiska)</author>
            
        </item>
        
        <item>
            <title>A2A Java SDK 1.0.0.Alpha1 - Embracing the 1.0 Specification</title>
            <link>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-alpha1/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I am pleased to announce the release of &lt;a href=&quot;https://github.com/a2aproject/a2a-java/releases/tag/v1.0.0.Alpha1&quot;&gt;A2A Java SDK 1.0.0.Alpha1&lt;/a&gt;. This release represents a significant milestone as we align with the upcoming 1.0 version of the &lt;a href=&quot;https://github.com/a2aproject/A2A&quot;&gt;Agent2Agent (A2A) Protocol specification&lt;/a&gt;. Note that the specification itself is still being finalised, so there might be some subtle changes until the final 1.0 version.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The A2A Protocol enables standardized communication between AI agents, allowing them to discover capabilities, delegate tasks, and collaborate seamlessly. This SDK provides a robust Java implementation for building both agents and clients that participate in the A2A ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;why-1-0-matters&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#why-1-0-matters&quot;&gt;&lt;/a&gt;Why 1.0 Matters&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The move to version 1.0 of the A2A specification marks its transition from experimental to production-ready. As the specification matures, we&amp;#8217;ve taken the opportunity to clean up technical debt, modernize our implementation, and establish patterns that will serve us well into the future.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;This release contains breaking changes.&lt;/strong&gt; We made the deliberate decision not to maintain backward compatibility with the 0.3.x series, as 1.0 represents the first &quot;proper&quot; release of the specification. This allows us to build on a solid foundation without carrying forward legacy patterns.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;major-changes&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#major-changes&quot;&gt;&lt;/a&gt;Major Changes&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;1-specification-alignment&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#1-specification-alignment&quot;&gt;&lt;/a&gt;1. Specification Alignment&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The SDK now implements protocol version &lt;code&gt;1.0&lt;/code&gt; and aligns with the latest &lt;a href=&quot;https://github.com/a2aproject/A2A/blob/main/specification/grpc/a2a.proto&quot;&gt;a2a.proto&lt;/a&gt; definitions. Key specification changes include:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AgentCard evolution&lt;/strong&gt;: The &lt;code&gt;AgentCard&lt;/code&gt; now uses a &lt;code&gt;supportedInterfaces&lt;/code&gt; list instead of separate &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;preferredTransport&lt;/code&gt;, and &lt;code&gt;additionalInterfaces&lt;/code&gt; fields. This provides a cleaner, more flexible way to advertise multiple protocol bindings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Removed kind discriminators&lt;/strong&gt;: The 1.0 specification eliminates the &lt;code&gt;kind&lt;/code&gt; field as a type discriminator, simplifying the protocol.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Refined error handling&lt;/strong&gt;: Error classes have been reworked to match the 1.0 specification&amp;#8217;s error model.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;2-modern-java-standardized-on-records&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#2-modern-java-standardized-on-records&quot;&gt;&lt;/a&gt;2. Modern Java: Standardized on Records&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The entire &lt;code&gt;spec&lt;/code&gt; module has been modernized to use Java records consistently. Previously, we had a mix of traditional classes and records across our domain model. Now all domain classes leverage records for immutability and conciseness, and all getters follow the same naming pattern:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;// Before (0.3.x): Mix of classes and records with inconsistent patterns
public class AgentCard {  // Some were classes
    private final String name;
    public String getName() { return name; }  // JavaBean-style getters
}

public record AgentSkill(String id, String name, ...) { }  // Some were already records
// Accessor: skill.name() without &apos;get&apos; prefix

// After (1.0.x): Consistent records throughout
public record AgentCard(
    String name,
    String description,
    AgentProvider provider,
    String version,
    List&amp;lt;AgentInterface&amp;gt; supportedInterfaces,
    String protocolVersion) {

    public static final String CURRENT_PROTOCOL_VERSION = &quot;1.0&quot;;
}

public record AgentSkill(String id, String name, String description, ...) { }

// Uniform accessor pattern throughout: card.name(), skill.name()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This standardization eliminates confusion and reduces boilerplate while providing a cleaner, more maintainable API.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;literalblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre&gt;The A2A Java SDK has seen significant improvements in type safety and **null-safety** through progressive adoption of JSpecify annotations over the past few months. This effort demonstrates the project&apos;s commitment to code quality and preventing null pointer exceptions at compile time.&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;builder-pattern-with-static-factory-methods&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#builder-pattern-with-static-factory-methods&quot;&gt;&lt;/a&gt;Builder Pattern with Static Factory Methods&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All builders now use static factory methods instead of public constructors. This provides better encapsulation and follows modern Java best practices:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;// Before (0.3.x): Public builder constructor
AgentCard card = new AgentCard.Builder()
    .name(&quot;My Agent&quot;)
    .description(&quot;Does things&quot;)
    .build();

// After (1.0.x): Static factory method
AgentCard card = AgentCard.builder()  &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
    .name(&quot;My Agent&quot;)
    .description(&quot;Does things&quot;)
    .version(&quot;1.0.0&quot;)
    .capabilities(AgentCapabilities.builder()  &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
        .streaming(true)
        .pushNotifications(false)
        .build())
    .defaultInputModes(List.of(&quot;text&quot;))
    .defaultOutputModes(List.of(&quot;text&quot;))
    .skills(List.of(
        AgentSkill.builder()  &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
            .id(&quot;weather_query&quot;)
            .name(&quot;Weather Queries&quot;)
            .description(&quot;Get current weather&quot;)
            .build()
    ))
    .supportedInterfaces(List.of(
        new AgentInterface(&quot;JSONRPC&quot;, &quot;http://localhost:9999&quot;)
    ))
    .protocolVersion(AgentCard.CURRENT_PROTOCOL_VERSION)
    .build();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AgentCard.builder()&lt;/code&gt; creates the builder - constructor is now private&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Nested builders also use static factory methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;All spec classes follow this pattern consistently&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Builder constructors are now private in the declaring classes, enforcing the use of the static factory method pattern throughout the SDK.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;3-protocol-buffers-as-source-of-truth&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#3-protocol-buffers-as-source-of-truth&quot;&gt;&lt;/a&gt;3. Protocol Buffers as Source of Truth&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ve eliminated our dependency on Jackson and established protocol buffers (protobuf) as the authoritative source for our domain model. The architecture is straightforward:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Protobuf definitions&lt;/strong&gt; in &lt;code&gt;a2a.proto&lt;/code&gt; define the wire format&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Java records&lt;/strong&gt; in the &lt;code&gt;spec&lt;/code&gt; module provide the SDK&amp;#8217;s API&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MapStruct mappers&lt;/strong&gt; handle conversions, giving compile errors if protobuf and spec classes go out of sync&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gson&lt;/strong&gt; handles JSON serialization for JSON-RPC transport&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This provides type safety across all transports, a single source of truth for the protocol, and clean separation between wire format and API without cluttering domain classes with serialization annotations.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;4-bill-of-materials-boms&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#4-bill-of-materials-boms&quot;&gt;&lt;/a&gt;4. Bill of Materials (BOMs)&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We&amp;#8217;ve introduced Maven BOMs to simplify dependency management:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;a2a-java-sdk-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.0.Alpha1&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Three BOMs are available:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;a2a-java-sdk-bom&lt;/code&gt;: Core SDK and client libraries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;a2a-java-extras-bom&lt;/code&gt;: Optional extensions (JpaDatabaseTaskStore and -PushNotificationStore, replicated QueueManager, Vert.X HTTP client)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;a2a-java-reference-bom&lt;/code&gt;: Quarkus reference implementations&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This eliminates version management headaches when using multiple SDK modules, and their dependencies.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;5-enhanced-api-documentation&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#5-enhanced-api-documentation&quot;&gt;&lt;/a&gt;5. Enhanced API Documentation&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Every class in the &lt;code&gt;spec&lt;/code&gt; module now has comprehensive Javadoc explaining its purpose, usage, and relationship to the A2A specification. We&amp;#8217;ve also added detailed documentation for integration points in &lt;code&gt;server-common&lt;/code&gt; and all client modules.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;6-additional-improvements&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#6-additional-improvements&quot;&gt;&lt;/a&gt;6. Additional Improvements&lt;/h3&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pagination support&lt;/strong&gt;: The &lt;code&gt;ListTasks&lt;/code&gt; and push notification configuration endpoints now support pagination with proper &lt;code&gt;Result&lt;/code&gt; wrappers&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pluggable HTTP client&lt;/strong&gt;: A new &lt;code&gt;A2AHttpClient&lt;/code&gt; interface allows custom HTTP implementations, with a Vert.x-based implementation provided&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Better validation&lt;/strong&gt;: Enhanced input validation across all transports&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TCK progress&lt;/strong&gt;: Continuous work towards full compliance with the 1.0 Test Compatibility Kit. The TCK is also work in progress, while the specification is being finalised.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;breaking-changes-summary&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#breaking-changes-summary&quot;&gt;&lt;/a&gt;Breaking Changes Summary&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you&amp;#8217;re migrating from 0.3.x, here are the key breaking changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;olist arabic&quot;&gt;
&lt;ol class=&quot;arabic&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AgentCard structure&lt;/strong&gt;: Replace &lt;code&gt;url&lt;/code&gt; + &lt;code&gt;preferredTransport&lt;/code&gt; with &lt;code&gt;supportedInterfaces&lt;/code&gt; list&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Builder pattern&lt;/strong&gt;: Use &lt;code&gt;AgentCard.builder()&lt;/code&gt; instead of &lt;code&gt;new AgentCard.Builder()&lt;/code&gt; - applies to all spec classes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Protocol version&lt;/strong&gt;: Update to &lt;code&gt;AgentCard.CURRENT_PROTOCOL_VERSION&lt;/code&gt; (now &lt;code&gt;&quot;1.0&quot;&lt;/code&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Field renames&lt;/strong&gt;: &lt;code&gt;supportsAuthenticatedExtendedCard&lt;/code&gt; → &lt;code&gt;supportsExtendedAgentCard&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Getter naming&lt;/strong&gt;: Records use &lt;code&gt;card.name()&lt;/code&gt; instead of &lt;code&gt;card.getName()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Package cleanup&lt;/strong&gt;: The &lt;code&gt;io.a2a.apec&lt;/code&gt; package has been trimmed&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Serialization&lt;/strong&gt;: If you relied on Jackson annotations, migrate to Gson patterns&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#getting-started&quot;&gt;&lt;/a&gt;Primeiros passos&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Using Maven, add the BOM and dependencies:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;a2a-java-sdk-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.0.0.Alpha1&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;

&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;io.github.a2asdk&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;a2a-java-sdk-reference-jsonrpc&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Creating an agent requires producing an &lt;code&gt;AgentCard&lt;/code&gt; and an &lt;code&gt;AgentExecutor&lt;/code&gt;. The &lt;code&gt;@PublicAgentCard&lt;/code&gt; qualifier marks the public agent card that serves as the entry point for discovery - this is what clients retrieve when discovering your agent. You can also provide an extended agent card with additional authenticated information. Here&amp;#8217;s a minimal example:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@ApplicationScoped
public class MyAgentCardProducer {
    @Produces @PublicAgentCard
    public AgentCard agentCard() {
        return AgentCard.builder()
            .name(&quot;Weather Agent&quot;)
            .description(&quot;Provides weather information&quot;)
            .version(&quot;1.0.0&quot;)
            .capabilities(AgentCapabilities.builder()
                .streaming(true)
                .pushNotifications(false)
                .build())
            .defaultInputModes(List.of(&quot;text&quot;))
            .defaultOutputModes(List.of(&quot;text&quot;))
            .skills(List.of(
                AgentSkill.builder()
                    .id(&quot;weather_query&quot;)
                    .name(&quot;Weather Queries&quot;)
                    .description(&quot;Get current weather for a location&quot;)
                    .build()
            ))
            .protocolVersion(AgentCard.CURRENT_PROTOCOL_VERSION)
            .supportedInterfaces(List.of(
                new AgentInterface(&quot;JSONRPC&quot;, &quot;http://localhost:9999&quot;)
            ))
            .build();
    }
}

@ApplicationScoped
public class MyAgentExecutorProducer {
    @Produces
    public AgentExecutor agentExecutor() {
        return new MyAgentExecutor();
    }

    private static class MyAgentExecutor implements AgentExecutor {
        @Override
        public void execute(RequestContext context, EventQueue eventQueue) {
            TaskUpdater updater = new TaskUpdater(context, eventQueue);
            updater.submit();
            updater.startWork();

            // Your agent logic here
            String response = &quot;Current weather: Sunny, 72°F&quot;;

            updater.addArtifact(List.of(new TextPart(response, null)));
            updater.complete();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For complete examples, see the &lt;a href=&quot;https://github.com/a2aproject/a2a-java/tree/main/examples/helloworld&quot;&gt;Hello World example&lt;/a&gt; in the repository.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;looking-forward&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#looking-forward&quot;&gt;&lt;/a&gt;Looking Forward&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This alpha release brings us significantly closer to a stable 1.0 SDK. Our focus areas for upcoming releases include:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Full compliance with the 1.0 TCK test suite&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Performance optimizations based on real-world usage&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Additional examples and integration guides&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WildFly Feature Pack for seamless Jakarta EE integration&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The A2A specification itself is still evolving toward its 1.0 release. We&amp;#8217;re actively participating in the specification process and will continue aligning the SDK as the spec finalizes.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;get-involved&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#get-involved&quot;&gt;&lt;/a&gt;Get Involved&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We welcome contributions, feedback, and real-world usage reports! If you&amp;#8217;re building AI agents or want to explore multi-agent architectures, the A2A Java SDK provides a solid foundation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href=&quot;https://github.com/a2aproject/a2a-java&quot; class=&quot;bare&quot;&gt;https://github.com/a2aproject/a2a-java&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;a href=&quot;https://github.com/a2aproject/a2a-java/tree/main/examples&quot; class=&quot;bare&quot;&gt;https://github.com/a2aproject/a2a-java/tree/main/examples&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Specification&lt;/strong&gt;: &lt;a href=&quot;https://github.com/a2aproject/A2A&quot; class=&quot;bare&quot;&gt;https://github.com/a2aproject/A2A&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;: &lt;a href=&quot;https://github.com/a2aproject/a2a-java/issues&quot; class=&quot;bare&quot;&gt;https://github.com/a2aproject/a2a-java/issues&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Try out 1.0.0.Alpha1 and let us know how it works for your agent use cases!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 19 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/a2a-java-sdk-1-0-0-alpha1/
            </guid>
            
            
            
            <author>Kabir Khan (https://twitter.com/kabirkhan)</author>
            
        </item>
        
        <item>
            <title>Quarkus Newsletter #64 - January</title>
            <link>
                https://quarkus.io/blog/quarkus-newsletter-64/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out this great &quot;Why Quarkus Finally “Clicks”: The 10 Questions Java Developers Ask Most&quot; by Markus Eisele as it&amp;#8217;s a great field guide based on real conversations at conferences, meetups, and across The Main Thread community. Read &quot;Quarkus Hibernate with Panache Next&quot; by Stéphane Épardaud to learn about the new Hibernate with Panache extension to unify both Hibernate ORM with Panache and Hibernate Reactive with Panache. Want a complete hands-on tutorial for modern, data-oriented application design? Markus Eisele has you covered with &quot;Build Event-Sourced Systems in Quarkus with Java Records and CQRS&quot;. Check out Stéphane Philippart&amp;#8217;s blog post to learn how and why to migrate your Jekyll blog to Quarkus Roq. Read &quot;Modern Java Meets Native Power: Image Processing with the FFM API in Quarkus&quot; by Markus Eisele to see how Java 25 integrates with ImageMagick to unlock fast, safe, zero-JNI native workflows. Want a simple way to disable all endpoints in a Quarkus application based on a configuration property? Check out Damir Arh&amp;#8217;s post &quot;Disable Quarkus endpoints with a request filter&quot; for some great instruction.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You will also see the latest Quarkus Insights episodes, top tweets/discussions and upcoming Quarkus attended events.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://quarkus.io/newsletter/64/&quot;&gt;Newsletter #64: January&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want to get newsletters in your inbox? &lt;a href=&quot;https://quarkus.io/newsletter&quot;&gt;Sign up for the newsletter&lt;/a&gt; using the on page form.&lt;/p&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 15 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-newsletter-64/
            </guid>
            
            
            
            <author>James Cobb (https://twitter.com/insectengine)</author>
            
        </item>
        
        <item>
            <title>Towards faster builds</title>
            <link>
                https://quarkus.io/blog/building-large-applications/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;When we initially released Quarkus, the industry was very much focused on microservices, and that was our primary target.
However, Quarkus is also perfectly suited for large monoliths, whether you are migrating existing applications to a more modern runtime or building new ones from scratch.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus has always been able to handle large applications, but we have recently made significant improvements in this area, particularly when it comes to build times.
In this post, we will walk through some of these improvements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;how-the-story-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-the-story-started&quot;&gt;&lt;/a&gt;How the story started&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once upon a time, I came across &lt;a href=&quot;https://zestedesavoir.com/billets/4876/quarkus-spring-boot-et-les-monolithes/&quot;&gt;an article comparing Spring Boot and Quarkus for building large monoliths&lt;/a&gt; (it&amp;#8217;s in French, apologies to non-French speakers, but the results are largely self-explanatory).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The article compared a Spring Boot application and a Quarkus application implementing the same functionality and even included a generator to create both applications. The generated applications are simple: a few entities, some REST services, and typical CRUD endpoints.
What made it really interesting was that you could easily scale up the number of entities and services to see how both frameworks handled larger applications.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I truly value this kind of feedback: it not only helps us identify areas for improvement, but also provides a reproducible way to explore them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As expected, Quarkus excelled in memory consumption and startup time.
But the build time was noticeably higher than Spring Boot&amp;#8217;s.
Again, this wasn&amp;#8217;t a surprise.
After all, Quarkus shifts more work to build time.
But the difference was still significant enough to warrant a closer look.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Long story short: we investigated and we improved. A lot.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;thanks&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#thanks&quot;&gt;&lt;/a&gt;Thanks&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;First, I would like to thank the author of the original article, SpaceFox, for writing it and for providing such a useful generator.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As is often the case in the Quarkus world, I was not alone on this journey.
I would therefore like to thank everyone who contributed through code, discussions, reviews, insights, and feedback.
In alphabetical order: Tamás Cservenák, Sanne Grinovero, Martin Kouba, David Lloyd, Alexey Loubyansky, Matej Novotny, Yoann Rodière, and Ladislav Thon (and if I missed anyone, please let me know!).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This covers the core Quarkus work, but, as discussed later, several improvements were also made to the &lt;a href=&quot;https://github.com/smallrye/smallrye-open-api&quot;&gt;SmallRye OpenAPI project&lt;/a&gt;.
For those contributions, I would like to thank Mike Edgar and Martin Panzer.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;our-journey-to-faster-builds&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#our-journey-to-faster-builds&quot;&gt;&lt;/a&gt;Our journey to faster builds&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This kind of journey naturally comes with its fair share of profiling and staring at flame graphs.
It&amp;#8217;s not just about spotting the hotspots, but also about evaluating whether your changes actually move the needle (in the right direction, hopefully!).
In the Java world, we&amp;#8217;ve been lucky to have a tool as powerful as &lt;a href=&quot;https://github.com/async-profiler/async-profiler&quot;&gt;Async Profiler&lt;/a&gt; by our side.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As with any optimization effort, the key lies in choosing your battles wisely and carefully weighing the inevitable trade-offs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;code-optimizations&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#code-optimizations&quot;&gt;&lt;/a&gt;Code optimizations&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A lot of effort was invested in optimizing various parts of the build process: reducing memory allocations and optimizing algorithms and data structures were a big part of it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This work resulted in numerous pull requests across Quarkus, Jandex, and even ByteBuddy.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;parallelization&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#parallelization&quot;&gt;&lt;/a&gt;Parallelization&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Our build process is already massively parallelized, but we identified a few areas where this was not the case, for example, the generation of Hibernate ORM proxies. We fixed that.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Another area for improvement was the creation of large JAR archives, which is inherently slow because it involves reading and compressing a significant number of resources, making it both I/O- and CPU-intensive.
Until now, we were building JARs using a ZipFileSystem, adding resources one by one in a single thread.
We have since switched to using the parallel compression support provided by Commons Compress.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This change required some fairly extensive refactoring of the JAR assembly code, but it was definitely worth it.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;doing-less&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#doing-less&quot;&gt;&lt;/a&gt;Doing less&lt;/h3&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All the other optimizations equally benefit Gradle builds, but the following change is specific to Maven as it relates to the Maven default lifecycle.&lt;/p&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;With all these optimizations, the time spent in the various goals of the &lt;code&gt;quarkus-maven-plugin&lt;/code&gt; was cut in half compared to our reference version, 3.25.1.&lt;/strong&gt;
That&amp;#8217;s great&amp;#8230;&amp;#8203; but building our sample application still took around two minutes, which is more than we would like.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s time to step back and look at the bigger picture.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For Quarkus applications, we build our own JARs for two main reasons:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We need to include additional resources and metadata.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We introduced custom JAR packagings designed to improve startup time.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This is the process we optimized by leveraging the parallel compression support provided by Commons Compress.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;However, when using Maven, a Quarkus application is still a traditional &lt;code&gt;jar&lt;/code&gt; Maven project.
It follows the standard lifecycle for the &lt;code&gt;jar&lt;/code&gt; packaging, which means Maven will also build a conventional JAR using the &lt;code&gt;maven-jar-plugin&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Taking a step back, we actually don&amp;#8217;t need this JAR in 99% of cases, so we should avoid building it (while still keeping the flexibility to do so when absolutely necessary).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus 3.31, we introduced the &lt;code&gt;quarkus&lt;/code&gt; packaging, which comes with its own lifecycle.
This packaging is intended to be used only for the Quarkus application module itself.
It automatically binds the goals of the &lt;code&gt;quarkus-maven-plugin&lt;/code&gt;, resulting in less boilerplate in your &lt;code&gt;pom.xml&lt;/code&gt; (and no changes required when new goals are added).
More importantly, it does not bind the &lt;code&gt;maven-jar-plugin&lt;/code&gt; execution, nor the &lt;code&gt;maven-install-plugin&lt;/code&gt;, which leads to significantly faster builds for large applications, and benefits all applications overall.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For newly generated applications, this new &lt;code&gt;quarkus&lt;/code&gt; packaging will be the default.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Once 3.31 is released, you will also be able to switch your existing applications to the new packaging by applying the following changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-diff hljs&quot; data-lang=&quot;diff&quot;&gt;diff --git a/pom.xml b/pom.xml
index 98660b8..3c60220 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,6 +5,7 @@
     &amp;lt;groupId&amp;gt;fr.spacefox.perftests.quarkus&amp;lt;/groupId&amp;gt;
     &amp;lt;artifactId&amp;gt;perftests-quarkus&amp;lt;/artifactId&amp;gt;
     &amp;lt;version&amp;gt;1.0.0-SNAPSHOT&amp;lt;/version&amp;gt;
+    &amp;lt;packaging&amp;gt;quarkus&amp;lt;/packaging&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;

     &amp;lt;properties&amp;gt;
         &amp;lt;compiler-plugin.version&amp;gt;3.14.0&amp;lt;/compiler-plugin.version&amp;gt;
@@ -66,16 +67,6 @@
                 &amp;lt;artifactId&amp;gt;quarkus-maven-plugin&amp;lt;/artifactId&amp;gt;
                 &amp;lt;version&amp;gt;${quarkus.platform.version}&amp;lt;/version&amp;gt;
                 &amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
-                &amp;lt;executions&amp;gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
-                    &amp;lt;execution&amp;gt;
-                        &amp;lt;goals&amp;gt;
-                            &amp;lt;goal&amp;gt;build&amp;lt;/goal&amp;gt;
-                            &amp;lt;goal&amp;gt;generate-code&amp;lt;/goal&amp;gt;
-                            &amp;lt;goal&amp;gt;generate-code-tests&amp;lt;/goal&amp;gt;
-                            &amp;lt;goal&amp;gt;native-image-agent&amp;lt;/goal&amp;gt;
-                        &amp;lt;/goals&amp;gt;
-                    &amp;lt;/execution&amp;gt;
-                &amp;lt;/executions&amp;gt;
             &amp;lt;/plugin&amp;gt;
             &amp;lt;plugin&amp;gt;
                 &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Use the &lt;code&gt;quarkus&lt;/code&gt; packaging instead of the default &lt;code&gt;jar&lt;/code&gt; packaging.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This is important and has been present in the generated projects for quite some time. Add it if not already there.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Drop the goals, they will be handled automatically and we don&amp;#8217;t want to run them twice.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To give you an idea of the impact, in our sample large application, &lt;strong&gt;this change alone reduced the build time from two minutes down to 37 seconds&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;follow-ups&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#follow-ups&quot;&gt;&lt;/a&gt;Follow-ups&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;smallrye-openapi&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#smallrye-openapi&quot;&gt;&lt;/a&gt;SmallRye OpenAPI&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In November 2025, I presented part of this work during the first Quarkus community call (see &lt;a href=&quot;https://github.com/quarkusio/quarkus/discussions/50682&quot;&gt;here&lt;/a&gt; for more information about our community calls).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Following this presentation, Martin Panzer, one of our regular community contributors, opened an &lt;a href=&quot;https://github.com/smallrye/smallrye-open-api/issues/2401&quot;&gt;issue in the SmallRye OpenAPI project&lt;/a&gt; highlighting how slow the build could be for large applications.
He provided a solid reproducer, which enabled Mike Edgar to implement several improvements that significantly reduced the contribution of SmallRye OpenAPI to the overall build time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These changes will directly benefit Quarkus build times, but since SmallRye OpenAPI is also used by other runtimes, they will positively impact the broader Java ecosystem as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The takeaway is simple: when you notice something odd, report it, we might be able to improve it.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;the-infamous-classtoolargeexception&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-infamous-classtoolargeexception&quot;&gt;&lt;/a&gt;The infamous ClassTooLargeException&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus, we generate a significant amount of bytecode, and for large applications you need to be careful, as scale can cause our generated bytecode to hit certain limits (for example, method size or class size limits).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The original French article mentioned hitting such a limit at a particular scale.
To be fair, that scale was already quite large, but it&amp;#8217;s still not ideal to run into an arbitrary limit just because one class happens to push you over the edge.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We recently alleviated this limitation, and Quarkus can now handle much larger applications.
This improvement will also be available in Quarkus 3.31.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;java-25&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#java-25&quot;&gt;&lt;/a&gt;Java 25&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Recently, we have rewritten most of our bytecode generation to use Gizmo 2, which is built on top of the Class-File API.
This work is still ongoing, but key components such as ArC, our CDI implementation, are already relying on it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To preserve compatibility with Java 17 and 21, we currently use a backport of the Class-File API,
but the Class-File API is relying on some classes from the underlying JDK.
Several of these classes have seen significant optimizations in Java 25, and as a result,
our bytecode generation performance improves noticeably when running on Java 25.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As Quarkus 3.31 will provide full support for Java 25, we recommend using it to build your applications and take advantage of these performance improvements.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus has always pushed the boundaries of developer experience: we introduced Dev Mode, pioneered the concept of Dev Services, and much more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But sometimes, improving developer experience means going back to the basics: build times.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;That&amp;#8217;s exactly what we focused on here, and we hope you&amp;#8217;ll enjoy building your Quarkus applications faster (and greener!).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;And if you spot additional opportunities to improve our build process, don&amp;#8217;t hesitate to open an issue: we&amp;#8217;re always happy to hear new ideas.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/building-large-applications/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.6 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-6-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.6, a new maintenance release for our 3.30 stream, and our first release for 2026.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.31 will be released at the end of the month.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.6&quot;&gt;3.30.6&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-6-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>A Better Way of Creating Dev Services</title>
            <link>
                https://quarkus.io/blog/new-dev-services-api/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In Quarkus 3.25, a new API for creating &lt;a href=&quot;https://quarkus.io/guides/dev-services&quot;&gt;Dev Services&lt;/a&gt; was introduced.
This new model fixes a problem where all Dev Services for all tests would start in the JUnit discovery phase, potentially causing port conflicts, configuration cross-talk, and excessive resource usage.
This issue was a side effect of the &lt;a href=&quot;/blog/test-classloading-rewrite&quot;&gt;test classloading rewrite&lt;/a&gt; in Quarkus 3.22.
As well as reducing resource consumption, we also hope the API makes it simpler for extension authors to create Dev Services, and moves some of the heavy lifting around managing discovery and container re-use to Quarkus core.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-changes-for-users&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-changes-for-users&quot;&gt;&lt;/a&gt;What changes for users?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;No action is needed for users.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you have test suites which use multiple profiles or test resources, you should find that you no longer see duplicate containers active at the same time. The containers should launch one after the other.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;However, this depends on the extension, as each needs to be converted to the new model. The Redis, Lambda, Narayana, and Kafka extensions have been converted so far. You can track progress on conversions by following the sub-issues in &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues/45785&quot;&gt;#45785&lt;/a&gt;.
As a workaround, if extensions you depend on have not yet been converted, splitting conflicting tests into separate projects should fix symptoms.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As always, if you spot issues or oddities, please let us know on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;zulip&lt;/a&gt; or &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;raise an issue&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;background&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#background&quot;&gt;&lt;/a&gt;Background&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;All dev services using the old API start in the JUnit discovery phase (as of Quarkus 3.22). This is because they are started during &lt;a href=&quot;https://quarkus.io/guides/reaugmentation#what-is-augmentation&quot;&gt;the augmentation phase&lt;/a&gt;, along with bytecode manipulation and other application initialization steps. When the testing design changed, all augmentation happened at the beginning of the test run, during the JUnit discovery phase. This means all Dev Services also start at the beginning of the test run. If several test classes with different Dev Service configuration are augmented before any tests are run, multiple differently-configured Dev Services may be running at the same time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In the new model, Dev Services are started after the augmentation but before the application&amp;#8217;s actual launch.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-changes-for-extension-owners&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-changes-for-extension-owners&quot;&gt;&lt;/a&gt;What changes for extension owners?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The new Dev Services model maintains backwards compatibility with the old one, so extension owners don&amp;#8217;t &lt;em&gt;need&lt;/em&gt; to do anything. In fact, for the first few releases of the new model, we recommended extension owners definitely did not do anything, while the API stabilised.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Now is a good time for extensions to start moving, so they can take advantage of the more concise programming model and reduced resource usage. This will also resolve some deprecation warnings triggered by the old model. Be aware that extensions which have moved to the new API will no longer work with old versions of Quarkus. 3.25 would be the minimum possible version, and we would recommend setting 3.27 or 3.28 as the minimum version (more on that below).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;principles-of-the-new-design&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#principles-of-the-new-design&quot;&gt;&lt;/a&gt;Principles of the new design&lt;/h3&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dev Services are prepped at build time, but the actual &lt;code&gt;start()&lt;/code&gt; call happens post-build, pre-runtime&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do not use static variables in the extension processor&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dev Service creation is handled by a builder (and there are different builders for connecting to an externally-managed instance and creating a new service)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Config which is only known after the service is started can be passed in using a &lt;code&gt;configProvider()&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;migration-checklist&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#migration-checklist&quot;&gt;&lt;/a&gt;Migration checklist&lt;/h3&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Update your extension&amp;#8217;s build file so it depends on both the &lt;code&gt;quarkus-devservices&lt;/code&gt; runtime and &lt;code&gt;quarkus-devservices-deployment&lt;/code&gt; modules (but see &lt;a href=&quot;#version-dilemma&quot;&gt;the discussion of choosing a Quarkus version&lt;/a&gt; for implications of this).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Provide &lt;a href=&quot;#startable&quot;&gt;an implementation&lt;/a&gt; of &lt;code&gt;io.quarkus.deployment.builditem.Startable&lt;/code&gt; which has methods for starting and stopping the new service. For container-based services, extending &lt;code&gt;GenericContainer&lt;/code&gt; and implementing &lt;code&gt;Startable&lt;/code&gt; is a good pattern.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Instead of directly constructing a &lt;code&gt;DevServicesResultBuildItem&lt;/code&gt;, switch to use the &lt;code&gt;discovered()&lt;/code&gt; and &lt;code&gt;owned()&lt;/code&gt; &lt;a href=&quot;#the-builder&quot;&gt;builders&lt;/a&gt; on &lt;code&gt;DevServicesResultBuildItem&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It is not necessary to call all methods on the builder, but either for owned services, &lt;code&gt;startable()&lt;/code&gt;, &lt;code&gt;serviceName()&lt;/code&gt;, &lt;code&gt;configProvider()&lt;/code&gt;, and &lt;a href=&quot;#eligibility-for-reuse&quot;&gt;&lt;code&gt;serviceConfig()&lt;/code&gt;&lt;/a&gt; are almost always needed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check code for anti-patterns&lt;/p&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Extension code should never stop or start the Dev Service&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove shutdown listeners; cleanup should be handled in the &lt;code&gt;stop()&lt;/code&gt; method of the service&amp;#8217;s &lt;code&gt;Startable&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;RunningDevService&lt;/code&gt; type should never be used in the new model&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remove &lt;a href=&quot;#static-fields&quot;&gt;static variables&lt;/a&gt; in the extension processor (such as pointers to a service instance)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do not try and set configuration for accessing the new service directly using system properties or other overrides; use &lt;code&gt;configProvider()&lt;/code&gt; instead&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;more-migration-details&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#more-migration-details&quot;&gt;&lt;/a&gt;More migration details&lt;/h3&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;static-fields&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#static-fields&quot;&gt;&lt;/a&gt;Get rid of static fields on the extension processor&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Extension authors should not rely on static variables for cross-instance communication. They should not assume that the invocation order of processors will be the same as the run order of applications.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://quarkus.io/guides/writing-extensions#injection&quot;&gt;extension writing guide&lt;/a&gt; says “State should only be communicated between build steps by way of build items, even if the steps are on the same class.”
However, almost every Dev Service implementation broke this rule, and used a static field to track previously-created services.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A good heuristic when migrating to the new model is that all static fields should go away. For example, remove all fields like these ones:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;private static volatile RunningDevService devService;
private static volatile MyDevServicesConfig capturedDevServicesConfiguration;
private static volatile boolean first = true;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Deciding whether to re-use or replace a service is now &lt;a href=&quot;#eligibility-for-reuse&quot;&gt;handled centrally&lt;/a&gt;, based on a diff of the configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;get-rid-of-shutdown-logic&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#get-rid-of-shutdown-logic&quot;&gt;&lt;/a&gt;Get rid of shutdown logic&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Because service lifecycle is handled centrally, any shutdown listeners or other logic for stopping services should also be removed.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;remove-any-references-to-runningdevservice&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#remove-any-references-to-runningdevservice&quot;&gt;&lt;/a&gt;Remove any references to &lt;code&gt;RunningDevService&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Because the processor does not handle starting the service, it should never return a &lt;code&gt;RunningDevService&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;the-builder&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-builder&quot;&gt;&lt;/a&gt;Use the builder&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Instead of direct construction, use the new builder API. Choose &lt;code&gt;owned()&lt;/code&gt; for services which are to be created,
or &lt;code&gt;discovered()&lt;/code&gt; to register externally-managed services which have been discovered.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;    DevServicesResultBuildItem = DevServicesResultBuildItem.owned()
                    .feature(MY_FEATURE_NAME)
                    .serviceName(name)
                    .serviceConfig(myConfig)
                    .startable(() -&amp;gt; new MyContainer(
                            myImageName,
                            myConfig.port(),
                            useSharedNetwork)
                            .withEnv(myConfig.containerEnv())
                     .configProvider(
                            Map.of(someProp, s -&amp;gt; s.getConnectionInfo()))
                    .build());&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;eligibility-for-reuse&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#eligibility-for-reuse&quot;&gt;&lt;/a&gt;Eligibility for re-use&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;How does the central lifecycle management decide whether a service can be re-used? This is based on &apos;sameness keys&apos; (the config objects) passed in to the builder to use as the basis for the comparison.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The key method is &lt;code&gt;.serviceConfig(myConfig)&lt;/code&gt;. The current config is compared reflectively to the config of running services each restart.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;startable&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#startable&quot;&gt;&lt;/a&gt;The &lt;code&gt;Startable&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In order to support lazy starting, pass an implementation of &lt;code&gt;Startable&lt;/code&gt; to the builder.
(In case it&amp;#8217;s not obvious, do &lt;strong&gt;not&lt;/strong&gt; call &lt;code&gt;start()&lt;/code&gt; on your &lt;code&gt;Startable&lt;/code&gt;. The Quarkus infrastructure will start your service at the appropriate time.)
(In case it&amp;#8217;s not obvious, do &lt;strong&gt;not&lt;/strong&gt; call &lt;code&gt;start()&lt;/code&gt; on your &lt;code&gt;Startable&lt;/code&gt;. The Quarkus infrastructure will start your service at the appropriate time.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For container-based services, it&amp;#8217;s usually convenient to extend &lt;code&gt;GenericContainer&lt;/code&gt;.
In that case, there&amp;#8217;s not even any need to implement &lt;code&gt;start()&lt;/code&gt;.
Most Dev Services implementations already provide a subclass of &lt;code&gt;GenericContainer&lt;/code&gt;, so the diff is just to add &lt;code&gt;implements Startable&lt;/code&gt; and then add a &lt;code&gt;close()&lt;/code&gt; method. The &lt;code&gt;close&lt;/code&gt; method can delegate to the superclass.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;private static class MyContainer extends GenericContainer&amp;lt;MyContainer&amp;gt; implements Startable {

        private final OptionalInt fixedExposedPort;

        private final String hostName;

        public MyContainer(String imageName, OptionalInt fixedExposedPort) {
            super(imageName);
            this.fixedExposedPort = fixedExposedPort;

            this.hostName =  ...

        }

        @Override
        protected void configure() {
            super.configure();

            if (fixedExposedPort.isPresent()) {
                addFixedExposedPort(fixedExposedPort.getAsInt(), DEFAULT_PORT);
            } else {
                addExposedPort(DEFAULT_PORT);
            }
        }

        public int getPort() {
            if (fixedExposedPort.isPresent()) {
                return fixedExposedPort.getAsInt();
            }
            return super.getFirstMappedPort();
        }

        // This looks strange, but is needed to satisfy the interface
        @Override
        public void close() {
            super.close();
        }

        @Override
        public String getConnectionInfo() {
            return getHost() + &quot;:&quot; + getPort();
        }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;version-dilemma&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#version-dilemma&quot;&gt;&lt;/a&gt;Dependency changes and setting a minimum Quarkus version&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This bit is a bit awkward, unfortunately! In Quarkus 3.28, a new &lt;code&gt;devservices&lt;/code&gt; runtime module was introduced. Most extensions have both a deployment and a runtime module, but historically, Dev Services only had a deployment module. The associated runtime classes lived in other modules. A runtime module was added in 3.28. Because it was a potentially disruptive change, it was done post-LTS. That seemed like a good idea, but it had some unexpected consequences.
The introduction of the new module was done in a way which preserved backwards compatibility, but not forward compatibility. That means extensions built against 3.27 will work with the 3.27 LTS, but not 3.28 or later versions. Extensions built with 3.28 will work with 3.27, and also 3.28 and later versions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For this reason, you should either create branches for 3.27 and 3.28+ versions of the extension, or just build against 3.28. If you build against 3.28, you will need to manually set the minimum Quarkus version in the extension metadata, so that the Quarkus tooling recognises the extension as compatible with 3.27.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-yaml hljs&quot; data-lang=&quot;yaml&quot;&gt;  requires-quarkus-core: &quot;[3.27,)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you do decide to build against 3.28, add the following to the &lt;code&gt;pom.xml&lt;/code&gt; of your runtime module:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-xml hljs&quot; data-lang=&quot;xml&quot;&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;io.quarkus&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;quarkus-devservices&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;faqs&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#faqs&quot;&gt;&lt;/a&gt;FAQs&lt;/h3&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;how-can-i-have-a-build-step-do-something-after-a-dev-service-is-started&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-can-i-have-a-build-step-do-something-after-a-dev-service-is-started&quot;&gt;&lt;/a&gt;How can I have a build step do something after a Dev Service is started?&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This isn’t possible, because a dev service would never be started in the build phase. However, the &lt;code&gt;postStartHook&lt;/code&gt; on the builder allows you to take actions once the dev service is started.
To pass configuration to the application, you can
&lt;a href=&quot;https://quarkus.io/guides/writing-extensions#injecting-configuration-into-recorders&quot;&gt;use recorders&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In general, the Quarkus philosophy is to move work from application start to build-time, not the other way round. If you do need to move work into a &lt;code&gt;postStartHook&lt;/code&gt; or recorder, try to move as little as possible, to avoid negative performance impacts. Often, code needs to know that a Dev Service &lt;strong&gt;will&lt;/strong&gt; be created, but not the actual address. This can be handled as part of the normal build flow using a marker build item, leaving the bare minimum to execute as part of the hook.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect3&quot;&gt;
&lt;h4 id=&quot;how-can-i-publish-links-to-my-service-in-the-dev-ui&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#how-can-i-publish-links-to-my-service-in-the-dev-ui&quot;&gt;&lt;/a&gt;How can I publish links to my service in the Dev UI?&lt;/h4&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If your service has an admin console, it&amp;#8217;s a nice pattern to publish a link to it in the Dev UI.
With the old Dev Services model, you might customise your extensions&amp;#8217;s card with code something like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;   @BuildStep(onlyIf = IsDevelopment.class)
   public CardPageBuildItem pages(List&amp;lt;SomeRelevantBuildItem&amp;gt; containers) {
      CardPageBuildItem cardPageBuildItem = new CardPageBuildItem();

      for (SomeRelevantBuildItem container : containers) {
         cardPageBuildItem.addPage(Page.externalPageBuilder(&quot;My Extension Name&quot;)
               .url(container.getTheUrl())
               .staticLabel(container.label());
      }

      return cardPageBuildItem;
   }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This will no longer work, because the url isn&amp;#8217;t known at build time.
Instead, replace the &lt;code&gt;url&lt;/code&gt; method with &lt;code&gt;dynamicUrlJsonRPCMethodName&lt;/code&gt;, &lt;a href=&quot;/guides/dev-ui#runtime-external-links&quot;&gt;passing in an RPC method name&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;     .dynamicUrlJsonRPCMethodName(&quot;getMyUrl&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;From 3.32, you can also pass through parameters on the method call. For example,&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;     .dynamicUrlJsonRPCMethodName(&quot;getMyUrl&quot;, Map.of(&quot;name&quot;, &quot;service-name&quot;, &quot;configKey&quot;, &quot;some-key&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Add a build step to register the providing class:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;    @BuildStep(onlyIf = IsLocalDevelopment.class)
    public JsonRPCProvidersBuildItem createJsonRPCService() {
     return new JsonRPCProvidersBuildItem(MyJsonRPCService.class, BuiltinScope.SINGLETON.getName());
    }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In your extension&amp;#8217;s runtime module, create a &lt;code&gt;MyJsonRPCService&lt;/code&gt; class with a &lt;code&gt;getMyUrl&lt;/code&gt; method.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;examples&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#examples&quot;&gt;&lt;/a&gt;Exemplos&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Sometimes it&amp;#8217;s easier to see what needs to be done in a diff.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For an example using a dev service which isn’t container-based, see the &lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/48753/files&quot;&gt;Lambda conversion&lt;/a&gt;. For a more complex conversion which uses compose, reuses existing external containers, and does post-start configuration, see just the &lt;code&gt;KafkaDevServicesProcessor&lt;/code&gt; part of the &lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/48445/files#diff-77328c7968b5b6e5280c55994dd56cd1da637e84b1fecd751d6130e78840aefd&quot;&gt;Kafka conversion&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/orgs/quarkusio/projects/49&quot;&gt;working group for Dev Services lifecycle&lt;/a&gt; is still underway, and welcomes contributions.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/new-dev-services-api/
            </guid>
            
            
            
            <author>Holly Cummins (https://twitter.com/holly_cummins)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.5 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-5-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.5, a new maintenance release for our 3.30 stream, and our last release for 2025.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;See you all next year!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.5&quot;&gt;3.30.5&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 24 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-5-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus Hibernate with Panache Next</title>
            <link>
                https://quarkus.io/blog/hibernate-panache-next/
            </link>
            <description>
                &lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;introducing-a-new-version-of-panache&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#introducing-a-new-version-of-panache&quot;&gt;&lt;/a&gt;Introducing a new version of Panache&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;…which was never called Panache, by the way, it was called Hibernate ORM with Panache,
or Hibernate Reactive with Panache, and this new version, is a new module, designed to
unify both, and is currently called &lt;a href=&quot;https://quarkus.io/version/main/guides/hibernate-panache-next&quot;&gt;Hibernate with Panache&lt;/a&gt;
(although the name could change).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Anyway, first a disclaimer: this is a new extension, which is experimental, which means everything
about it can (and probably will) change: the extension name, the package names, the class names
and even the API. We are releasing it because we feel it&amp;#8217;s in a good shape to be tested and discussed
by the community, and we hope to get better feedback before we commit to anything like names or
API.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Please report feedback either on &lt;a href=&quot;https://quarkusio.zulipchat.com/#narrow/channel/187038-dev/topic/WG.20-.20Panache.2ENext/with/562916276&quot;&gt;Zulip&lt;/a&gt;
or via &lt;a href=&quot;https://github.com/orgs/quarkusio/projects/50/views/1&quot;&gt;GitHub issues&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;what-was-wrong-with-the-old-panache-apis&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#what-was-wrong-with-the-old-panache-apis&quot;&gt;&lt;/a&gt;What was wrong with the old Panache APIs?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Mostly it&amp;#8217;s fine, but it has a few drawbacks that are definitely annoying and dated:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We have two &lt;a href=&quot;https://quarkus.io/guides/hibernate-orm-panache&quot;&gt;competing&lt;/a&gt; and
&lt;a href=&quot;https://quarkus.io/guides/hibernate-reactive-panache&quot;&gt;incompatible&lt;/a&gt; APIs depending on whether we want to use blocking or non-blocking database
drivers. The recent support of mixing Hibernate ORM and Hibernate Reactive in Quarkus means people no longer want
to be blocked having to choose which entity type to extend, between the blocking &lt;code&gt;PanacheEntity&lt;/code&gt; and its non-blocking
counterpart.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Both Hibernate ORM with Panache and its Hibernate Reactive counterpart only support managed entities, and we want
to add support for stateless entities (using &lt;code&gt;StatelessSession&lt;/code&gt;), but we cannot do that with the current Panache API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We want to add support for &lt;a href=&quot;https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0&quot;&gt;Jakarta Data&lt;/a&gt;,
which allows defining type-safe queries using annotations, which are
checked at build time, but the current
&lt;a href=&quot;https://quarkus.io/guides/hibernate-orm-panache#solution-1-using-the-active-record-pattern&quot;&gt;&lt;em&gt;active record&lt;/em&gt;&lt;/a&gt;
version of Panache entities does not easily support this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We currently have a split between &lt;em&gt;active record&lt;/em&gt; and
&lt;a href=&quot;https://quarkus.io/guides/hibernate-orm-panache#solution-2-using-the-repository-pattern&quot;&gt;&lt;em&gt;repository&lt;/em&gt;&lt;/a&gt; modes of
operations, which is not satisfactory, and can be confusing to new users.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The static methods of &lt;em&gt;active record&lt;/em&gt; entities have a hole in their types which require they be either assigned to
known types (not &lt;code&gt;var&lt;/code&gt;) or have their type arguments explicitly specified.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Method pointers cannot be used on the static methods of &lt;em&gt;active record&lt;/em&gt; entities, causing confusion.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;I could spend a long time explaining each of these issues, and the many things we experimented on to fix them, but
you&amp;#8217;re probably more interested in what we came up with.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;so-whats-this-new-api&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#so-whats-this-new-api&quot;&gt;&lt;/a&gt;So, what&amp;#8217;s this new API?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s a new Quarkus extension, and it lets you specify your entity in a way which allows you to use it using a blocking
JDBC driver, or a Reactive driver, as a managed entity, or as a stateless entity, with type-safe queries, or non-type-safe
queries. It&amp;#8217;s very flexible and it&amp;#8217;s still clearly a continuation of the old Panache APIs, with a dash of
&lt;a href=&quot;https://jakarta.ee/specifications/data/1.0/jakarta-data-1.0&quot;&gt;Jakarta Data&lt;/a&gt;
and all mixed in a way that we hope you will like.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/version/main/guides/hibernate-panache-next&quot;&gt;The documentation&lt;/a&gt; has a lot of
information as to how to set it up, and all the options, so I will focus on some
bite-sized samples for this blog post. Here&amp;#8217;s your first entity with type-safe queries:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Entity
public class Cat extends PanacheEntity {
    public String name;
    public LocalDate birth;
    public Breed breed;

    public enum Breed {
        CUTE, HAIRLESS;
    }

    public interface Repo extends PanacheRepository&amp;lt;Cat&amp;gt; {
        @Find
        Cat findByName(String name);

        @HQL(&quot;where breed = CUTE&quot;)
        List&amp;lt;Cat&amp;gt; findCute();

        @HQL(&quot;delete from Cat where name = :name&quot;)
        long deleteByName(String name);

        @HQL(&quot;delete from Cat where breed = HAIRLESS&quot;)
        long deleteHairless();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Here&amp;#8217;s what you can notice right away:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Your entity extends &lt;code&gt;PanacheEntity&lt;/code&gt; (a familiar type, but in a new package), which means: by default it&amp;#8217;s blocking and
managed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Its operations are defined in a repository that is conveniently nested in the entity. No more mixing instance
entity methods and &lt;code&gt;static&lt;/code&gt; methods, and yet you retain the close proximity of these operations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can define type-safe operations with &lt;code&gt;@Find&lt;/code&gt; and &lt;code&gt;@HQL&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You still have all the Panache type-unsafe operations in the &lt;code&gt;PanacheRepository&lt;/code&gt; supertype.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You could use it like this:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;    @Inject
    Cat.Repo repo;

    @Transactional
    public void method() {
        Cat cat = new Cat();
        cat.name = &quot;Lucky&quot;;
        cat.birth = LocalDate.of(2015, 01, 12);
        cat.breed = Cat.Breed.CUTE;

        // Persist the cat
        cat.persist();

        // Make a change, no need to update it
        cat.name = &quot;Luckynou&quot;;

        // Find our cat
        cat = repo.findByName(&quot;Luckynou&quot;);

        // Find cute cats
        List&amp;lt;Cat&amp;gt; cuteCats = repo.findCute();

        // Delete our cat
        cat.delete();

        // Delete queries
        repo.deleteByName(&quot;Lucky&quot;);
        repo.deleteHairless();
    }&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But if you find injecting the repository disruptive, you can also access it using the generated metamodel accessor
&lt;code&gt;Cat_.repo()&lt;/code&gt;, which is super handy for completion and API discovery.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;heres-where-it-gets-better&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#heres-where-it-gets-better&quot;&gt;&lt;/a&gt;Here&amp;#8217;s where it gets better&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want a reactive version of your entity for stateless sessions?&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Entity
public class Cat extends WithId.AutoLong implements PanacheEntity.Reactive.Stateless {
    public String name;
    public LocalDate birth;
    public Breed breed;

    public enum Breed {
        CUTE, HAIRLESS;
    }

    public interface Repo extends PanacheRepository.Reactive.Stateless&amp;lt;Cat, Long&amp;gt; {
        @Find
        Uni&amp;lt;Cat&amp;gt; findByName(String name);

        @HQL(&quot;where breed = CUTE&quot;)
        Uni&amp;lt;List&amp;lt;Cat&amp;gt;&amp;gt; findCute();

        @HQL(&quot;delete from Cat where name = :name&quot;)
        Uni&amp;lt;Integer&amp;gt; deleteByName(String name);

        @HQL(&quot;delete from Cat where breed = HAIRLESS&quot;)
        Uni&amp;lt;Integer&amp;gt; deleteHairless();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;It&amp;#8217;s a bit longer, at the moment, but bear with us. Here&amp;#8217;s the run-down:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You extend &lt;code&gt;WithId.AutoLong&lt;/code&gt; if you want a generated &lt;code&gt;Long&lt;/code&gt; identifier.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You implement &lt;code&gt;PanacheEntity.Reactive.Stateless&lt;/code&gt; to get reactive stateless operations by default.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your repository implements &lt;code&gt;PanacheRepository.Reactive.Stateless&lt;/code&gt; to get reactive stateless operations by default.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your queries return &lt;code&gt;Uni&lt;/code&gt; for non-blocking operation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Otherwise, it&amp;#8217;s the same API. Pick which mode of operation you want your entities to be based on by default. Mix and
match modes for different entities if you want.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;heres-where-it-gets-really-better&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#heres-where-it-gets-really-better&quot;&gt;&lt;/a&gt;Here&amp;#8217;s where it gets really better&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s say you declared your entity to be blocking and managed, but you want to also access it for a reactive and
stateless part of your API.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can always access every mode of operation on your entity or repository using supertype methods:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;public class Code {

    // By default, the Cat is blocking and managed
    @Transactional
    public void blockingManagedMethod() {
        Cat cat = new Cat();
        cat.name = &quot;Lucky&quot;;
        cat.birth = LocalDate.of(2015, 01, 12);
        cat.breed = Cat.Breed.CUTE;

        // Persist the cat
        cat.persist();

        // Make a change, no need to update it
        cat.name = &quot;Luckynou&quot;;
    }

    // But we can always call statelessReactive() and use reactive and stateless operations
    @WithTransaction
    public Uni&amp;lt;Void&amp;gt; reactiveStatelessMethod(Long catId) {
        Cat cat = new Cat();
        cat.name = &quot;Lucky&quot;;
        cat.birth = LocalDate.of(2015, 01, 12);
        cat.breed = Cat.Breed.CUTE;

        // Insert the cat
        return cat.statelessReactive().insert()
                .chain(() -&amp;gt; {
                    // Make a change, we need to update it
                    cat.name = &quot;Luckynou&quot;;
                    return cat.statelessReactive().update();
                });

    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can even define multiple repositories for your different modes of operations:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;@Entity
public class Cat extends PanacheEntity {
    public String name;
    public LocalDate birth;
    public Breed breed;

    public enum Breed {
        CUTE, HAIRLESS;
    }

    public interface Repo extends PanacheRepository&amp;lt;Cat&amp;gt; {
        @Find
        Cat findByName(String name);
    }

    public interface TheOtherRepo extends PanacheRepository.Reactive.Stateless&amp;lt;Cat, Long&amp;gt; {
        @Find
        Uni&amp;lt;Cat&amp;gt; findByName(String name);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;merry-christmas&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#merry-christmas&quot;&gt;&lt;/a&gt;Merry Christmas&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Just in time for the holidays, we&amp;#8217;re merging this to &lt;code&gt;main&lt;/code&gt; so it will be in a release near you very soon.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Give it a try, &lt;a href=&quot;https://quarkus.io/version/main/guides/hibernate-panache-next&quot;&gt;read the documentation&lt;/a&gt;, and give us feedback either on
&lt;a href=&quot;https://quarkusio.zulipchat.com/#narrow/channel/187038-dev/topic/WG.20-.20Panache.2ENext/with/562916276&quot;&gt;Zulip&lt;/a&gt;
or via &lt;a href=&quot;https://github.com/orgs/quarkusio/projects/50/views/1&quot;&gt;GitHub issues&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 24 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/hibernate-panache-next/
            </guid>
            
            
            
            <author>Stéphane Épardaud (https://twitter.com/UnFroMage)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.4 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-4-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.4, a new maintenance release for our 3.30 stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.4&quot;&gt;3.30.4&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 17 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-4-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus feature flags</title>
            <link>
                https://quarkus.io/blog/quarkus-feature-flags/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Feature flags are a proven and popular technique.
In essence, a feature flag makes it possible to turn on-off and/or configure a specific functionality in your application.
It is also referred to as toggles or switches.
There are many types of feature flags.
You may have heard of a &quot;killer switch&quot; that simply disables a problematic feature instantly.
Feature flags can be used to implement &quot;gradual rollout&quot; to deliver new features gradually to small groups of users (aka beta testers).
Permission flags are used to control access for different users.
And so on.
However, that&amp;#8217;s not the subject of this blogpost.
We would like to introduce &lt;a href=&quot;https://github.com/quarkiverse/quarkus-flags/&quot;&gt;Quarkus Feature Flags&lt;/a&gt; - a Quarkiverse project that aims to provide a &lt;em&gt;lightweight&lt;/em&gt; and &lt;em&gt;extensible&lt;/em&gt; feature flags Quarkus extension.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;More specifically, it provides:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A blocking/non-blocking API to access feature flags.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A non-blocking SPI to provide flags and externalize the computation of a flag value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Several built-in flag providers:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quarkus config can be used to define feature flags,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An in-memory flag repository which is useful for testing and dynamic registration of flags.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hibernate ORM&lt;/strong&gt; module, where feature flags are mapped from an annotated entity and are automatically loaded from the database.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt; module, so that it&amp;#8217;s possible to evaluate flags based on the current &lt;code&gt;SecurityIdentity&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Qute&lt;/strong&gt; module, so that it&amp;#8217;s possible to use the flags directly in templates.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CRON&lt;/strong&gt; module with a flag evaluator that matches a specific CRON expression.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that the goal of this extension is not to replace robust solutions such as &lt;a href=&quot;https://openfeature.dev/&quot;&gt;OpenFeature&lt;/a&gt; and &lt;a href=&quot;https://www.getunleash.io/&quot;&gt;Unleash&lt;/a&gt;.
Instead, we would like to offer a flexible option that integrates well with other parts of the Quarkus ecosystem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;flag&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#flag&quot;&gt;&lt;/a&gt;Flag&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this extension, a feature flag is represented by the &lt;code&gt;io.quarkiverse.flags.Flag&lt;/code&gt; interface.
It refers to a specific feature with a string identifier and provides several convenient methods to compute the &lt;em&gt;current value&lt;/em&gt;.
The value of a feature flag can be represented as &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;integer&lt;/code&gt;.
There can be only one flag for a given feature at a given time.
A flag can also expose metadata which that can be leveraged in the SPI.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;simple-example&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#simple-example&quot;&gt;&lt;/a&gt;Simple example&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Let&amp;#8217;s start simple.
We will create a flag for a feature called &lt;code&gt;my-feature-alpha&lt;/code&gt; in the &lt;code&gt;application.properties&lt;/code&gt; file.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.value=true &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Define a &lt;em&gt;runtime&lt;/em&gt; flag for feature &lt;code&gt;my-feature-alpha&lt;/code&gt; with initial value &lt;code&gt;true&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock tip&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-tip&quot; title=&quot;Tip&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
A &lt;code&gt;runtime&lt;/code&gt; feature flag can be overriden at runtime, e.g. using a system property or an environment variable. You can also define a flag fixed at build time, i.e. &lt;code&gt;quarkus.flags.build.&quot;my-feature-alpha&quot;.value=true&lt;/code&gt;. However, its values ​​cannot be modified at runtime.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;io.quarkiverse.flags.Flags&lt;/code&gt; interface represents the central point to access feature flags.
The container registers a CDI bean that implements &lt;code&gt;Flags&lt;/code&gt; automatically.
Therefore, we will simply inject &lt;code&gt;Flags&lt;/code&gt; and use one of its convenient methods.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;package org.example;

import io.quarkiverse.flags.Flags;
import jakarta.inject.Inject;

@ApplicanScoped
public class MyService {

    @Inject
    Flags flags;

    void call() {
        if (flags.isEnabled(&quot;my-feature-alpha&quot;)) {
            // This business logic is executed only if &quot;my-feature-alpha&quot; value evaluates to true
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can also access the flag in your UI built with Qute:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-html hljs&quot; data-lang=&quot;html&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
   &amp;lt;title&amp;gt;Flags&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
   &amp;lt;h1&amp;gt;Hello - Quarkus Club 2025&amp;lt;/h1&amp;gt;
   {#if flag:enabled(&apos;my-feature-alpha&apos;)} &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
   &amp;lt;p&amp;gt;Feature alpha is enabled!
   {/if}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;flag:&lt;/code&gt; namespace provides other useful properties and methods.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
If you want to use the Qute integration in your application then you&amp;#8217;ll need to add the &lt;code&gt;io.quarkiverse.flags:quarkus-flags-qute&lt;/code&gt; extension to your build file first.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;flag-providers&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#flag-providers&quot;&gt;&lt;/a&gt;Flag providers&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So far we defined the flag in the Quarkus config.
This is not very flexible.
Let&amp;#8217;s try some other built-in flag providers.
We can use the &lt;code&gt;io.quarkiverse.flags.InMemoryFlagProvider&lt;/code&gt; - an in-memory repository that can be useful for testing and dynamic registration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;import io.quarkiverse.flags.BooleanValue;
import io.quarkiverse.flags.Flag;
import io.quarkiverse.flags.InMemoryFlagProvider;
import io.quarkus.runtime.Startup;
import jakarta.inject.Inject;

@ApplicationScoped
public class MyInitService {

   AtomicBoolean alpha = new AtomicBoolean();

   @Inject
   InMemoryFlagProvider provider; &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;

   @Startup &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
   void addFlags() {
      provider.addFlag(Flag.builder(&quot;my-feature-alpha&quot;) &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
            .setCompute(ctx -&amp;gt; BooleanValue.from(alpha.get())) &lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;
            .build());
   }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Inject &lt;code&gt;InMemoryFlagProvider&lt;/code&gt; to add/remove flags.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;This method is automatically executed at application startup.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;InMemoryFlagProvider&lt;/code&gt; has higher priority and overrides the flag provided in config.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current value of &lt;code&gt;my-feature-alpha&lt;/code&gt; is calculated from &lt;code&gt;MyInitService#alpha&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This way we can control the current value of &lt;code&gt;my-feature-alpha&lt;/code&gt; easily.
However, in real use cases we will probably need to persist the feature flags in an external system.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-flags/dev/hibernate-orm.html&quot;&gt;&lt;code&gt;quarkus-flags-hibernate-orm&lt;/code&gt; extension&lt;/a&gt; provides integration with Hibernate ORM.
It discovers all JPA entities annotated with &lt;code&gt;@io.quarkiverse.flags.hibernate.common.FlagDefinition&lt;/code&gt; and generates a flag provider automatically.
The generated provider simply loads all flags from the database.
A mapping looks like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-java hljs&quot; data-lang=&quot;java&quot;&gt;import jakarta.persistence.Entity;

import io.quarkiverse.flags.hibernate.common.FlagDefinition;
import io.quarkiverse.flags.hibernate.common.FlagFeature;
import io.quarkiverse.flags.hibernate.common.FlagValue;
import io.quarkus.hibernate.orm.panache.PanacheEntity;

@FlagDefinition &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
@Entity
public class MyFlag extends PanacheEntity {

    @FlagFeature &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
    public String feature;

    @FlagValue &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
    public String value;

}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Marks a flag definition entity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Defines the feature name of a feature flag.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Defines the value of a feature flag.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock tip&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-tip&quot; title=&quot;Tip&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
The feature flags are collected at runtime. More specifically, the extension injects all CDI beans that implement &lt;code&gt;io.quarkiverse.flags.spi.FlagProvider&lt;/code&gt; and calls the &lt;code&gt;FlagProvider#getFlags()&lt;/code&gt; method. You can easily implement your own provider.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;flag-evaluators&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#flag-evaluators&quot;&gt;&lt;/a&gt;Flag evaluators&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In real applications, you will very likely need some dynamic evaluation logic based on some application state, such as the current user or current time.
There is the &lt;code&gt;io.quarkiverse.flags.spi.FlagEvaluator&lt;/code&gt; SPI which makes it possible to externalize the computation of the current value of a feature flag.
Flag evaluators must be CDI beans.
By default, a flag can reference one &lt;code&gt;FlagEvaluator&lt;/code&gt; in its &lt;em&gt;metadata&lt;/em&gt; with a key &lt;code&gt;evaluator&lt;/code&gt;. This evaluator is automatically used to compute the current value for any flag produced by means of &lt;code&gt;Flag.Builder&lt;/code&gt; (i.e. created by &lt;code&gt;Flag#builder(String)&lt;/code&gt;).
There are also several built-in evaluators available.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;current-time&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#current-time&quot;&gt;&lt;/a&gt;Current time&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;io.quarkiverse.flags.TimeSpanFlagEvaluator&lt;/code&gt; evaluates a flag based on the current date-time obtained from the system clock in the default time-zone.
The current time must be after the &lt;code&gt;start-time&lt;/code&gt; (exclusive) and before the &lt;code&gt;end-time&lt;/code&gt; (exclusive).&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.evaluator=quarkus.time-span &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.start-time=2001-01-01T10:15:30+01:00[Europe/Prague] &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt; &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Assign the evaluator to the flag. Note that we do not specify the initial value for &lt;code&gt;my-feature-alpha&lt;/code&gt; - it is &lt;code&gt;true&lt;/code&gt; by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current date-time must be &lt;strong&gt;after&lt;/strong&gt; the specified &lt;code&gt;start-time&lt;/code&gt;. The &lt;code&gt;java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME&lt;/code&gt; is used to parse the &lt;code&gt;start-time&lt;/code&gt; value.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;We do not specify the &lt;code&gt;end-time&lt;/code&gt; metadata value, so there is no upper bound for the time inverval.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;current-user&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#current-user&quot;&gt;&lt;/a&gt;Current user&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;SecurityIdentityFlagEvaluator&lt;/code&gt; from the &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-flags/dev/security.html&quot;&gt;&lt;code&gt;quarkus-flags-security&lt;/code&gt; extension&lt;/a&gt; can be used to compute the current value of a feature flag based on the current &lt;code&gt;SecurityIdentity&lt;/code&gt;.
A typical feature flag configuration looks like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.evaluator=quarkus.security.identity &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.authenticated=true &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.roles-allowed=foo,bar &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Assign the evaluator to the flag. Note that we do not specify the initial value for &lt;code&gt;my-feature-alpha&lt;/code&gt; - it is &lt;code&gt;true&lt;/code&gt; by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current user must be authenticated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current user must have one of the defined roles.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;code&gt;UsernameRolloutFlagEvaluator&lt;/code&gt;, on the other hand, is an evaluator using a simple percentage-based rollout strategy, based on a consistent numerical representation of the current user name.
It can be used to implement gradual rollout.
A typical feature flag configuration may look like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.evaluator=quarkus.security.username-rollout &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.rollout-percentage=20 &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Assign the evaluator to the flag. Note that we do not specify the initial value for &lt;code&gt;my-feature-alpha&lt;/code&gt; - it is &lt;code&gt;true&lt;/code&gt; by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Enable the flag for the given percentage of users.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;cron&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#cron&quot;&gt;&lt;/a&gt;CRON&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-flags/dev/cron.html&quot;&gt;quarkus-flags-cron&lt;/a&gt; extension provides the &lt;code&gt;CronFlagEvaluator&lt;/code&gt; that can be used to compute the current value of a feature flag based on the current date-time obtained from the system clock in the default time-zone and the configured CRON expression.
A typical feature flag configuration may look like:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.evaluator=quarkus.cron &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.authenticated=* * * * mon &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Assign the evaluator to the flag. Note that we do not specify the initial value for &lt;code&gt;my-feature-alpha&lt;/code&gt; - it is &lt;code&gt;true&lt;/code&gt; by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current date-time must match the given CRON expression. In this particular case, the flag will be enabled &lt;strong&gt;every Monday&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;admonitionblock note&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td class=&quot;icon&quot;&gt;
&lt;i class=&quot;fa icon-note&quot; title=&quot;Note&quot;&gt;&lt;/i&gt;
&lt;/td&gt;
&lt;td class=&quot;content&quot;&gt;
By default, the Unix/crontab syntax is used. However, it is also possible to use the syntax from Cron4j, Quartz and Spring. For more information, see &lt;a href=&quot;https://docs.quarkiverse.io/quarkus-flags/dev/cron.html&quot;&gt;the documentation&lt;/a&gt;.
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;the-case-for-multiple-evaluators&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#the-case-for-multiple-evaluators&quot;&gt;&lt;/a&gt;The case for multiple evaluators&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Sometimes it might be useful to combine several evaluators to compute the value of a flag.
The core extension provides &lt;code&gt;io.quarkiverse.flags.CompositeFlagEvaluator&lt;/code&gt; that evaluates a flag with the specified sub-evaluators.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-properties hljs&quot; data-lang=&quot;properties&quot;&gt;quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.evaluator=quarkus.composite &lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;(1)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.sub-evaluators=quarkus.time-span, quarkus.security.identity &lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;(2)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.start-time=2026-01-01T12:00:00+01:00[Europe/Prague] &lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;(3)&lt;/b&gt;
quarkus.flags.runtime.&quot;my-feature-alpha&quot;.meta.roles-allowed=admin &lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;(4)&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;colist arabic&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;1&quot;&gt;&lt;/i&gt;&lt;b&gt;1&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Assign the evaluator to the flag. Note that we do not specify the initial value for &lt;code&gt;my-feature-alpha&lt;/code&gt; - it is &lt;code&gt;true&lt;/code&gt; by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;2&quot;&gt;&lt;/i&gt;&lt;b&gt;2&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The value of &lt;code&gt;sub-evaluators&lt;/code&gt; represents a comma-separated list of sub-evaluator identifiers. They are executed in the specified order. In this particular case, the &lt;code&gt;TimeSpanFlagEvaluator&lt;/code&gt; is executed first and then the &lt;code&gt;SecurityIdentityFlagEvaluator&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;3&quot;&gt;&lt;/i&gt;&lt;b&gt;3&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current date-time must be after the specified start-time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;i class=&quot;conum&quot; data-value=&quot;4&quot;&gt;&lt;/i&gt;&lt;b&gt;4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;The current user must have the role &lt;code&gt;admin&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;extensibility&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#extensibility&quot;&gt;&lt;/a&gt;Extensibility&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Flag providers and flag evaluators are CDI beans.
So all you have to do is add a bean that implements &lt;code&gt;FlagProvider&lt;/code&gt; or &lt;code&gt;FlagEvaluator&lt;/code&gt; in your application.
You can use CDI interceptors and even decorate these components.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus Feature Flags is a lightweight and extensible extension that can help you build more flexible applications.
Feedback, feature requests and contributions are welcome.
Feel free to create questions and issues on GitHub repository: &lt;a href=&quot;https://github.com/quarkiverse/quarkus-flags/issues&quot; class=&quot;bare&quot;&gt;https://github.com/quarkiverse/quarkus-flags/issues&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Mon, 15 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-feature-flags/
            </guid>
            
            
            
            <author>Martin Kouba (https://twitter.com/martunek)</author>
            
        </item>
        
        <item>
            <title>Quarkus Newsletter #63 - December</title>
            <link>
                https://quarkus.io/blog/quarkus-newsletter-63/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &quot;Java Meets the Future: How Quarkus Seamlessly Combines Architecture, Performance, and Cloud-Native&quot; by Holger Tiemeyer to see how Quarkus impressively demonstrates that even an aging ecosystem like Java can always be reinvented to meet the demands of the next technological era. Learn how to build Quarkus application images using Cloud Native Buildpacks and OpenShift Builds with Piotr Minkowski&amp;#8217;s article; &quot;Quarkus with Buildpacks and OpenShift Builds&quot;. Learn how to generate, extend, and optimize a Quarkus actuator-style endpoint with build-time processing, runtime beans, and native support by reading &quot;How to Build a Custom Quarkus Actuator Extension: A Complete Java Developer’s Guide&quot; by Markus Eisele. Did you know about Roq? A powerful new tool that combines Java and Quarkus. Ok, prep a warm drink and put on some soft music and let&amp;#8217;s find out why Roq is so cool with the comfort of Quarkus Dev Mode and all its eco-system. Bonus: a touch of TailwindCss to make it look great! Learn more by reading Andy Damevin&amp;#8217;s article &quot;Discover Roq, the Quarkus Way for Static Site Generation in Java&quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You will also see the latest Quarkus Insights episodes, top tweets/discussions and upcoming Quarkus attended events.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Check out &lt;a href=&quot;https://quarkus.io/newsletter/63/&quot;&gt;Newsletter #63: December&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Want to get newsletters in your inbox? &lt;a href=&quot;https://quarkus.io/newsletter&quot;&gt;Sign up for the newsletter&lt;/a&gt; using the on page form.&lt;/p&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 11 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-newsletter-63/
            </guid>
            
            
            
            <author>James Cobb (https://twitter.com/insectengine)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.3 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-3-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.3, a new maintenance release for our 3.30 stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.3&quot;&gt;3.30.3&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 10 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-3-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30.2 - Maintenance release</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-2-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.2, a new maintenance release for our 3.30 stream.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.2&quot;&gt;3.30.2&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 03 Dec 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-2-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
        <item>
            <title>Quarkus: A Runtime and Framework for Cloud-Native Java</title>
            <link>
                https://quarkus.io/blog/mmaler-blogpost-2-quarkus-runtime-and-framework-for-cloud-native-java/
            </link>
            <description>
                &lt;div id=&quot;preamble&quot;&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/quarkus-as-a-powerful-runtime.jpeg&quot; alt=&quot;Quarkus: Runtime and Framework for Cloud-Native Java&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Public clouds such as AWS, Microsoft Azure, and Google Cloud, and platforms like Red Hat OpenShift, favor services that start fast and stay lean.
Quarkus is engineered for exactly that.
Build time processing reduces runtime overhead and results in rapid startup, a small memory footprint, and frictionless deployment across Kubernetes, OpenShift, serverless, and managed container services in any cloud.
If your Java services need to start in milliseconds, run dense on shared nodes, and still feel great to build, Quarkus was made for that job.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus is a Java runtime that seamlessly integrates popular frameworks and libraries, shaping both the structure of modern applications and the developer experience behind them.
In this post, “runtime” means the full execution stack in production: JVM or native, plus Quarkus and the integrated frameworks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus itself can also work as a framework, as it constitutes a higher-level layer that provides structure and APIs.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;why-quarkus-stands-out&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#why-quarkus-stands-out&quot;&gt;&lt;/a&gt;Why Quarkus stands out?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In modern software development, runtimes and frameworks form the foundation of productivity and consistency.
Frameworks promote uniformity, simplify infrastructure, and enable automation at scale.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/1-history.png&quot; alt=&quot;A brief timeline leading to modern Java and Quarkus&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus is a cloud-native Java runtime that integrates multiple frameworks and optimizes them for fast startup, low memory use, and smooth deployment across any cloud.
It runs well on Kubernetes and Red Hat OpenShift, and it also integrates with native cloud services, from compute platforms such as AWS EC2 and Google Cloud Run to serverless offerings and managed container platforms.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Then, during development, Quarkus live reload provides instant feedback by applying code changes without a rebuild or restart.
This shortens the inner loop and helps teams iterate faster than traditional redeploy cycles.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;But beyond speed and live reload, Quarkus integrates established Java specifications such as CDI-Lite, JAX-RS, and JPA, with implementations provided by Arc (CDI-Lite), RESTEasy (JAX-RS), and Hibernate ORM (JPA).
It also enforces its own conventions, drives behavior with annotations, and defines how applications are structured.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In this sense, Quarkus is a development framework and runtime for cloud-native Java applications.
It adheres to industry standards and offers compatibility with technologies such as Spring, Apache Kafka, and Apache Camel to support familiar, flexible development models.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;quarkus-as-a-versatile-framework&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#quarkus-as-a-versatile-framework&quot;&gt;&lt;/a&gt;Quarkus as a versatile framework&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Beyond staple traits of modern frameworks, Quarkus introduces two platform-defining features: buildtime optimization and deep extensibility.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Buildtime optimization&lt;/strong&gt;: Quarkus shifts work from runtime to build time wherever possible.
This approach reduces startup overhead and memory usage, resulting in a lean, fast, and efficient application tailored for production.&lt;/p&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/2-build-time-principle.png&quot; alt=&quot;Buildtime principle in Quarkus: being fast by doing less at runtime&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 1. Quarkus performs at build time what traditional frameworks do at runtime: reading configuration files, scanning annotations, and building a model of the application.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/3-BuildTimeP-Benefits-JVM.png&quot; alt=&quot;Benefits of Quarkus buildtime processing on the JVM&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 2. Thanks to buildtime initialization, the resulting application starts faster and consumes less memory.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/4-BuildTimeP-Benefits-native.png&quot; alt=&quot;Benefits of Quarkus native image compared to JVM&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 3. All the benefits of buildtime initialization also apply when compiling to a native binary.&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Extensibility&lt;/strong&gt;: Quarkus exposes extension points for everything from startup hooks to request filters.
Over 800 &lt;a href=&quot;https://extensions.quarkus.io&quot;&gt;extensions&lt;/a&gt; allow seamless integration with modern technologies such as Kafka, OpenTelemetry, and OpenID Connect.&lt;/p&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These extensions integrate with Quarkus and participate in its buildtime and runtime lifecycle, making them first-class components of Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;simplified-developer-experience&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#simplified-developer-experience&quot;&gt;&lt;/a&gt;Simplified developer experience&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Frameworks succeed when they reduce complexity without sacrificing flexibility.
Quarkus does exactly that:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Preconfigures popular libraries with sensible defaults.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Offers unified configuration and developer tooling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Provides instant feedback with live reload and continuous testing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dev Services for automatic provisioning of databases, brokers, and other services in dev mode.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Continuous testing to run tests in the background and surface results immediately.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This makes Quarkus both powerful and approachable.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can start with a simple REST endpoint and scale it into a production-grade service without changing your development model.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/6-Frictionless.png&quot; alt=&quot;Frictionless developer experience: live reload, dev services, continuous testing&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;title&quot;&gt;Figure 4. Frictionless developer experience: Vastly improved development feedback loop, unified approach to producing different package types, and using proven APIs that Java developers already know.&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;These features give developers structure, sensible defaults, and clear conventions during development, and they deliver fast startup, low memory use, and operational consistency in production.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;performance-that-matters&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#performance-that-matters&quot;&gt;&lt;/a&gt;Performance that matters&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Teams optimize for different goals, such as startup latency, sustained throughput, memory footprint, elasticity, and cost.
Quarkus addresses these needs by shifting work from run time to build time, keeping one development model across JVM and native, and exposing production signals such as health checks, metrics, and tracing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Start with &lt;strong&gt;JVM mode&lt;/strong&gt; for most services.
On the JVM, Quarkus often starts faster and uses less memory than traditional JVM-based runtimes because it performs more work at build time.
Just-in-time compilation raises steady-state throughput, scales well across cores, and offers mature garbage collectors and tuning options.
The JVM also provides rich observability and diagnostics, which help you understand and tune live systems.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Use &lt;strong&gt;native mode&lt;/strong&gt; when startup latency and memory footprint are strict constraints.
Native executables start in milliseconds and can use less memory, which supports scale-to-zero workflows and lowers idle costs on small instances.
Trade-offs include lower peak throughput, limited multi-core scaling, a single-threaded garbage collector in current native images, longer build times, and a slower inner loop for developers.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If your system needs both profiles, split by workload.
Run bursty or event-driven endpoints in native mode, and run long-lived high-throughput services on the JVM.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;strong&gt;Observability note.&lt;/strong&gt;
JVM mode exposes richer diagnostics and metrics, including GC, heap, and thread telemetry, JFR, and profiler support, which makes issue triage and performance tuning easier.
Native mode still exports application-level metrics and traces with Micrometer and OpenTelemetry, but it offers fewer VM-level signals.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Always measure your workload:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For native, reduce reflection and dynamic class loading, trim resources, and consider profile-guided optimizations (PGO) where supported. PGO is not available in Mandrel and currently requires an Oracle GraalVM distribution that provides PGO.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For the JVM, choose a garbage collector that matches your latency and heap goals, budget for warmup, and test steady-state throughput under realistic load.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Taken together, these in production choices provide measurable wins:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/7-success-stories.png&quot; alt=&quot;Real-world success stories using Quarkus&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://quarkus.io/blog/vodafone-greece-replaces-spring-boot/&quot;&gt;Vodafone Greece replaces Spring Boot with Quarkus&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.logicmonitor.com/blog/quarkus-vs-spring&quot;&gt;Quarkus vs. Spring Boot&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;security&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#security&quot;&gt;&lt;/a&gt;Segurança&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus uses a standards-first composable security model.
You enable what you need and configure it for your environment:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transport:&lt;/strong&gt; Enable HTTPS in the application by configuring TLS.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authentication:&lt;/strong&gt; Choose Basic, form-based, mTLS, OpenID Connect (OIDC), or WebAuthN.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Authorization:&lt;/strong&gt; Enforce RBAC on web endpoints with &lt;code&gt;@RolesAllowed&lt;/code&gt;, &lt;code&gt;@DenyAll&lt;/code&gt;, and &lt;code&gt;@PermitAll&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This lets you apply the right security controls for each deployment.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;observability-and-control-surfaces&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#observability-and-control-surfaces&quot;&gt;&lt;/a&gt;Observability and control surfaces&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Common control surfaces, such as metrics, logging, tracing, and configuration, are essential for site reliability engineers (SREs) and platform teams.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus exposes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Unified logging with &lt;a href=&quot;https://quarkus.io/guides/logging&quot;&gt;&lt;code&gt;quarkus-logging&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Centralized logging with OpenTelemetry (OTLP logs) with &lt;a href=&quot;https://quarkus.io/guides/opentelemetry&quot;&gt;OpenTelemetry&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Metrics and tracing with &lt;a href=&quot;https://quarkus.io/guides/telemetry-micrometer-to-opentelemetry&quot;&gt;Micrometer and OpenTelemetry&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unified configuration of all the application&amp;#8217;s aspects by using &lt;code&gt;application.properties&lt;/code&gt; or environment variables.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This standardization enables automation and scalable monitoring.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;modular-and-production-ready&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#modular-and-production-ready&quot;&gt;&lt;/a&gt;Modular and production-ready&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Following a lean-core, modular-at-the-edge approach, Quarkus delivers:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A minimal core for fast startup.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pluggable extensions for authentication, tracing, messaging, and more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Built-in production primitives, including health checks, readiness and liveness probes, and graceful shutdown.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fault tolerance with standard annotations, for example, retries, circuit breakers, bulkheads, and timeouts.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Whether you are building a prototype or deploying to OpenShift, Quarkus adapts.
This modularity spans both the framework-level APIs developers work with and the runtime behaviors that execute beneath them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Because Quarkus modularity is declarative and unified across extensions, it supports a platform-like developer experience without the rigidity of traditional frameworks.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;building-your-stack-with-quarkus&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#building-your-stack-with-quarkus&quot;&gt;&lt;/a&gt;Building your stack with Quarkus&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We will explore this topic in depth in part 3 of this series.
For now, here is how Quarkus fits into the picture.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Frameworks can serve as a foundation for creating higher-level abstractions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus fits this model by enabling teams to build customized stacks and internal frameworks on top of it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Unlike many traditional frameworks, Quarkus provides a unified extension architecture that supports deep customization.
Organizations can tailor Quarkus to fit specific domains, technologies, or compliance needs.
This enables the creation of organization-specific developer experiences, including internal stacks built on a unified Quarkus extension architecture.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;By encouraging consistency, offering buildtime integration, and exposing clean extension points, Quarkus supports the creation of opinionated, scalable internal frameworks without forking or reinventing the core.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;By packaging Quarkus extensions, curated defaults, and service templates into an internal Quarkus stack, teams focus on business logic.
At the same time, your framework layer standardizes infrastructure, security, and operational integrations across services.
This has been proven by Logicdrop, who refactored their entire Spring Boot stack with Quarkus, reducing container size by ~75%, achieving sub-second startup times, and significantly improving developer productivity.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information, see the &lt;a href=&quot;https://quarkus.io/blog/logicdrop-customer-story/&quot;&gt;Logicdrop customer story&lt;/a&gt; and their &lt;a href=&quot;https://quarkus.io/blog/logicdrop-automating-quarkus-with-gitlab/?utm_source=chatgpt.com&quot;&gt;GitLab automation write-up&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#conclusion&quot;&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus unifies the strengths of a development framework and a runtime.
As a framework, it provides structure, conventions, and a cohesive developer experience.
As a runtime, it delivers fast startup, low memory use, and operational consistency in the cloud.
This dual role helps teams standardize practices, reduce costs, and ship resilient cloud-native services.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus is built in the open under the Apache License 2.0, governed with the Commonhaus model, and developed end-to-end on GitHub.
Beyond the core project, the ecosystem includes the &lt;a href=&quot;https://hub.quarkiverse.io/&quot;&gt;Quarkiverse Hub&lt;/a&gt;, a community-run collection of &lt;a href=&quot;https://quarkus.io/extensions/&quot;&gt;Quarkus extensions&lt;/a&gt; and related projects.
The Quarkiverse Hub provides repository hosting with build, CI, and release publishing, so features land as versioned, testable modules you can adopt, fork, or extend.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;imageblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;img src=&quot;/assets/images/posts/mmaler-blog-posts/2-Quarkus-as-a-powerful-runtime/8-expectations.png&quot; alt=&quot;Setting expectations for performance and developer experience with Quarkus&quot; width=&quot;100%&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;So, that’s all for now, thank you for reading, and let’s meet again in the third article of this series, which will cover building your own stack with Quarkus.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For a closer look at how Quarkus makes Java cloud-native, see the &lt;a href=&quot;https://quarkus.io/blog/mmaler-blogpost-1-intro/&quot;&gt;introductory blog post&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Thu, 27 Nov 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/mmaler-blogpost-2-quarkus-runtime-and-framework-for-cloud-native-java/
            </guid>
            
            
            
            <author>Michal Mickey Maléř (https://twitter.com/mickeymaler)</author>
            
        </item>
        
        <item>
            <title>Quarkus 3.30 - JsonView on REST Client, Hibernate Validator 9.1, CLI decrypt command, and more</title>
            <link>
                https://quarkus.io/blog/quarkus-3-30-released/
            </link>
            <description>
                &lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Today, we released Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Quarkus 3.30 introduces the following notable changes:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/51043&quot;&gt;#51043&lt;/a&gt; - Introduce support for &lt;code&gt;@JsonView&lt;/code&gt; on the REST Client&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50196&quot;&gt;#50196&lt;/a&gt; - Update to Hibernate Validator 9.1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50332&quot;&gt;#50332&lt;/a&gt; - Add a CLI command to decrypt secrets&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50723&quot;&gt;#50723&lt;/a&gt; - OIDC token propagation - allow users to select REST Client methods for which token should be propagated&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50806&quot;&gt;#50806&lt;/a&gt; - Support method-level &lt;code&gt;@OidcClientFilter&lt;/code&gt; bindings&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/quarkusio/quarkus/pull/50952&quot;&gt;#50952&lt;/a&gt; - Use &lt;code&gt;@QuarkusIntegrationTest&lt;/code&gt; tests as a test run for AOT file generation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;As usual, this release also includes many bug fixes and improvements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;update&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#update&quot;&gt;&lt;/a&gt;Atualização&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;To update to Quarkus 3.30, we recommend updating to the latest version of the Quarkus CLI and run:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;listingblock&quot;&gt;
&lt;div class=&quot;content&quot;&gt;
&lt;pre class=&quot;highlightjs highlight&quot;&gt;&lt;code class=&quot;language-bash hljs&quot; data-lang=&quot;bash&quot;&gt;quarkus update&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Note that &lt;code&gt;quarkus update&lt;/code&gt; can update your applications from any version of Quarkus (including 2.x) to Quarkus 3.30.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;For more information about the adjustments you need to make to your applications, please refer to the &lt;a href=&quot;https://github.com/quarkusio/quarkus/wiki/Migration-Guide-3.30&quot;&gt;Quarkus 3.30 migration guide&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;whats-new&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#whats-new&quot;&gt;&lt;/a&gt;What&amp;#8217;s new?&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;rest-client&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#rest-client&quot;&gt;&lt;/a&gt;REST Client&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;code&gt;@JsonView&lt;/code&gt; support has been added to the REST Client.
You can now use this annotation on your REST Client interfaces to control the serialization and deserialization of JSON data based on different views.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;This feature used to be only supported on the server side.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;hibernate-validator&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#hibernate-validator&quot;&gt;&lt;/a&gt;Hibernate Validator&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Hibernate Validator has been updated to version 9.1, which comes with some significant performance improvements.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;cli&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#cli&quot;&gt;&lt;/a&gt;CLI&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;A new &lt;code&gt;config decrypt&lt;/code&gt; command has been added to the Quarkus CLI to decrypt secrets that were encrypted using the &lt;code&gt;quarkus config encrypt&lt;/code&gt; command.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;oidc&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#oidc&quot;&gt;&lt;/a&gt;OIDC&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;OIDC token propagation has been enhanced to allow users to select specific REST Client methods for which the token should be propagated.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;Additionally, method-level &lt;code&gt;@OidcClientFilter&lt;/code&gt; bindings are now supported, allowing for more granular control over OIDC client behavior.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect2&quot;&gt;
&lt;h3 id=&quot;aot-cache&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#aot-cache&quot;&gt;&lt;/a&gt;AOT cache&lt;/h3&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;&lt;code&gt;@QuarkusIntegrationTest&lt;/code&gt; tests are now used as a test run for AOT file generation.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;full-changelog&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#full-changelog&quot;&gt;&lt;/a&gt;Full changelog&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;You can get the full changelog of &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.0.CR1&quot;&gt;3.30.0.CR1&lt;/a&gt;, &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.0&quot;&gt;3.30.0&lt;/a&gt;, and &lt;a href=&quot;https://github.com/quarkusio/quarkus/releases/tag/3.30.1&quot;&gt;3.30.1&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;contributors&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#contributors&quot;&gt;&lt;/a&gt;Contributors&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;The Quarkus community is growing and has now &lt;a href=&quot;https://github.com/quarkusio/quarkus/graphs/contributors&quot;&gt;1136 contributors&lt;/a&gt;.
Many many thanks to each and everyone of them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;In particular for the 3.30 release, thanks to Ales Justin, Alexey Loubyansky, Andreas Repp, Andy Damevin, Antonio Musarra, Aurea Munoz, azerr, Bruno Baptista, Christian Pieczewski, Clement Escoffier, David M. Lloyd, Eric Deandrea, eschcam, Foivos Zakkak, Fouad Almalki, Galder Zamarreño, George Gastaldi, Georgios Andrianakis, Greg Stewart, Guillaume Smet, Holly Cummins, Jakub Pietrzak, James Netherton, Jan Martiska, jcarranzan, jcjveraa, Johannes Schleger, Jonas Rutishauser, Juan Antonio Breña Moral, Julien Ponge, Junior DUSSOUILLEZ, Karm Michal Babacek, Kevin Ferrare, Ladislav Thon, Loïc Hermann, Luca Molteni, Lucas Reeh, Maciej Swiderski, Manuel Müller, Marco Belladelli, mariofusco, marko-bekhta, Martin Kouba, Matej Novotny, Matej Vašek, Matheus Cruz, Melloware, Michael Edgar, Michal Vavřík, Nicolo Pietro Belcastro, Ozan Gunalp, Peter Palaga, Phillip Krüger, Pierre Beitz, Robert Stupp, Roberto Cortez, Rolfe Dlugy-Hegwer, Rostislav Svoboda, Sanne Grinovero, Sergey Beryozkin, staillebois, Stéphane Épardaud, Teymur Babayev, Thomas Segismont, Tomas Hofman, Willem Jan Glerum, xstefank, and Yoann Rodière.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;sect1&quot;&gt;
&lt;h2 id=&quot;come-join-us&quot;&gt;&lt;a class=&quot;anchor&quot; href=&quot;#come-join-us&quot;&gt;&lt;/a&gt;Come Join Us&lt;/h2&gt;
&lt;div class=&quot;sectionbody&quot;&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;We value your feedback a lot so please report bugs, ask for improvements&amp;#8230;&amp;#8203; Let&amp;#8217;s build something great together!&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;paragraph&quot;&gt;
&lt;p&gt;If you are a Quarkus user or just curious, don&amp;#8217;t be shy and join our welcoming community:&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;ulist&quot;&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;provide feedback on &lt;a href=&quot;https://github.com/quarkusio/quarkus/issues&quot;&gt;GitHub&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;craft some code and &lt;a href=&quot;https://github.com/quarkusio/quarkus/pulls&quot;&gt;push a PR&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;discuss with us on &lt;a href=&quot;https://quarkusio.zulipchat.com/&quot;&gt;Zulip&lt;/a&gt; and on the &lt;a href=&quot;https://groups.google.com/d/forum/quarkus-dev&quot;&gt;mailing list&lt;/a&gt;;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ask your questions on &lt;a href=&quot;https://stackoverflow.com/questions/tagged/quarkus&quot;&gt;Stack Overflow&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
            </description>
            <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
            <guid>
                https://quarkus.io/blog/quarkus-3-30-released/
            </guid>
            
            
            
            <author>Guillaume Smet (https://twitter.com/gsmet_)</author>
            
        </item>
        
    </channel>
</rss>
