What’s New in Maven 3.9 – The “Finally Cleaning House” Release
Maven 3.9 dropped in 2023 and honestly felt like the team finally got tired of carrying all that old baggage from the Maven 2 days.
It’s still the same Maven you know – no massive breaking overhaul like 4.0 – but they upgraded the resolver big time, added a bunch of smart warnings to keep your POMs from rotting, and switched to a modern HTTP client. Builds got a little safer, a little smarter, and yeah… sometimes a tad slower on huge projects. But the trade-off? Way better security and fewer “why is this downloading from a sketchy mirror?” moments.
I’ve been running 3.9.x (up to 3.9.11 now in late 2025) on most of my enterprise gigs ever since. It’s solid.
Java Requirements – Goodbye Java 7, Hello Modern Times
Maven 3.9 finally requires Java 8 to run. About damn time.
Your projects can still compile down to Java 6 or whatever ancient version your compliance team forces on you – just tweak the compiler plugin like always. But the Maven runner itself needs Java 8+. This let them upgrade a ton of internal deps and unlock features that were blocked forever.
If you were still on Java 7 in 2023… I don’t even want to know.
Core Stuff That Actually Makes Life Easier
Maven now yells at you (politely, with warnings) when you’re using deprecated plugins, goals, or parameters. I love it – catches cruft before it bites you years later.
You can finally invoke plugins shorthand style: mvn compiler:3.13.0:compile instead of the full groupId nonsense. Small thing, but I use it all the time now.
Console output got cleaned up – no more weird ANSI escape garbage when you copy-paste logs into tickets.
Profiles can activate based on packaging (e.g., only fire WAR-specific stuff when <packaging>war</packaging>). Super handy for multi-module setups.
And it plays nice with the new 3.x install/deploy plugins out of the box – no more annoying warnings.
Resolver Got a Massive Overhaul (The Real Star Here)
The dependency resolver jumped to 1.9.x and it’s packed with goodies.
Local repo sharing got proper locking – file-based, Hazelcast, or even Redis for teams. No more corrupted metadata when ten devs hammer the same repo.
They added a “workspace” split mode for branching experiments without polluting your main local repo.
Transport switched to native Java HTTP client by default (bye Wagon!). You can still swap in others if you’re into that.
Parallel POM downloads with the new breadth-first collector – shaves time off huge dependency trees.
Remote repo filtering, trusted checksum sources (provide your own hashes to block tampered artifacts), pluggable post-processors… basically a ton of supply-chain security love.
I’ve seen CI pipelines get way more reliable after flipping on trusted checksums.
Security Wins – Finally Taking Supply Chain Seriously
The big one: trusted checksums. You can feed Maven verified hashes upfront so it rejects anything that doesn’t match. Huge against poisoned artifacts.
Remote repository filters let you whitelist only trusted sources. No more accidental pulls from random mirrors.
It’s quiet protection – doesn’t get in your way, but blocks a whole class of attacks. Every enterprise team I work with now mandates this.
Performance – The One Downside Everyone Complains About
Full disclosure: on massive multi-module builds, 3.9.0 was roughly 10% slower than 3.8.x. The new transport and collector added overhead.
Later patches (especially resolver updates in 3.9.9+) improved memory usage and fixed some bottlenecks. Parallel downloads help on dependency-heavy projects.
Bottom line: for most teams it’s a non-issue, and the security/reliability gains are worth it. But if your build is already 20+ minutes, test first.
Breaking Changes – Yeah, There Are a Few
They ditched the ancient auto-injection of plexus-utils into plugins. If a plugin breaks, either the maintainer fixes it (most did) or you add the dep manually as a workaround.
No more creating your own RepositorySystem in mojos – reuse the one Maven gives you.
.mvn/maven.config now treats each line as one argument. Multi-word args? Split them across lines.
System and user properties got cleaned up – no more sneaky cross-setting.
Wagon transport is gone – you’re on native HTTP now (or configure alternatives).
Most projects upgraded without pain, but legacy plugins or weird configs bit a few teams.
Upgrade Advice – Just Do It, But Test
Get on Java 8+ (duh). Run your build with the latest 3.9.11 – it’s stable as hell by now.
Check for plugins missing plexus-utils and add it if needed. Update .mvn/maven.config formatting.
Turn on trusted checksums and repo filters in your settings.xml – you’ll sleep better.
Test large builds for that potential 10% hit and tweak resolver settings if necessary.
For 99% of teams, 3.9.x is a straight upgrade: safer dependencies, helpful warnings, and a cleaner experience. I haven’t looked back since switching.