October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

New Java Features Are Not Just for Interviews. Two Real-World Use Cases from Axelix

Newer Java features earn their place when they express an invariant your code relies on. Two Axelix examples show ScopedValue for request context and a sealed endpoint interface for map keys, with their limits.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Yes, newer Java features have a place in ordinary production code, but only where they make a specific rule of the application easier to see and harder to break. Axelix, an open-source project, shows this with two examples in a September 16, 2026 article by technical lead Mikhail Polivakha: using ScopedValue to carry request-scoped security context, and sealing an interface that is used as a map key. Both examples come from one principle, which the article puts as a question you should ask before adopting any feature: “Which invariant of my application does this feature allow me to express and protect?”

Start with the invariant, not the syntax

An invariant is a rule the program depends on being true, such as “this request’s identity is only visible while this request is being handled” or “this endpoint key never changes after it is stored in a lookup table.” Language features are useful when they let the code state that rule directly. A feature that does not express an invariant your code actually relies on adds vocabulary without adding safety.

As an Amazon Associate I earn from qualifying purchases.

That framing also limits what the examples prove. Neither feature is a universal replacement for older patterns, and neither makes a program safe by itself. Each is a design choice that fits a particular shape of problem.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Example 1: ScopedValue for authorization context

The problem Axelix describes is familiar to anyone who has worked on servlet filters and thread pools. A filter authenticates a request and needs the resulting identity to reach code several layers down, such as a transport component that attaches the caller’s bearer token to an outgoing Authorization header. The traditional tool for this is ThreadLocal. Its weakness is that the value is mutable from anywhere on the thread, and on a pooled thread it survives unless someone remembers to call remove() in a finally block. A missed cleanup or a stray set() can leak one request’s identity into a later request handled by the same thread.

How the binding works

In the Axelix design, the filter creates a SecurityContext and binds it for the duration of the downstream call using ScopedValue.where(...), with the work supplied through call(...). The binding exists only inside that call. When the call returns, the value is no longer bound, so there is nothing to clear. Deeper code reads the value through the ScopedValue key and cannot rebind it for its own purposes.

The sketch below is illustrative and is not Axelix’s code. It shows the shape of the pattern:

static final ScopedValue<SecurityContext> CURRENT_CALLER = ScopedValue.newInstance();

void handle(Request request, SecurityContext ctx) throws Exception {
    ScopedValue.where(CURRENT_CALLER, ctx).call(() -> {
        return chain.proceed(request);   // any code in this call can read CURRENT_CALLER.get()
    });
    // outside the call, CURRENT_CALLER is unbound again
}

When ScopedValue fits, and when it does not

The article recommends ScopedValue when context flows down a bounded operation, when downstream code should read the value but not change it, and when the value’s lifetime matches that operation. It recommends ordinary method parameters when the dependency belongs in a method’s contract, because a parameter tells every caller what the method needs. The comparison below reflects the axes the article uses.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Question ScopedValue ThreadLocal Explicit parameter
Lifetime and cleanup Bound only for the enclosed call; no manual removal Lasts until remove() is called; cleanup is the developer’s job Lives as long as the call stack that passes it
Mutability The binding is fixed; the object inside it can still be mutable Can be reassigned at any point on the thread Depends on the parameter type
Visible to the reader of a signature No, it is implicit context No, it is implicit context Yes, it is part of the contract
Work on other threads Not automatically propagated to arbitrary executor or CompletableFuture tasks Not inherited by other threads without explicit copying Carried wherever the code passes it
Java baseline Per the Axelix article, finalized in Java 25; check the JDK release notes for your version Available in long-supported releases Any version

ThreadLocal remains a reasonable choice for mutable state that must change during processing, for integrations written against it, and for codebases that must run on older Java versions.

Limits the pattern does not remove

  • Asynchronous work. A binding is not automatically carried into arbitrary CompletableFuture or executor tasks. The Axelix example works because the relevant proxy operation runs synchronously on the same thread. If the work hops threads, the value may be unbound there, so verify it explicitly rather than assuming it follows the work.
  • Mutable contents. Making the binding immutable does not make an object stored inside it immutable. If a SecurityContext holds a mutable list of roles, that list can still change.
  • Hidden dependencies. Implicit context keeps method signatures short, but it hides what a method needs. If the dependency is part of what the method means, pass it as a parameter.

Example 2: sealing the endpoint interface used as a map key

The second example concerns a lookup table. Axelix maps an McpEndpoint key to the authority required to call it. Hash-based maps assume a key’s hashCode() stays stable after insertion. If arbitrary implementations of McpEndpoint can be supplied, one of them could be mutable, with equals and hashCode that change over time. Once that happens, a lookup can fail to find an entry that is plainly present, or find the wrong one. The rule the code relies on is that endpoint keys have stable value semantics.

The proposed hierarchy

The Axelix design seals the interface so that only a fixed, permitted implementation can extend it. The permitted implementation is a record with a String component. Records derive equals and hashCode from their components, and a String cannot be mutated, so the key’s identity is fixed when it is created. The sketch below is illustrative and not Axelix’s code:

public sealed interface McpEndpoint permits NamedEndpoint {}

public record NamedEndpoint(String name) implements McpEndpoint {}

Map<McpEndpoint, Authority> required = Map.of(
    new NamedEndpoint("tools/list"), Authority.READ_TOOLS);

Sealed types are a Java SE 17 feature described in the Java Language Specification by OpenJDK. A sealed type lists the classes and interfaces permitted to extend or implement it, and the compiler rejects any other direct subtype. The feature makes the set of direct implementations an explicit, checkable part of the design.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What sealing does not prove

Sealing does not validate the authority table. It does not guarantee that endpoint names are unique, and it does not ensure that every new endpoint is registered with an authority. Those are separate design and testing concerns, and the article treats them that way. Sealing narrows which kinds of key can exist; it does not check that the data put into the map is correct or complete.

Sealed interface or enum?

The article notes that an enum may be the better choice when the set of endpoints is permanently fixed. A sealed interface leaves room for controlled variation, such as different distributions of the software supplying different endpoint types, while still restricting who may implement the interface. The choice depends on two questions:

  • Is the set of values fixed for the life of the product, or do controlled extensions need to be added?
  • Do implementation properties, such as mutability or custom equals, matter to correctness? If so, restricting the implementations is the point of the design.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A checklist before you adopt either feature

  • Name the invariant in one sentence. If you cannot, the feature will not make the code safer.
  • For context binding, confirm that all work carrying the value runs within the bound call, or that the value is passed explicitly where it leaves that call.
  • Confirm the Java version your project must support before choosing a preview or recently finalized API.
  • For sealed hierarchies, decide whether the permitted set should be fixed (enum) or extensible in a controlled way (sealed interface), and make sure the permitted implementations have stable value semantics if they serve as keys.
  • Keep the separate checks, such as uniqueness of names and completeness of mappings, in tests. The type system does not do them for you.

The Axelix article is also explicit that its codebase may change, so the specific implementation details it describes should be read as a design example rather than a fixed reference.

“

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.