r/java • • Oct 08 '20

[PSA]/r/java is not for programming help, learning questions, or installing Java questions

324 Upvotes

/r/java is not for programming help or learning Java

  • Programming related questions do not belong here. They belong in /r/javahelp.
  • Learning related questions belong in /r/learnjava

Such posts will be removed.

To the community willing to help:

Instead of immediately jumping in and helping, please direct the poster to the appropriate subreddit and report the post.


r/java • • 9h ago

Using Java skills for something a little different

Post image
100 Upvotes

Java is quite a handy language. Though it's challenging to use it for more fun projects. Towards that end, I set myself a challenge to use Java to build a browser-based game. No server, no API, just pure Web Assembly driven game play. Yes, there's some JavaScript glue, because, well, you gotta, but, the core logic is all Java. Along the way I learned that streams allocate a lot of objects, so I switched back to good old for loops... And watched the GC usage drop a fair bit. What I really do enjoy is how Java has evolved and changed over the years, and it makes it a lot simpler to do things like this. Records save me a ton of boilerplate code. Playable at https://nofuss.co.za/games/wartech/, but it's a bit meh on mobile, I'm still working on that. My focus right now is desktop play, and getting sound to work. Flame me in the comments with bug reports, I know there's a few... Hundred.


r/java • • 1h ago

Java based Numerical library (JNum-v0.2) This time even better and faster!

Thumbnail github.com
• Upvotes

previous post

And yeah made another version for Java Numerations(JNum).

A lot has changed and I want you guys help now. JNum is now performant and comparable traditional OpenBlas/LAPACK bindings like ND4J and Numpy.

Benchmarks and features are in detailed in my github release but for lazy guys like me here are some data points worth see:-

-> JNum is feature rich(at least from previous version) where we have statistics jnum.stat IO operations jnum.io and basic Neural Networks jnum.nn.

-> JNum's IO will help you parse files like .npy/.npz , .csv/.tsv and most importantly .safetensorwhich Java lagging in this AI era.

-> We also have AsyncIO using Virtual Threads which make IO file reads faster in JNum.

-> jnum.statmodule has various statistic methods which Java community can use like standard deviations, variance , co-variance, cummulative sum/product, percentile etc.

-> JNum has slicing and subviewing features. Since we use NDArrays our operations can be chained together.

-> Most engineered parts are Matrix multiplication, Expression engine and Kotlin DSL. Since this is java subreddit i will go with first two parts.

  1. Matrix multiplication

in detail see my docs

But in short this is our benchmarks for matmul:

Matrix Dimensions JNum (Pure Java 25) NumPy (C / OpenBLAS) ND4J (OpenBLAS C++) EJML (Pure Java) Performance Highlights
$4 times 4$ 0.0002 ms 0.0023 ms 0.020 ms ≈ 0.0001 ms 11× faster than NumPy, 100× faster than ND4J
$16 times 16$ 0.0004 ms 0.0028 ms 0.019 ms 0.003 ms 7× faster than NumPy, 47× faster than ND4J
$64 times 64$ 0.015 ms 0.013 ms 0.190 ms 0.140 ms On-par with NumPy, 9.3× faster than EJML
$128 times 128$ 0.138 ms 0.254 ms 0.499 ms 1.028 ms 1.8× faster than NumPy, 7.4× faster than EJML
$512 times 512$ 2.50 ms 1.86 ms 2.67 ms 27.16 ms Matches C++ BLAS, 10.8× faster than EJML
$1024 times 1024$ 13.85 ms 8.98 ms 12.18 ms 216.56 ms Near-native speed, 15.6× faster than EJML
$2048 times 2048$ 94.62 ms 62.99 ms 85.29 ms 2,049.86 ms Pure Java competitive with C BLAS, 21.6× faster than EJML
$4096 times 4096$ 942.38 ms 487.92 ms 857.41 ms 17,419.52 ms Matches ND4J C++, 18.4× faster than EJML
$8192 times 8192$ 6,784.15 ms 5,967.30 ms 6,317.97 ms 141,500.0 ms ~88% of NumPy C BLAS, 20.8× faster than EJML
  1. Expression Engine

Basic engine for now but if some one gets fatigue of writing a.add().mul().div()... the we have JNum.eval() which is a literal AST running on shunting yard algorithm. Better than chaining but I would still recommend in place for better performance.

Kotlin devs can skip this because of DSL operator overloading.

Linear Algebra:-

we have various Linear Algebra methods which have performance on par sometimes beating Numpy

Operation JNum (Pure Java 25) NumPy EJML ND4J JNum Advantage
Matrix Inverse 7.271 ms 10.680 ms 18.122 ms 1,224.654 ms 1.47× faster than NumPy, 2.5× faster than EJML, 168× faster than ND4J
Linear Solve ($Ax=b$) 1.976 ms 1.003 ms 5.331 ms 37.278 ms Near-native speed, 2.7× faster than EJML, 18.8× faster than ND4J
Determinant 1.839 ms 5.735 ms 5.380 ms 399.752 ms 3.1× faster than NumPy, 2.9× faster than EJML
Cholesky 1.261 ms 2.328 ms 3.545 ms — 1.8× faster than NumPy, 2.8× faster than EJML
QR Factorization 46.170 ms 12.622 ms 7.447 ms 586.330 ms 12.7× faster than ND4J

Size and deploy :- JNum is under 500kb and available of maven central just simple dependencies and you can use it

<dependency>

<groupId>io.github.ch-abhinav</groupId>

<artifactId>jnum</artifactId>

<version>0.2.0</version>

</dependency>

What I want from you guys is simple, Try using JNum and see how it works it gives me motivation to continue. If community helps me build the library then yes having performance on par to native libraries isn't that far.

If you guys can run on other Architectures and Operating Systems give feedback and try to contribute in project it will be great because I can't do that. Since project is has grown a lot without people helping it out it's very tough task for me :(

That's why I have 6 good-first issues worth trying for. It will be even more great if people make there own issues and enhancement proposals.

TO JDK devs:-
1. Vector API is amazing tool but when I do SIMD operations I expect less warmup time but that's not the case i my library.
2. when I stop a JMH benchmark midway it's causing Zombie runs (mainly with multithreaded programs) basically because of off heap memory calculations benchmarks sometimes don't stop and run even though terminal running that is closed. IDK if this is windows only bug or intended feature or random event but once check it out please. My 10k x 10k 5 matmuls which are multithreaded become zombie process basically take 100% of cpu throughput for basically a program which should have stopped long ago.


r/java • • 1d ago

Tomcact breaking change regarding locales can cause application failure for certain users

45 Upvotes

With Tomcat 9.0.123/10.1.61/11.0.27, the following line can be found in the changelog:

Update: Optimize Accept-Language header processing and use of resource budles for localization. (remm)

This is actually a breaking change in how more than 10 browser locales are handled. If your application tries to access request.getLocale(), and the users browser had more than 10 languages configured, then this will generate an exception: java.lang.IllegalArgumentException: More than the maximum allowed number of locales, [10], were detected. Use the maxLocaleCount attribute of the connector to resolve this if the application should accept more locales. at org.apache.catalina.connector.Request.parseLocales(Request.java:3409) at org.apache.catalina.connector.Request.getLocale(Request.java:1177) at org.apache.catalina.connector.RequestFacade.getLocale(RequestFacade.java:428) => For our application, users with more than 10 locales could no longer login after the Tomcat update. This impacted more than 500 users.

Setting maxLocaleCount=-1 in your server.xml will revert it back to the old behavior.

Bugzilla ticket: https://bz.apache.org/bugzilla/show_bug.cgi?id=70278 (needs login) This ticket requests a higher default limit to impact less users, but was resolved as WONTFIX.

So keep this in mind, if you upgrade to the newest Tomcat version.


r/java • • 1d ago

Building full-stack web apps using TeaVM (and why it’s great for working with AI coding agents too)

9 Upvotes

Hey r/java,

TeaVM was something that had been on my radar for a while, and I finally got around to giving it a proper spin recently. After playing around with it and seeing what I can build with it I wanted to share my thoughts and hopefully get a few more eyes on the project!

If you haven’t run into it before, TeaVM is an ahead-of-time compiler that turns Java bytecode into JavaScript or WebAssembly. It operates directly at the bytecode level, emits remarkably clean JS, and integrates with your existing Java tooling.

Why this workflow clicked for me:

  1. One language across the stack: Keeping everything in Java keeps context-switching to a minimum and lets you share domain models directly between backend and frontend.
  2. AI Agent Friendly: Having both frontend and backend written in strongly-typed, readable Java makes it remarkably easy for LLM coding agents to navigate, refactor, and reason about the full application without hitting cross-language friction.

To document what I learned, I put together a 3-part series walking through how to build interactive frontends with TeaVM:

Has anyone else here given TeaVM a try? Would love to hear how your experience compares to other JVM web approaches!


r/java • • 1d ago

fose: A flat combining primitive for Java (looking for review)

11 Upvotes

Hi, so I've been building fose, an open source flat combining primitive for Java. As of now, it is not released as a library, so you'd have to clone the repo to try it.

The idea comes from the 2010 SPAA paper. You wrap a sequential object and submit operations against it. If the lock is free, your thread runs its own op. If it's contended, the op is published to a queue and the current lock holder applies it on your behalf with the main benefits being reduced cache coherence traffic and sometimes opportunities for batching

Currently, I've only benchmarked it with JMH against a StampedLock write lock baseline on my 4-core i5 (Windows), a heap benchmark with some work between operations showed about 60-70% lower avg latency at 4+ threads. These are averages only and I haven't measured latency across different percentiles. I also haven't tested on Linux or on more cores. Currently, correctness tests use Lincheck

I'd especially like feedback on:

  • If executing operations out of order in certain scenarios as a means to improve perf is acceptable
  • The backoff heuristic which uses missed lock acquisitions as a guess at queue depth
  • Also, whether the benchmarks are fair, and what baselines I'm missing. Also, if you can run the benchmarks on your machine and lmk the results, that'd be useful as well

I'd be interested to hear whether it fits anything you're working on, and what might be missing.

Repo: https://github.com/kusoroadeolu/fose


r/java • • 1d ago

calit 1.28.0

Thumbnail
0 Upvotes

For those of you who are interested in Quarkus, this codebase might be interesting to browse around — it touches a lot of essential parts: Panache and native JDBC for persistence, testing techniques, controllers, Qute for templates, and a way to use daisyUI with it. Both integration and unit tests, and even image generation!

The repo is here: github.com/asm0dey/calit


r/java • • 2d ago

CondationCMS - a flat-file CMS written in Java

24 Upvotes

Hi,

I’d like to show you a project I’ve been working on for some time: CondationCMS, a Java-based flat-file CMS.

The tech stack is relatively small: embedded Jetty, GraalJS for extensions, and Lucene for fast queries.

A few words about the architecture: All content is stored in Markdown files with frontmatter for metadata. All metadata is indexed in Lucene, allowing fast queries without having to read every file. URLs basically follow the folder structure.

That’s the architecture in a really, really short version.

Some other features I want to mention:

  • Manager UI, completely optional, to keep the editorial and production systems separated
  • Shortcodes to add more possibilities to Markdown
  • Multisite support

Background

Back in 2023, I needed a CMS for some ideas I was working on. As I’m a Java developer, I wanted a Java-based system. And because it should be easy to use, I was looking for a flat-file CMS. Unfortunately, I didn’t find anything that fit my needs.

I worked for one of Germany's largest CMS vendors for many years. I was and am still interested in CMSs and different CMS implementations and ideas. My head was always full of ideas for the CMS of my dreams. So I decided to build the CMS I wanted to use for my own projects.

I wanted it to be feature-rich, easy to use, and open source.

Status

It’s a hobby project and should be treated as such. I’ve been running some websites with CondationCMS since the beginning. There have been some issues along the way, but the current version is stable.

https://condation.com

https://github.com/CondationCMS/cms-server

The website is not completely up to date yet, but I'm working on adding more content. If anyone wants to give CondationCMS a try, I'd be happy to hear your feedback!


r/java • • 2d ago

Faster by Design: Performance engineering in the Microsoft JDBC Driver for SQL Server

Thumbnail devblogs.microsoft.com
45 Upvotes

r/java • • 2d ago

Campfire port in Java is faster then Rust. Some thoughts about JEP 544 (AOT Code Compilation)

Post image
133 Upvotes

DHH is porting campfire to Rust. I saw port in C# so I was wondering about Java performance. I asked Claude to do the migration, and even though the first version was faster, it was very far from idiomatic Java. I tried to close the gap, but some compromise had to be reached in order to make this work as a drop-in replacement.

Also, some typical Java approaches were just slower. Probably both the Rust and Java implementations could probably do better in terms of performance and being closer to how idiomatic code is written by everyday developers

Stack is Java + quarkus.

Beside just Java migration I tested some new feature like AOT with training introduced in Java 28 (EA build). My main conclusion is - its hard to beat a language that will adjust code to how your app is used. Its more about the JVM than Java.

I tried different combinations of AOT also with Graalvm CE. I didn't put much effort into making graal more optimal. Probably fair comparision would be to also do training run and add EE edition.

What I notice, and it's obvious in hindsight, AOT helps when end usage is same as training usage. When id differs code it optimized for different path and it hurts execution. It's not so visible in benchmark numbers but on smaller and shorter runs it was more visible. JIT needs time to adjust.

Edit: Repo: https://github.com/kgonia/once-campfire-java


r/java • • 2d ago

Eclipse WaSP 4.0.3 released! (provides Pages/JSP support for Quarkus)

Thumbnail github.com
11 Upvotes

r/java • • 2d ago

IntelliJ IDEA's Java & Kotlin extension for VS Code and Cursor is now 1.0

Thumbnail blog.jetbrains.com
63 Upvotes

Hey folks,

Marco here, from JetBrains. About 10 weeks ago we released a preview of an LSP-based extension, that brings our Java & Kotlin intelligence to the VSCode universe - now it's hit 1.0.

We'd love you to give it a try and give us feedback:

For now you've got:

  • Java, Kotlin, and mixed-language project support
  • Navigation, find usages, smart completion, IntelliJ inspections
  • Refactorings and quick-fixes
  • Maven, Gradle, and Bazel(!) import
  • Good performance on large projects and monorepos
  • JUnit test runner support
  • Debugging, including emulated breakpoints and async stack traces
  • Nullability analysis with JSpecify, plus Spring-aware inspections

To install:

  • just search for "Java and Kotlin by IntelliJ IDEA" under extensions
  • or do "Ctrl / Cmd+P → ext install JetBrains.intellij-server" inside VSCode or Cursor.

A word on licensing: with 1.0 the free preview ends and after a 30-day free trial you'll need an IntelliJ IDEA Ultimate subscription.

Let us know what you think, we'll be in the comments.

We're especially interested in hearing from people using it on big Gradle or Bazel builds. And in any problems and errors you encountered, so we can improve.

Thank you

Marco


r/java • • 1d ago

Migrating Java Applications to AWS Serverless: A Practical Guide

Thumbnail javarevisited.substack.com
0 Upvotes

r/java • • 3d ago

Should a request DTO be a value class (JEP 401)?

62 Upvotes

In a year or so, we'll need to recalibrate our intuition about which kind of type to use for each class. Originally, we used classes for everything. Then we got record, and now we get another keyword, value, which expands the number of options we have when defining a type.

I remember that in C#, there's always the question: "Should I use a class, a record, a readonly record, a struct, or something else"? They have some guidelines that consider not only identity semantics but also the size of objects (i.e., how many fields they have and how much memory they occupy).

So, if I just need a type to deserialize JSON from an HTTP request, should I use a value type? Or does it also depend on the number of fields? For example, if it has 15 int fields, should I still make it a value type if it is semantically a value, even if copying it could potentially be more expensive than passing a reference (assuming that's how it works)?


r/java • • 4d ago

Killing Reflection at Build Time: Avro, Codename One and Java Code Generation (Foojay Podcast #103)

Thumbnail youtube.com
23 Upvotes

In this episode of the Foojay Podcast, Dmitry Moskalyuk and Shai Almog compare how they cut runtime reflection out of very different projects.

Dmitry runs a backend model layer that takes JSON, XML, YAML and TOML and converts it all to Avro. His choice between Jackson and kotlinx.serialization came down to where the reflection cost actually hides. Shai works on the Codename One code generation pipeline, which aims for no reflection, no service loader and no Class.forName.

Topics include Jackson Blackbird versus kotlinx.serialization, the missing unknown-fields feature that sent one team back to Jackson, generated code (Lombok, Manifold, jOOQ), what Records and Project Leyden change, and build time cost versus runtime cost.

Available in your favorite podcast app and on YouTube:
YouTube: https://www.youtube.com/watch?v=smHzWWNOyMU

Disclosure: I host the Foojay Podcast.


r/java • • 5d ago

OpenJDK 28 EA build 20 is now available with JEP 544 (AOT Code Compilation)

Thumbnail jdk.java.net
64 Upvotes

r/java • • 5d ago

A plugin that keeps parent folders visible in JetBrains IDEs

14 Upvotes

The third plugin I created a long time ago as a proof of concept is now stable. And it's free because free is a fair price.

Here's the thing — when you scroll through a deeply expanded project tree, the parent folders disappear offscreen. I built Sticky Project View to keep them pinned at the top so you can still see where you are.

The demo clip shows the same project with the plugin disabled and enabled. The pinned rows keep the tree’s existing styling.

It’s also free and open source: JetBrains Marketplace · GitHub

Demo: https://youtube.com/shorts/XsbLyD3ZBcs

r/java • • 6d ago

Does shrinking a JDBC connection pool actually save PostgreSQL memory? I measured it.

39 Upvotes

At a previous company, I spent quite a bit of time tuning a custom-built JDBC connection pool. One of the most effective memory optimizations I found was automatically shrinking the pool during idle periods. PostgreSQL uses a process-per-connection model, so keeping unnecessary connections open has a real memory cost.

I wanted to revisit this with HikariCP and measure both the memory savings and the cost of reopening connections.

I ran two Spring Boot instances sharing PostgreSQL 16, comparing three pool configurations under the same burst → idle → burst workload.

Results:

  • Default pool: 20 connections remained open, PostgreSQL memory ~57.5 MiB.
  • Shrinking pool: connections dropped to 2, PostgreSQL memory ~28.5 MiB.
  • Savings: ~29 MiB of PostgreSQL memory.

The tradeoff was connection reopening. Median acquisition time increased from under 3 ms to around 200 ms when traffic returned.

One interesting detail: setting minimumIdle=1 alone wasn't enough when idle retirement was disabled. The pool still held all 20 connections after the burst.

The experiment used a deliberately short idle timeout to make the behavior observable, not as a production recommendation.

With many application instances maintaining independent connection pools, the potential savings can add up.

To clarify the practical motivation: this was a deliberately small experiment to isolate the effect, not just an exercise in saving 29 MiB on one server.

At my previous company, we had many application VMs connecting to a shared PostgreSQL database. Shrinking idle pools across those instances produced substantial aggregate memory savings. For example, 30 instances with 32 connections each means 960 persistent connections. If idle retirement brings that down to an average of 16 per instance, that's 480 fewer PostgreSQL connections consuming resources.

Actual savings depend on the workload, but this is where the approach becomes particularly valuable.

Full article, measurements, and reproducible experiment:

https://pvrlabs.xyz/articles/spring-boot-jdbc-pool-reclaim.html

Do you use fixed-size pools in production, or allow idle connections to retire?


r/java • • 6d ago

Introducing Titan, an open-source message dispatcher

7 Upvotes

Hi, I've been building Titan, an open-source message dispatcher for apps that need to send updates to connected clients.

An app publishes a message to a destination, and Titan delivers it to anyone subscribed to that destination. It supports STOMP over TCP and WebSocket, and there's a Java client with Spring Boot integration.

I'm thinking of uses like chat rooms, in-app notifications, and live dashboards. For example, people viewing the same dashboard could receive updates as they happen instead of having their browsers keep polling the backend.

Messages are kept in memory, so they won't survive a server restart. That's something to keep in mind if your application needs persistent messages.

I wanted to build something useful that I could share with other developers working on messaging applications. I'd be interested to hear whether this fits anything you're building, and what's missing for your use case.

https://github.com/traffic-hunter/titan


r/java • • 6d ago

HeapLens is now available in IntelliJ IDEA as well

26 Upvotes

The initial package targets macOS Apple Silicon and IntelliJ IDEA 2026.1–2026.2.

A heap dump tells you what is in memory. The harder question is: why is it still there?

I built HeapLens, a free, open-source plugin that brings heap investigation into IntelliJ IDEA.

With HeapLens, you can:

  • Explore class histograms and dominator trees.
  • Follow “Why alive?” paths to understand object retention.
  • Inspect fields and trace incoming references.
  • Query heap objects using HeapQL, a SQL-like language.
  • Navigate to matching Java source.
  • Use optional AI assistance to explain findings and propose changes for review.

Heap analysis runs locally through a bundled Rust engine—no separate analysis-server installation required. AI features use your configured provider, and Fix with AI asks before sending source code.

If you investigate Java memory issues, I would love your feedback: what is the hardest part of your current heap-analysis workflow?

HeapLens Marketplace listing
Source code and feedback

#Java #IntelliJIDEA #JVM #PerformanceEngineering #memoryleak #performance #heaplens


r/java • • 7d ago

☕ actions/setup-java v6.1.0 is out!

Thumbnail github.com
21 Upvotes

Eclipse Temurin on Linux RISC-V, improved Java version matching, Maven server credential origins & plugin repositories, plus GPG cleanup fixes.


r/java • • 7d ago

Dependencies-only AOT cache?

9 Upvotes

I am investigating using an AOT cache to speed up the startup time of our services.

I'm specifically interesting in speeding up the time between a developer making a change to the code and having that code running in a remote dev K8s cluster.

I've previously dismissed an AOT cache for this purpose because I knew that it would result in a longer build time than would be saved in startup time. That isn't a criticism - AOT caching just didn't seem targeted at my problem.

However, the majority of our classpath involves third party dependencies yet a minority of our development builds and deployments involve changes to those third party dependencies. If I could work out a way to avoid invalidating the AOT cache whenever our own code changed, then this would give us a cache that could be reused for the majority of our dev builds (removing the additional build time) whilst still enjoying the faster startup speed.

I note that https://openjdk.org/jeps/483 says this:

All runs must have consistent class paths. A subsequent run may specify extra class-path entries, appended to the training class path; otherwise, the class paths must be identical.However, I note that https://openjdk.org/jeps/483 says this:All runs must have consistent class paths. A subsequent run may specify extra class-path entries, appended to the training class path; otherwise, the class paths must be identical.

So, could I create an AOT cache for JUST the third party classes and then add our own code in later, thereby allowing me to reuse the AOT cache between dev builds?

I'm not 100% on how to achieve this yet but maybe if the training run only had the dependencies on the classpath with a custom launcher. The launcher's child classpath would then have our own code on it.

Then for the production run, I would still have the custom launcher (because I think this has to be identical between training and production runs) and I would then append our own jars onto the end of the classpath (which seems to be allowed by the JEP). Finally, we would run our real main method, rather than the launchers main method because I think we are allowed to have different main classes between training and production runs.

Anyway is this a terrible idea or has anybody already done something like this?


r/java • • 7d ago

Java sessions at WAWTech, 26–27 November

15 Upvotes

Hi, everyone! Its a two-day technology conference covering software engineering, AI and product development. It’s organised by DOU, and I’m part of the team. Here’s Java-related part:

  • Nicolai Parlog: modern Java, including pattern matching, virtual threads and the language’s future.
  • Adam Warski: structured concurrency, safe cancellation and lightweight channels.
  • Denys Makogon: Java/C++ integration, particularly the differences in memory management, object lifecycles and error handling.

The event takes place at EXPO XXI in Warsaw on 26–27 November 2026. Sharing the specific sessions here for people following these areas of Java development.

Event details, if you’re considering going.


r/java • • 8d ago

Javalin 7 vs Spring Boot 4 on a 256 MiB VM: 4x faster startup, but memory under load was closer than I expected

41 Upvotes

I've been running a series of Java performance experiments with different frameworks. This time I wanted to explore a less mainstream, more lightweight option, so I picked Javalin 7.

I built equivalent JDBC/H2 APIs in Javalin 7 and Spring Boot 4 on JDK 25, then ran each on a 256 MiB Alpine VM (1 vCPU) through a five-minute, 1,500-request workload.

Both used the same JVM flags: -Xms16m -Xmx80m -XX:+UseSerialGC -Xss512k.

Metric Javalin Spring Boot
Startup to ready 2.46 s 9.89 s
Idle Java RSS 90 MiB 119 MiB
Workload Java RSS 106 MiB 119 MiB
Min guest MemAvailable 70 MiB 45 MiB
Successful requests 1,500/1,500 1,500/1,500

What stood out: startup is where the gap is large. Under load, the RSS difference shrank to 13 MiB, as Javalin's footprint grew while Spring Boot's stayed relatively flat.

I expected Javalin to be lighter, but I wouldn't read this as a reason to replace Spring Boot. Spring Boot provides a lot of functionality out of the box that you'd need to assemble yourself with Javalin.

Caveats: one run per implementation, different web servers (Jetty vs Tomcat), and no attempt to isolate framework overhead from other components. I also didn't test AppCDS, Spring AOT, or native image, which could change the startup picture.

Full charts, methodology, and raw results:

https://pvrlabs.xyz/java-performance/experiments/javalin-vs-spring-boot-256mb.html

For those who've used Javalin or similar lightweight Java frameworks, how has the trade-off between smaller footprint and Spring Boot's built-in functionality worked out in practice?


r/java • • 8d ago

Rainbow Gum 0.15.0: ScopedValue key values, logging into JFR, and OpenTelemetry without the SDK

29 Upvotes

Rainbow Gum 0.15.0: ScopedValue key values, logging into JFR, and OpenTelemetry without the SDK

I try not to spam every release, but 0.15.0 has some stuff I'm genuinely excited about, and 1.0.0 is coming before the holidays hence need some feedback.

First up, Scoped Key Values. MDC on ThreadLocal has been leaking requestIds into the wrong requests since the dawn of time because somebody forgot a finally block or threadpool cleanup. JDK 25 gave us ScopedValue (JEP 506) and holy shit it just fixes it:

ScopedKeyValues.builder()
    .add("requestId", requestId)
    .add("userId", userId)
    .run(() -> {
        logger.info("handling request"); // has requestId and userId
        service.handle(request);
    });

StructuredTaskScope forks get a frozen snapshot, so sibling tasks can't stomp on each other. I barely had to do anything; the JDK devs did the hard part, and this is what MDC should be going forward. This should hopefully get added to SLF4J 3.0. Bless the JDK team.

Next, logging straight into JDK Flight Recorder. Each log event becomes a JFR event, so your logs sit on the same timeline as GC pauses and lock contention in JMC:

logging.appenders=jfr
logging.appender.jfr.output.uri=jfr:///var/log/myapp.jfr

No -XX:StartFlightRecording flags to screw up in your Dockerfile. And here's the kicker: in our benchmark, logging to JFR was about 40% faster than plain text to a file, and the output was about 8x smaller on disk. The JFR folks built something seriously fast and most of us only ever open it when production is on fire.

Last, OpenTelemetry. rainbowgum-otlp ships logs over OTLP using nothing but the JDK's own HttpClient. No OpenTelemetry SDK, no OkHttp. It's roughly 7x smaller than the Logback or Log4j2 OpenTelemetry setups with their default dependencies: https://github.com/jstachio/rainbowgum/blob/main/doc/why/opentelemetry_export_size.md

Oh and here is something shocking. The Logback and Log4j2 OpenTelemetry appenders hand events to the SDK, whose batch processor has a 2048 event queue by default. When it fills up, it throws your logs away and doesn't tell you. When we blasted a burst of logs at a collector with stock settings, only about 7% (Logback) and 10% (Log4j2) of them made it. Rainbow Gum applies backpressure by default, and if a batch does fail you get an alert and a metric, not silence. Losing logs exactly when your app is getting hammered is the worst possible time to lose logs. On a related note after bugging them I think Spring Boot might had some more observation hooks to logging frameworks.

There's a lot more (colorful logs with no pattern strings, error messages that tell you exactly which property is wrong and where it came from). You can even cosplay as a Go process with logfmt support. The longer pitch is here: https://github.com/jstachio/rainbowgum/blob/main/why_rainbowgum_is_better.md

GitHub: https://github.com/jstachio/rainbowgum

Docs: https://jstach.io/doc/rainbowgum/current/apidocs/

Before 1.0 I can still break things without feeling bad about it, so if the API or the property names bug you, now's the time to tell me. Brutal honesty welcome.

Finally I'm not a paid professional OSS developer so this library like my others is sort of a love letter to the Java community and language.