Might be worth noting that npm didn’t have lock files for quite a long time, which is the era during which I formed my mental model of npm hell. The popularity of yarn (again importing bundled/cargo-isms) seems like maybe the main reason npm isn’t as bad as it used to be.
npm has evolved, slowly, but evolved, thanks to yarn and pnpm.
It even has some (I feel somewhat rudimentary) support for workspaces and isolated installs (what pnpm does)
Lock files are only needed because of version ranging.
Maven worked fine without semantic versioning and lock files.
Edit: Changed "semantic versioning" to "version ranging"
> Maven worked fine without semantic versioning and lock files.
No, it actually has the exact same problem. You add a dependency, and that dependency specifies a sub-dependency against, say, version `[1.0,)`. Now you install your dependencies on a new machine and nothing works. Why? Because the sub-dependency released version 2.0 that's incompatible with the dependency you're directly referencing. Nobody likes helping to onboard the new guy when he goes to install dependencies on his laptop and stuff just doesn't work because the versions of sub-dependencies are silently different. Lock files completely avoid this.
It is possible to set version ranges but it is hard to see this in real world. Everyone is using pinned dependencies.
Version ranges are really bad idea which we can see in NPM.
My apologies I should have said "version ranging" instead of "semantic versioning".
Before version ranging, maven dependency resolution was deterministic.
Always using exact versions avoids this (your pom.xml essentially is the lock file), but it effectively meant you could never upgrade anything unless every dependency and transitive dependency also supported the new version. That could mean upgrading dozens of things for a critical patch. And it's surely one of the reasons log4j was so painful to get past.
I’ve been out of the Java ecosystem for a while, so I wasn’t involved in patching anything for log4j, but I don’t see why it would be difficult for the majority of projects.
Should just be a version bump in one place.
In the general case Java and maven doesn’t support multiple versions of the same library being loaded at once(not without tricks at least, custom class loaders or shaded deps), so it shouldn’t matter what transitive dependencies depend on.
Right, that's the program. Let's say I really on 1.0.1. I want to upgrade to 1.0.2. Everything that also relies on 1.0.1 also needs to be upgraded.
It effectively means I can only have versions of dependencies that rely on the exact version that I'm updating to. Have a dependency still on 1.0.1 with no upgrade available? You're stuck.
Even worse, let's say you depends on A which depends on B, and B has an update to 1.0.2, if A doesn't support the new version of B, you're equally stuck.
Maven also has some terrible design where it will allow incompatible transitive dependencies to be used, one overwriting the other based on “nearest wins” rather than returning an error.
there are a small number of culprits from logging libraries to guava, netty that can cause these issues. For these you can use the Shade plugin https://maven.apache.org/plugins/maven-shade-plugin/
If in some supply chain attack someone switches out a version's code under your seating apparatus, then good look without lock files. I for one prefer being notified about checksums of things suddenly changing.
Maven releases are immutable
Sounds like the Common Lisp approach, where there are editions or what they call them and those are sets of dependencies at specific versions.
But the problem with that is, when you need another version of a library, that is not in that edition. For example when a backdoor or CVE gets discovered, that you have to fix asap, you might not want to wait for the next Maven release. Furthermore, Maven is Java ecosystem stuff, where things tend to move quite slowly (enterprisey) and comes with its own set of issues.