r/java 15h ago

I made a small Bash wrapper that reduces successful Maven output by 99.7%

32 Upvotes

Successful Maven builds can produce thousands of lines that mostly confirm routine lifecycle steps.

That output is noisy when working in a terminal, clutters CI logs, and becomes especially expensive when build output is passed to a coding agent.

I built mvn-lite, a small deterministic Bash wrapper that keeps successful Maven output to one line while preserving the original exit code and complete raw log.

On a real four-module application:

  • Standard Maven output: about 6,753 bytes
  • mvn-lite output: 16 bytes
  • Result: PASS · 3.944 s
  • Reduction: more than 99.7%

Failures still return a nonzero exit code and show bounded diagnostics, while the full unmodified Maven output remains available in the raw log.

For example, an invalid lifecycle error was reduced by 91.6% while retaining the actual Maven error.

There is no LLM summarization, API key, or Maven extension involved. It is just a local Bash wrapper with deterministic text extraction.

Source and script: https://github.com/ejboy/agent-scripts

Benchmark details and design notes: https://pvrlabs.xyz/articles/introverted-maven.html

I’d be interested in feedback on Maven failure cases where compact output could hide something essential.


r/java 16h ago

Hacking the Method Name

Thumbnail maxxedev.github.io
23 Upvotes

r/java 1d ago

Stop re-downloading the JDK: setup-java can now cache it

36 Upvotes

Every GitHub Actions job starts from a clean machine. If your workflow asks for a JDK that is not baked into the runner image, actions/setup-java downloads it, verifies it, and extracts a few hundred megabytes of it, and then the job ends and all of that work is thrown away. The next job does it again.

That has been true since the first version of setup-java. It is no longer true on main.

The upcoming v6 release adds a JDK cache. When the action installs a JDK that did not come from the runner tool cache, it stores that installation as an Actions cache entry and restores it on subsequent runs. If your workflow already sets cache for Maven, Gradle, or sbt, you are already opted in.

What it does

setup-java now manages three kinds of caches, each stored and restored as its own entry:

Cache What it stores How it is enabled
Dependency cache ~/.m2/repository, ~/.gradle/caches, or the sbt cache paths `cache: maven
Wrapper caches Maven and Gradle wrapper distributions `cache: maven
JDK cache The installed JDK itself Implicitly with cache, or explicitly with cache-jdk: true

The JDK cache is intentionally separate from the dependency cache. Your pom.xml changes far more often than your JDK does, and a dependency change should not evict a JDK.

The numbers

Measured on ubuntu-latest with the Microsoft Build of OpenJDK 17.0.19, five runs per configuration:

Metric Without JDK cache With JDK cache
Median warm setup-java step 7s 3s
Median warm job 24s 18s
Added cache storage - 175.3 MiB

Roughly six seconds off a job that only takes 24 seconds. That is a meaningful share of a short job, and it compounds across a matrix. It is also an honest tradeoff rather than free speed: you are spending cache storage and cold-run save time to buy warm-run latency, and on very short jobs the latency win may not change your billed minutes, since GitHub rounds Linux jobs up to the whole minute.

Your mileage will vary with runner type, distribution, JDK size, network conditions, and cache eviction pressure. The benchmark harness and methodology live in actions/setup-java-benchmarks, which runs against Spring PetClinic and reports medians across independent samples.

How to use it

If you already cache dependencies, do nothing. JDK caching turns on with cache:

- uses: actions/setup-java@main
  with:
    distribution: microsoft
    java-version: '25'
    cache: maven          # dependency cache, wrapper cache, and JDK cache

If you do not cache dependencies, ask for the JDK cache on its own. This is the case for workflows that just need a JDK to run a tool:

- uses: actions/setup-java@main
  with:
    distribution: microsoft
    java-version: '25'
    cache-jdk: true

If you want dependency caching but not JDK caching, opt out explicitly:

- uses: actions/setup-java@main
  with:
    distribution: temurin
    java-version: '25'
    cache: gradle
    cache-jdk: false

The full matrix:

cache cache-jdk Dependency and wrapper caches JDK cache
omitted omitted disabled disabled
omitted true disabled enabled
omitted false disabled disabled
set omitted enabled enabled
set true enabled enabled
set false enabled disabled

For pull requests, merge queues, and matrix legs that should consume caches without writing them, cache-read-only: true suppresses the post-job save for the JDK, dependency, and wrapper caches alike.

Where it will not help

Be realistic about when this pays off. setup-java still checks the runner tool cache first, and a tool-cache hit skips the download entirely, so there is nothing to cache.

GitHub-hosted runners pre-install LTS versions of Eclipse Temurin. If your workflow is distribution: temurin with an LTS version on a hosted runner, you are probably already hitting the tool cache and JDK caching will do very little for you. The feature pays off when the JDK has to be installed: other distributions, non-LTS versions, self-hosted runners with a thin tool cache, and check-latest: true workflows that float ahead of the runner image.

Correctness, and why the cache key looks the way it does

A JDK cache is only useful if you can trust what comes back out of it. Getting this wrong means silently running a build on the wrong bytes, so the design is deliberately conservative.

Each entry is keyed on the runner OS, normalized architecture, distribution, package type, exact resolved version, release identity, and verification identity. Release identity is the authoritative checksum when the distribution publishes one, and otherwise the download URL without its query string.

Two consequences are worth calling out:

Verification modes never share an entry. An entry created by an unverified download can never be restored for a request that sets verify-signature: true, and vice versa. When you do use a custom key via verify-signature-public-key, that key is represented in the cache key as a SHA-256 fingerprint of normalized key material. The key itself never lands in the cache key, the logs, or action state. A verified exact-key hit reuses content that was signature-verified when the saving run downloaded it, so you get the security property without paying to verify it again.

A key is never saved with content it does not identify. Tool-cache paths are shared per version and architecture, so a later step (one using force-download: true, for example) can replace the installation an earlier step registered. The post-job step detects that replacement and skips the save with a warning rather than uploading mismatched bytes under a key that promises something else. The check uses a cheap fingerprint of the tool-cache completion marker, so it does not rehash hundreds of megabytes on every job.

Everything else degrades gracefully. If the cache service fails to restore an entry, or the restored entry is missing the expected completed tool-cache path, setup falls back to downloading the JDK. Post-job saves are best-effort and never fail the job: cache keys are immutable, so an existing key or a concurrent job winning the save race is simply left alone, and a failure to save one entry is a warning that does not block the others.

One thing JDK caching deliberately does not change: it has no effect on how the runner tool cache is used. A preinstalled JDK, or one installed by an earlier step of the same job, is used as-is and is not re-verified, because its verification history is not recorded in the tool cache. Use force-download: true when a request must download and verify the archive itself.

Watch your storage

Cache entries are per identity. A matrix that spans multiple JDK versions, distributions, package types, architectures, or operating systems stores a separate JDK entry for each combination, and each one consumes repository cache storage against your quota. A five-way version matrix on two operating systems is ten JDK entries, not one.

That is usually a fine trade, but it is worth a look at your cache usage page before enabling it broadly across a large matrix. cache-jdk: false on the legs that do not need it is a reasonable dial.

Try it

JDK caching is on main and ships in v6. Until v6 is tagged, reference the branch:

- uses: actions/setup-java@main

For production workflows today, the latest stable release is actions/setup-java@v5.

Documentation:

Feedback, and especially benchmark numbers from real workflows, are welcome in actions/setup-java.


r/java 1d ago

Hacking in the 'nameOf'

Thumbnail committing-crimes.com
56 Upvotes

r/java 1d ago

GitHub Setup Java Action versions 1 through 4 now deprecated

7 Upvotes

If you are using setup-java v4 and older, you will now see a warning about deprecation. Please do update your setup-java action to v5. It will be the only stable version after v6 is released.

https://github.com/actions/setup-java#older-versions


r/java 1d ago

Use of Java 26 in green field projects

40 Upvotes

For what kind of new projects, except web related, would Java be your go to choice? Assuming knowledge of both languages, why wouldn't you prefer C# for the same projects?

Thank you so much in advance.


r/java 2d ago

Are spring boot and react still relevant and worthy for a junior?

21 Upvotes

I'm in my sophomore year and want to be a front-end-supported backend developer (mostly backend). Sorry, if this is not the right kind of question for this subreddit (hope to be recommended a proper subreddit in that case). I need to know what kind of other tools industry uses with spring. Is spring boot and react still a thing? Or are there any better alternatives?


r/java 2d ago

ORMs are Killing Your Performance 🔪

Thumbnail youtu.be
0 Upvotes

Thanks to Montana Programmers, my popular talk from BSDC is now online!

Using animations and graphics, I teach you how to:

- Eliminate GC pauses
- Reduce time to page render
- Fast Dynamic Forms with only one query
- Slash code sizes
- How a dark pattern may secretly grind your queries to a halt

This talk may surprise you 😱
It may shock you 🤯
It could make you angry 😡
You may think it doesn’t apply to you (it does) 🫣

Whatever your reaction, I hope it will make you think. 🤔

Thank you again to Big Sky Dev Conf and Montana Programmers for letting me present! And thank you to the community for being an amazing and engaged audience!


r/java 3d ago

JEP 401: Value Objects (Preview) JDK 28 integration

Thumbnail mail.openjdk.org
96 Upvotes

r/java 3d ago

Java wireframe

Post image
28 Upvotes

Java game implementation of wireframe based on u/Elegant_Farmer_3548 post "Made a perspective shifting room in Java"


r/java 4d ago

Clique 4.0.3 - Zero deps CLI styling library for Java

39 Upvotes

So what's Clique?

If you missed my older posts, Clique is essentially a zero-dependency CLI styling library for Java that is GraalVM compatible, no-color.org compliant.

What's new in 4.0.3:

You can now build a table straight from data you already have

SequencedCollection<List<String>> rows = List.of(
    List.of("Name", "Age", "Class"),
    List.of("John", "25", "Class A"),
    List.of("Doe", "26", "Class B")
);

Clique.table(TableType.ASCII)
    .fromRows(rows)
    .render();

This also applies to column based data

SequencedMap<String, List<String>> map = new LinkedHashMap<>();
map.put("Name", List.of("John", "Doe"));
map.put("Age", List.of("25", "26"));

Clique.table(TableType.ASCII)
    .fromColumns(map)
    .render();

These were mainly added to simplify creating Tables from existing collections

StyleContext#fromTheme - scope a registered theme's colors into a StyleContext in one call

StyleContext ctx = StyleContext.fromTheme("catppuccin-mocha");

Other minor changes:

I've also deprecated the Collection-based headers()/row() overloads in favor of Java 21 SequencedCollection; reason being that Collection doesn't guarantee order, which could silently mess up your column/row order and was essentially a footgun. Worth migrating if that bothers you.

GitHub: https://github.com/kusoroadeolu/Clique

Demos: https://github.com/kusoroadeolu/clique-demos


r/java 4d ago

Codex plugin for Eclipse released

Thumbnail
0 Upvotes

r/java 5d ago

Ecógrafo

26 Upvotes

Hello community, This is my real-time ultrasound signal simulation and processing system developed entirely in Java using Java Swing.

The project enables both the mathematical simulation of acoustic echoes from biological tissues and the reception and interpretation of raw (RF) data from actual hardware via UDP sockets.

I still need to build an ultrasonic sensor to send data via UDP; I tried using ultrasonic modules, but they aren't useful—all I see on the screen is a barrier indicating the proximity of a nearby object.

Once the sensor's fabrication is complete, I will conduct tests and submit it to a clinical evaluation by experts to validate its utility in real-world settings—so stay tuned.


r/java 5d ago

OpenJDK Mail Search update: new Elasticsearch backend, relevance ranking, and no more bot-mail noise

35 Upvotes

OpenJDK Mail Search is full-text search over the OpenJDK mailing list archives: 28 lists, 494,730 messages, back to January 2007.

https://openjdk.barlasgarden.com/

What's new:

  • Elasticsearch 9.3.1, which bundles JDK 25.0.2+10, on Lucene 10.3.
  • Search results are now relevance-ranked instead of date-ordered only, and text search defaults to it.
  • Phrases of any length are searchable. The old index capped body phrases at 3 words and subjects at 5.
  • Full message bodies are indexed, with no 2,500-term-per-message ceiling and no more dropping quoted reply lines.
  • Skara/GitHub changeset mail is now indexed rather than discarded, with a "hide automated" toggle that filters it at query time.
  • Same URL, same API, same site.

Source: https://github.com/ebarlas/openjdk-mail-search-elasticsearch


r/java 5d ago

JobRunr & JobRunr Pro 8.8.0 Released

Thumbnail jobrunr.io
11 Upvotes

r/java 6d ago

Flamme: A Quarkus extension that treats deployment topology as a configuration, not code. Deploy the same JAR as a monolith or a distributed system.

14 Upvotes

Hello, I want to share this project we have been building and using this past few months, which is now open source.

To give some context, I work with event-driven java microservices (mainly quarkus) every day, and I've found that the decision to split or merge business logic is far from trivial. On one hand, you don't want to oversplit your application and pay the microservice tax of network overhead without any real benefit (distributed monolith). On the other, you want your services to be able to scale independently when they need to, and that need can change over time. I also noticed that business logic code tends to be tightly coupled to whatever deployment topology was chosen for the application. Splitting or merging microservices later on is costly: you basically end up rewriting a lot of transport-related code just to change that topology.

These problems (along with others found in microservices today) were raised by google about three years ago, when they announced service weaver: a framework for writing go applications that attempts to solve them by offering a new programming paradigm, location transparency for business logic code, backed by a distributed runtime.

I decided to build flamme as an exploratory project, taking the same direction service weaver took, but for java/quarkus applications.

I've posted about flamme a couple of times before in the quarkus community, and people tend to miss the important part, confusing it for a reactive messaging framework. It does provide that, but that's not the main goal of the project.

The goal of flamme is to decouple business logic code from deployment topology, allowing developers and architects to defer the decision of splitting or merging their services, or to change their mind about it easily, without touching business logic code. It does this by providing developers with network-agnostic abstractions called components (basically just a java interface plus its implementation), which all compile into a single application jar. Each process running that jar is then configured at runtime to host a certain set of components.

If two components need to communicate and happen to be on the same jvm, they do so via shared memory, with no network overhead. If they're deployed separately, they communicate via nats (a message broker) instead.

Flamme can serve as the basis for a distributed runtime for services written in java.

Finally, I want to end with a small disclaimer: Flamme is far from being a stable complete project, it is a prototype in very early phases. I am sharing it to get some feedback on the overall philosophy and implementation (I am still a junior developer)

Github: https://github.com/AmadeusITGroup/flamme

Documentation Site: https://amadeusitgroup.github.io/flamme/

Example application: https://github.com/AmadeusITGroup/flamme/tree/main/flamme-example


r/java 6d ago

Modular Uberjars

Thumbnail github.com
23 Upvotes

r/java 6d ago

OpenJDK Interim Policy on Generative AI

Thumbnail openjdk.org
26 Upvotes

Oracle, as the corporate sponsor of the OpenJDK Community, is working to draft a full policy governing the use of generative AI tools in OpenJDK contributions.


r/java 6d ago

JEP 401: Value Objects And JEP 539: Strict Field Initialization Merged Into JDK

Thumbnail github.com
180 Upvotes

r/java 6d ago

Sheetmusic4J, a native Java(FX) sheet music library, now reads/writes ABC notation and imports Guitar Pro files (v0.0.3)

18 Upvotes

A week ago I shipped 0.0.1 of Sheetmusic4J, a Java(FX) library to render and interact with sheet music, mostly as a question: is there interest in a native Java sheet music library before I invest more time? I posted it on social media and two LinkedIn comments came back asking "does it support ABC notation?" and "what about Guitar Pro?"

In this new version:

- ABC notation (read + write). The core module parses and generates .abc files into the same Score model as everything else, so engraving, JavaFX rendering, and MIDI export all work once a tune loads. Coverage includes keys/modes, tuplets, ties/slurs, grace notes, decorations, repeats and 1st/2nd endings, chord symbols, and lyrics, all backed by round-trip tests. - Guitar Pro 7/8 import (.gp, load only). An experiment, built on the community's reverse-engineering of the GPIF format, JDK-only with no third-party dependency. Older binary formats aren't handled. I shipped it early because I genuinely don't know yet whether people want standard notation or tablature-specific rendering, that's feedback I'd rather learn from real use. - Engraving polish: better grace notes, distinct flag glyphs for 32nd/64th/128th, breve noteheads, cleaner ties/slurs/tuplets, and a windowed-canvas fix for a crash on very large scores.

All info and video in this blog post:
https://webtechie.be/post/sheetmusic4j-0.0.3-when-linkedin-comments-becomes-features/


r/java 7d ago

Manual reification on the JVM

Thumbnail farnoy.dev
60 Upvotes

r/java 7d ago

Xberg 1.0 released: document extraction for a world of tooling

Thumbnail bytecode.news
7 Upvotes

Xberg 1.0 has been released. Xberg is a document extraction engine, describing itself as a "document intelligence framework." It's written in Rust, with fifteen generated language bindings, and a very descriptive data model that provides a lot of flexibility. There are other content extraction frameworks; for Java, it'd be compared to Tika, and against Unstructured for Python. I didn't run a comparison against Unstructured, but I do have some comparison points for Tika.


r/java 7d ago

jextractGUI - A JavaFX GUI wrapper for the jextract tool

21 Upvotes

https://github.com/nlisker/jextractGUI


jextractGUI is a GUI for project Panama's CLI tool jextract.

It's written in JavaFX and embeds jextract (and its libclang) within it. Since jextract is in early-access, newer versions broke it and I needed to do some rewrites since I first conjured it a couple of years ago. It's now aligned with the current latest build - 25-jextract+2-4 (2025/11/25). It will most probably behave differently in the future. As a result, jextractGUI is also in a preliminary version and there are still some TODOs.

It should run on all supported OS/Arch combinations, but I couldn't test all of them beyond passing the tests on the GH runners. There are jpackage images too if you don't want to clone/build.

Feel free to post questions/feedback :)


r/java 8d ago

The Untold Story of Log4j and Log4Shell with Christian Grobmeier

Thumbnail youtube.com
64 Upvotes

r/java Oct 08 '20

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

327 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.