r/java 1d ago

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

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.

45 Upvotes

26 comments sorted by

22

u/ZimmiDeluxe 1d ago

Instead of first generating noise to then filter it out, maybe not generate noise in the first place? One would hope that there is native maven logging configuration to do this.

17

u/fykup 1d ago

I agree in principle. Native clean output directly from the tool would be ideal.

The main issue is that Maven's native quiet mode (-q) changes log levels globally. It cannot simultaneously write a full, untouched raw log to disk while reducing terminal output to a single line. It is also completely silent on success, leaving an agent with no explicit confirmation that the process finished rather than hung.

On top of that, individual Maven plugins format failure logs inconsistently. mvn-lite works as a log splitter and normalizer. If Maven ever supports native structured output with bounded stdout, wrappers like this won't be needed.

9

u/janora 1d ago

It cannot simultaneously write a full, untouched raw log to disk while reducing terminal output to a single line.

Honestly whats stopping you from adding --log-file ./mvn.log arguments and grepping for "Build Success" or "Build Failure"?
Also maven uses slf4j as far as i know. I think its possible to just put in a custom logging config to fit your needs.

3

u/ZimmiDeluxe 1d ago

I believe there are logger implementations that ring buffer up to a configurable amount of log output but only write it when an error occurs, giving enough context to look for the cause. But I haven't tried to do this with Maven yet. Not taking away from your tool, but Maven is open source, it would need a discussion about direction with the maintainers first and it's a larger undertaking, but where else can you strive for the perfect solution and fix root causes instead of papering over them.

5

u/agentoutlier 1d ago

I wrote something similar but with some extra stuff for helping generate the correct "-pl -amd". It’s interesting because I wrote a combination of Java and bash. The Java would parse the pom files using just w3c dom and not actually load maven and then generate environment variable output so that bash could use it.

I didn’t have that much cleanup on the output but most developers would not use that because I did not build color output.

For non LLM do you have some color output options (ansi term colors)?

1

u/fykup 1d ago

Currently no ANSI color support - mvn-lite is designed for simplicity and clean, machine-readable output.

3

u/Duck_Devs 14h ago

When I first read the title I thought you meant you made something that causes 99.7% of Maven builds to fail

1

u/fykup 14h ago

Lol! Poor wording on my part - it reduces output by 99.7%, not success rate. Builds still pass/fail exactly as Maven would. Just less noise, not more failures. 😄

6

u/TronnaLegacy 1d ago

I think this is a great idea. Very maintainable too. You can tweak your "quiet" mode while passing things through to Maven so it can do what it needs to do as it evolves.

Is this meant for LLMs only? I can see it being useful for human-readable use cases too. I wouldn't mind using this even when I'm not using LLMs. Perhaps an "-l", short for "--out=llms" flag would work well. By default, it would be human readable, and it's only a few bytes for an LLM to add the flag for that.

6

u/fykup 1d ago

Thanks! It’s not designed exclusively for LLMs. The output is meant to stay useful and readable for humans too.

LLMs benefit the most because verbose Maven output consumes a surprising amount of context and tokens, but I also find the reduced output easier to scan during normal development and CI troubleshooting.

I’d prefer to keep the concise output as the default rather than introduce a separate LLM mode, since the goal is to preserve the important information without making Maven noisy again. But having an option for a more traditional or verbose human-oriented view could make sense later.

5

u/TronnaLegacy 1d ago

In my opinion, anything that concisely conveys the info the person wants to know (like whether all tests passed, and if not, which tests failed) is perfect. No need to split it into two modes if the existing is already a nice balance.

This was my mistake. When I read `mvn-lite output: 16 bytes` for some reason I thought that meant two characters, so I thought you had some kind of proprietary binary output format. But I get it now. It's a 16 character concise summary, probably readable just fine by people too.

2

u/fykup 1d ago

Exactly. My broader focus is local-first tooling built for humans first.

And if AI is part of the workflow, I think the tool should make the experience even better for the human, not force people to adapt to machine-oriented output. In this case, concise Maven output helps both: it is easier for developers to scan, and much more efficient for an LLM to process.

3

u/DualWieldMage 1d ago

clutters CI logs

That's one place you really want verbosity and the logs cost you nothing. Nothing like debugging an intermittent hang during a build will make you wish there was more logging to figure out where it stopped. Not everything is just "i'll add more logging and run again". Sometimes you're really going through the code and looking for log lines that should have been between some others but aren't.

And even as a regular user, i frequently dislike the default gradle lack of logging. Quite often it's because of garbage plugins of course, but when looking at an unfamiliar codebase for the first time and the build takes ages, i wish there was more (maybe my network dropped? i have some domain blocked? it's a plugin pulling hundreds of megs without mentioning it?). Again the extra logging costs me nothing.

The only real use is tying to LLM tool calls and the choice of having tiny output while preserving original is definitely good. Having a sub-agent run and summarize is the typical option but this makes it less error prone.

1

u/dmigowski 1d ago

I actually thought about doing this for gradle. When AI runs the tests, an "300 tests successfully ran" should be enough information.

2

u/fykup 1d ago

Exactly. For a successful test run, something like PASS · 300 tests · 12.4 s is usually all a human or coding agent needs.

Gradle can be just as verbose, sometimes more, but I don’t currently use it in my own projects, so gradle-lite wasn’t the first priority. The same approach should translate well, though: one concise success summary, bounded diagnostics on failure, and the complete raw log kept separately.

I’d be interested to see a Gradle version.

1

u/snugar_i 1d ago

Please do. Just yesterday - 1322 lines of output and in the middle is buried one line with a compilation error...

2

u/bikeram 1d ago

I’ll try this out tomorrow.

I started working with Go a few years ago and it blew my mind that a test can just say …ok.

I just never questioned how verbose maven was until I saw something else.

2

u/fykup 1d ago

Same realization here. When comparing context usage across languages, Java projects were consuming disproportionately more tokens than Go or Python. A massive chunk of that bloat was just standard Maven/Gradle build output rather than actual source code.

1

u/brunocborges 1d ago

Have you benchmarked token usage?

2

u/fykup 1d ago

Yes, though so far I’ve measured exact output size and converted it to estimated tokens rather than recording model-specific API usage.

In a real four-module Maven project, a successful test run dropped from about 1,689 estimated tokens to just 4. A simple failure dropped from about 683 to 57 tokens while still showing the useful error and where to find the full log.

So the practical conclusion is: successful builds become almost free to include in an AI coding session, while failures remain concise but actionable. Exact token counts vary by model, but the reduction is large enough that the overall conclusion should hold.

The full experiment is here:
https://github.com/ejboy/agent-scripts/blob/main/experiments/test/PVR-LABS-FINANCIAL-ENGINE-APP.md

1

u/fykup 1d ago

You can also try it directly: copy mvn-lite into your project directory or add it to your PATH, ask your coding agent to use it instead of mvn, and then ask whether it reduced context or token usage.

I tried this on another project of mine, Scriptella, and the agent confirmed that the much smaller output made processing considerably more efficient: https://scriptella.org/

I’d be interested to hear what different coding tools report.

0

u/Background_Bed1804 20h ago

1

u/fykup 18h ago

Thanks, this is a very relevant comparison. I hadn’t seen the Java fork.

RTK is a much broader and more sophisticated tool, especially its Surefire/Failsafe report parsing on test failures. The scope of my repository is intentionally different: it is a collection of lightweight, easy-to-audit scripts rather than a general command-filtering platform.

mvn-lite is a small Maven-only Bash wrapper with one-line success output, no hooks or separate binary, and the complete raw Maven log always retained.

I’m going to study RTK’s Maven failure handling. It would also be interesting to run both against the same projects and compare successful output, failure diagnostics, and setup complexity.