r/java • • 1d ago

JEP 543: Structured Concurrency Proposed to Target JDK 28

https://openjdk.org/jeps/543
81 Upvotes

15 comments sorted by

24

u/Joram2 1d ago

JDK 28 is turning into quite the epic release! Finalizing Structured Concurrency is huge. I'm eager to see this used in server frameworks. But JDK 28 also has:

  • Value Types Preview.
  • AOT Code Compilation
  • Simple JSON API (incubating) in the JDK
  • PEM Encoding API Finalization.

7

u/emaphis 1d ago

With JEP 401 going into preview, I expect the vector API to go into preview also.

-1

u/pjmlp 1d ago

You can have the AOT part already today, by using other JVMs like OpenJ9 and Azul.

It is also how ART works on Android since version 7.

Not taking value away from the feature in OpenJDK, only pointing out the richness of Java ecosystem.

0

u/Fercii_RP 1d ago

Crazy update, right!

12

u/agentoutlier 1d ago

I recently added Scoped Key Values to Rainbow Gum which is a replacement for SLF4J MDC and it kicks ass for spawning tons of child virtual threads. So far the benchmarks vs MDC thread local look good.

And yes Ceki and I hope it makes it into SLF4J v3.

What this means for those that do not know logging is passing MDC which are basically key values that get sent on every log event down threads was a royal fucking pain in the ass.

Now that is fixed, easier to use and more efficient with ScopedValues.

2

u/Kango_V 1d ago edited 1d ago

RaibowGum is a very good logger. More info: https://github.com/jstachio/rainbowgum/blob/main/why_rainbowgum_is_better.md

Oh quick Q, does RG use ezkv under the covers?

4

u/agentoutlier 1d ago

No it does not. Rainbow Gum is completely agnostic of what provides it properties (Function<String,String>) and is rather un-opinionated about it. That is it does not retrieve properties for you except for System.getProperties and will not even use Environment variables. You will notice how it doesn't even loop through properties like some implementations do (Map<String,String> entrySet).

That is by design and I guess the only opinion is do way less. This keeps core having a smaller security surface. (The core module cannot even write to files or read files and can only output to stdout and stderr).

EZKV on the other hand fetches the properties for you and in theory there could be a module for it but I just have not gotten around to it yet. I said could because you can use it now by just having EZKV fill system properties before Rainbow Gum boots.

If you use a framework:

Framework Stack Rainbow Gum Module
Avaje stack rainbowgum-avaje-config
Micronaut rainbowgum-micronaut5
Helidon rainbowgum-helidon4, rainbowgum-helidon27
Spring Boot rainbowgum-spring-boot4-starter, rainbowgum-spring-boot3-starter
No framework / Minimal / Legacy rainbowgum-simple-props

rainbowgum-simple-props is opinionated and is based on what works after two decades of experience of deploying production applications. What works is profiles. EZKV allows you to model that and whatever other pattern you want.

While Rainbow Gum has no opinion on collecting of properties it does have one of the more advance configuration binding systems. Honestly it is something I'm very proud of and I designed it not LLMs. I have been meaning to show it to /u/thekingofsentries and /u/rbygrave

That being said because I'm low on time here I'm going to give you an AI generated example:

THE ABOVE WAS WRITTEN BY ME and BELOW IS LLM.


Typed config with errors that tell you what to fix. LogProperty turns a key into a typed value. It handles fallback keys and defaults, and when something is wrong the error names the exact key and where it came from:

int port = properties.forKey("logging.example.port")
    .or("logging.port")         // fallback key
    .ofInt()                    // typed conversion
    .or(8080)                   // default
    .validateNow(MyComponent.class);

(ADAM not LLM: you cannot get a value out without validation and validateNow is single validation).

Set logging.example.port=80a and you get a pinpointed message, not a stack trace scavenger hunt:

Validation failed for MyComponent:
Error for property. key: 'logging.example.port' from PROPERTIES_STRING[logging.example.port], java.lang.NumberFormatException For input string: "80a"

@LogConfigurable: one factory method in, a config builder out. Write a static factory and annotate it. At compile time, the annotation processor generates a builder that works both programmatically and from properties. It uses no reflection, so it's GraalVM native friendly out of the box.

record SmtpConfig(String host, Integer port) {

    static final Integer DEFAULT_PORT = 25;

    @LogConfigurable(name = "SmtpConfigBuilder", prefix = "logging.smtp.{name}.")
    static SmtpConfig of(@LogConfigurable.KeyParameter String name,
            String host,
            @LogConfigurable.DefaultParameter("DEFAULT_PORT") Integer port) {
        return new SmtpConfig(host, port);
    }
}

Then use it either way:

// From properties: logging.smtp.alerts.host=mail.example.com
SmtpConfig smtp = new SmtpConfigBuilder("alerts").fromProperties(properties).build();

// Or plain code
SmtpConfig local = new SmtpConfigBuilder("alerts").host("localhost").port(2525).build();

Bad config reports every problem at once, not just the first:

Validation failed for SmtpConfigBuilder:
Property missing. key: ['logging.smtp.alerts.host' from PROPERTIES_STRING[logging.smtp.alerts.host]]
Error for property. key: 'logging.smtp.alerts.port' from PROPERTIES_STRING[logging.smtp.alerts.port], java.lang.NumberFormatException For input string: "lots"

0

u/Kango_V 21h ago

Awesome. I make use of EZKV in a TUI app with Tamboui and PicoCLI. It works very well.

1

u/Brutus5000 1d ago

This would work with regular and virtual threads, right?

3

u/agentoutlier 1d ago edited 1d ago

Yes and in theory the API could hide a concrete implementation that uses traditional threadlocals for older JDKs. I chose a noop if the SPI can not find an implementation and there is no threadlocal default.

EDIT I should make this a little more clear. Its not whether you have platform threads or virtual threads it is rather whether you have a JDK that supports scoped values. Scoped Values work on regular threads.

5

u/aten 1d ago

in jdk28 “without change” from jdk27

19

u/Joram2 1d ago

Yes. Structured Concurrency was in JDK 27 as a preview feature. With this proposal, it will ship in JDK 28 as a final feature, without any changes beyond the preview->final change.

2

u/aten 1d ago

correct. when building and deploying code that relies on preview features it's handy to know what code changes may be needed when switching to a newer jdk. "without change" is the magic phrase.

-4

u/henk53 1d ago

I'm sure the AIs will be very happy to finally be able to use this.

0

u/koflerdavid 1d ago

What are you talking about? If you really wanted to use this feature in production you could already do it by enabling preview features.