> Java will never become a player in CLI tooling until build packaging becomes first class.

Python packaging has always been painful and it’s a popular option for CLI regardless.

I don’t think there only rational explanations, technology choices are a lot about culture and dogmas too.

I think the python counterexample speaks a lot. A lot of languages "hide" their footprint in /usr/local or in a venv somewhere; out of sight, out of mind.

The JVM installs cleanly and is self contained, but any artifacts, by default, are not shared system wide as this _always_ have been seen as a security risk. The hot term for it today is "supply chain attack".

Instead, most Java programs tow their dependencies, giving it a bloated feel because its all just there, present in front of you, stored and running as your own user.

I know Python has been big in the space for longer than uv's existence, but uv (https://docs.astral.sh/uv/) has made Python packaging dead simple to me

I don't think uv makes distribution simple? Unless I've missed something, it doesn't do anything out of the box to help you produce a standalone artifact - it builds wheels but those are only useful for a user that already has python and pip, and don't do anything to deal with Python version drift etc.

uv can install a version of python of your choosing in addition to pulling the specific versions of libraries specified in your lockfile. it's extremely dummy-resistant.

Right, but that means the end user has to have (or install) uv, and then you ship them all your code, and then they can use uv to run that. That's a development workflow - and exactly what I meant when I said that uv didn't solve distribution in the way a language like Go or Rust does by producing a single binary.

uv does not solve all problems - but it for sure greatly improves chance of python tools working.

jbang is to java, what uv(x) is to python and what npm/npmx is to javascript.

Python packaging isn't really any more difficult than Rust, C# or Go if you use pyinstaller [1]

A single executable is always just one "pyinstaller --onefile --noconsole main.py" away.

[1] https://pyinstaller.org/en/stable/usage.html