r/java • • 15h ago

Jdbi vs MyBatis vs jOOQ in a small Javalin REST API: memory and latency on a 512 MiB VM

5 Upvotes

I've been experimenting with lightweight Java applications on small VMs. After comparing Javalin with Spring Boot, I wanted to see how much the SQL persistence library affects resource usage.

I implemented the same small market-quote REST API using Jdbi Core, MyBatis Core, and jOOQ Open Source Edition.

Setup:

  • JDK 25, Javalin 7, H2, HikariCP
  • Alpine Linux VM, 1 vCPU, 512 MiB RAM, no swap
  • JVM: -Xms16m -Xmx80m -XX:+UseSerialGC -Xss512k
  • 1,500 requests over 5 minutes, 80% reads / 20% writes
  • Two independent runs per implementation, rebooting the VM between runs

Results across the two runs:

Library Median workload RSS HTTP p95
Jdbi Core 120.0 - 122.4 MiB 7.38 - 8.48 ms
MyBatis Core 116.6 - 118.0 MiB 7.47 - 7.52 ms
jOOQ OSE 152.1 - 154.3 MiB 9.19 - 9.35 ms

RSS is the median process resident memory sampled during the workload, including the application, JVM, and embedded H2.

All six runs completed successfully without errors, OOM events, or swapping.

A few observations:

  • MyBatis had the lowest resident memory usage in both rounds.
  • Jdbi was very competitive on both metrics, and required the least handwritten Java code.
  • jOOQ used approximately 34–38 MiB more RSS than MyBatis, consistently across both runs. This is a whole-application difference, not necessarily memory consumed directly by the library. I haven't isolated its cause.

One implementation difference worth mentioning: Jdbi and MyBatis hold one pooled connection across the three latest-quote queries, while the datasource-backed jOOQ implementation checks out and returns a connection for each query. I haven't measured the impact of this difference.

I also configured MyBatis with localCacheScope=STATEMENT rather than its default SESSION scope.

From a developer experience perspective, the tradeoffs are interesting too. Jdbi keeps SQL and mapping close to the repository, MyBatis uses annotated mapper interfaces, and jOOQ offers type-safe SQL composition with generated schema classes.

For my own applications, I generally prefer MyBatis because I like its mapper-oriented programming model and explicit SQL. Its lower memory footprint in this experiment is another point in its favor, although I wouldn't choose a library based on memory usage alone.

Limitations:

This is a small, low-load case study, not a general performance ranking. The measurements include the complete application and embedded H2. Two runs show consistency in memory usage but aren't enough to establish statistically significant latency differences.

I also didn't include a raw JDBC baseline, which would be useful as a minimal reference point. PostgreSQL could produce different results.

Full write-up, charts, implementation sources, and raw measurements:

https://pvrlabs.xyz/java-performance/experiments/mybatis-jooq-jdbi-512mb.html

I'm interested in whether others have compared these libraries in similarly small applications, particularly with PostgreSQL, and how much the programming model influences your choice.


r/java • • 18h ago

Release announcement: Sheetmusic4J 0.0.4 and 0.0.5: clickable notes, a 3D fly-over view and LilyPond support (Java and JavaFX sheet music library)

17 Upvotes

Hi all,

I've been working on Sheetmusic4J, an open-source Java library that renders sheet music natively in Java(FX). Two new releases are out, and I made a video showing both: https://youtu.be/8n7WONyX0yk

0.0.4

- NodeSheetView builds the score as a JavaFX scene graph, with one Group per note, rest and chord. Each element can take mouse events, effects and tooltips like any other node. The demo app lets you select a note and drag it up or down.

- FlyOverSheetView is a 3D play-along view. A perspective camera flies over the score, and a glowing ball per voice hops from note to note.

- Headless rendering to an image via the new render and render-awt modules, with no JavaFX needed:

BufferedImage image = HeadlessScoreImage.render(score, 1200);

- The 3000+ line Engraver class is split into focused packages, and all library modules are now JPMS modules.

0.0.5

- LilyPond (.ly) import and export through the ScoreFile facade, without running LilyPond:

Score score = ScoreFile.load(Path.of("bach-bwv610.ly"));

ScoreFile.save(score, Path.of("bach-copy.ly"));

- Engraving improvements: tuplet placement and nesting, octave clefs, and the percussion clef.

- Layouts are now identical across CPU architectures.

LilyPond support (and other formats earlier) came from suggestions on Reddit, so thanks to everyone who asked for it. Overrides and Scheme code are skipped, because the library does its own layout. The LilyPond page on the site lists what is supported.

It also reads MusicXML, MIDI, ABC and Guitar Pro.

The demo app has a "Report Visual Issue" button. It captures the Sheetmusic4J rendering, the reference PDF and your description, ready to attach to a GitHub issue. If a score looks wrong, that is the most useful feedback I can get.

- Release notes: https://sheetmusic4j.com/releases/

- GitHub: https://github.com/sheetmusic4j/sheetmusic4j

Feedback, issues and score files that break things are all welcome.

Thanks
Frank


r/java • • 15h ago

We found a bypass in Java’s eMudhra certificate blocklist mitigation

48 Upvotes

Hi r/java — I’m with Sonatype, and our research team published a write-up of a reproducible issue we found while reviewing Java’s response to the eMudhra certificate incident.

The mitigation uses SHA-256 fingerprints to block specific compromised intermediate certificates. We found that re-encoding an intermediate can change its fingerprint while leaving it valid under the tested Java trust-store configurations. We reproduced this for ECDSA and RSA certificates.

The finding began as an AI-assisted research lead, but a researcher independently tested and confirmed the behavior. We also tested removing the relevant roots, which rejected both the original and re-encoded chains; that approach has compatibility tradeoffs.

The write-up includes the reproduction and its scope: https://www.sonatype.com/blog/the-limits-of-fingerprint-blocklists-a-reproducible-java-certificate-bypass

We’d welcome technical feedback, especially on how this behaves across different JDK versions and trust-store configurations. We have not found evidence that this technique was used in the wild.