Live data from Hacker News

Mill: A fast JVM build tool for Java and Scala

mill-build.org

21–30 of 168 posts

Re: Mill: A fast JVM build tool for Java and Scala

#21
post #4

What tends to be complex about build requirements that necessitates special purpose tools? Golang seems to be doing fine with just go build and go test. What else are people doing with gradle/maven that requires static typing, DAGs, plugins etc.?

Build tools sit in an unhappy corner of the design space where they provide features not found in the core of regular programming languages, and which are so generally useful that there's a temptation to make them very abstract, but then they often lack some of the features that let regular programs scale well.

The key feature that justifies their existence is parallel and incremental execution of DAGs of world-mutating tasks. This is an awkward fit with most programming languages, hence the prevalence of DSLs. But people don't want their build system to become a general purpose programming language, because they don't want to think about build systems at all and because programmers don't buy programming languages anymore, so, this causes a big design tension between generality (people want to use build systems to automate many things) and deliberately limiting the expressive power to try and constrain the design space and thus tooling investment required.

Java is in an awkward place because the JDK was born in the 90s on UNIX, by people who thought make is a sufficiently good solution. You still see remnants of this belief in the official Java tutorials, in JEPs, and in the fact that OpenJDK itself is compiled using an autotools based build system! (fortunately it's one of the nice make based build systems out there).

The problem with make is twofold:

1. It assumes a CLI that's both powerful and standardized provided by the host OS. Windows violates this assumption but Java is meant to be portable to Windows.

2. "Plugins" are CLI tools or scripts and so make implicitly assumes that subprocess creation is cheap. But process creation on Windows is expensive, and starting up JVM programs is also expensive due to the JIT compiling.

Therefore make just doesn't work well in the JVM ecosystem. At the same time, the Java project wasn't providing any competing solution, so the wider open source community was left to fill in the gaps. These days language developers provide build tooling out of the box as part of the base toolset along with the compiler, but Java still doesn't.

So - you ask, what are people doing with Gradle/Maven that requires all those features. The answer is: everything! Gradle builds frequently orchestrate dozens of different tools as part of a build pipeline, build documentation websites, do upload and deployment, download and manage dependencies, run security scanners and license compliance checkers, analyze dependency graphs, modify compiler behaviors, and so on.

Additionally Gradle isn't specific to Java, or even JVM apps. It can also be used to compile C/C++ programs, run native code compilers like Kotlin/Native, and it abstracts the underlying platform so Gradle builds aren't tied to UNIX.

That's why it's so complicated.

Re: Mill: A fast JVM build tool for Java and Scala

#22
post #15

Earlier quoted context omitted.

I'm working on a project that encompasses both JVM (Gradle, Kotlin) and Golang. My hot take: JVM build tools, especially Gradle, are a soup of unnecessary complexity, and people working in that ecosystem have Stockholm Syndrome. In Golang, I spend about 99% of my time dealing with code. In JVM land, I'm spending 30% just dealing with the build system. It's actually insane, and the community at large thinks this is no…

You speak from my soul! I'm in the Java world for a really long time now and I'm wondering for years why the build tools need to be so complicated an annoying. I know Go, Node.js and bit of Rust and all have more pleasant easier to use build tools! The JVM (or GraalVM) as an ecosystem is just fine and probably one of the best, but build tools might be achille's heel. Maybe it would be a good idea for Oracle to invest…

My experience of JS projects is that build tools are frequently ad-hoc. That is, there simply isn't a general build tool at all, but just a large pile of scripts calling under-documented libraries. Parallelization, caching and quite often even portability are just missing.

To justify this statement consider this blog post I wrote a while ago about porting GitHub Desktop (an Electron app) from its prior build/deployment system to Conveyor [1]. Conveyor is a tool for shipping desktop apps and is implemented as a single-purpose build system. The relevant part is this commit:

https://github.com/hydraulic-software/github-desktop/commit/...

The amount of code that can be deleted is huge! Some of it is in-process code that isn't needed with Conveyor (setting up Squirrel etc), but a lot is just shell scripts that happen to be written in JS. Replacing that with a real build system not only simplifies the codebase but means the build steps are fully parallelized, fully incremental, easier to debug, portable (the build can run on any platform), progress is reported in a uniform way and so on.

So whilst the JS ecosystem's approach to build tools may be "simple" in some way, in the sense that there's no dominant build tool like Maven or Gradle, that simplicity does cost you in other ways.

[1] https://hydraulic.dev/blog/8-packaging-electron-apps.html (Disclosure: Conveyor is a commercial product made by my company)

Re: Mill: A fast JVM build tool for Java and Scala

#23

Earlier quoted context omitted.

> the community at large thinks this is normal Half are ignorant. Other half are like me and just stuck with no options. But the tooling ecosystem on the JVM truly is horrific.

I think there are a lot of "JVM Lifers" who are so deep in the ecosystem they are unaware how much better things can be. Anecdote: I wanted to publish a ~100LoC multiplatform Kotlin library -- just some bindings. I publish these sorts of things for Go with just a "git push". Steps were: 1. Spend a few hours trying to understand Maven Central/Sonotype, register and get "verified". They're in the middle of some kind of…

Although a lot of it is generic badness, Kotlin Multiplatform isn't the JVM ecosystem. You don't need CI runners to publish a JVM library. The reason it comes up with Multiplatform is because Kotlin defines "Multiplatform" to mean platforms like JavaScript, or their own LLVM based compiler toolchain that bypasses JVMs entirely.

Re: Mill: A fast JVM build tool for Java and Scala

#24
post #13

The comparision with Gradle is not up to date. There is stated that you would end up in an untyped mess of Groovy build files, but statically typed Kotlin files are the default for quite some time now in Gradle! https://mill-build.org/mill/0.12.1/comparisons/gradle.html

Author here. Unfortunately this is because my own experience with Gradle is not up to date; I've only lived in the Gradle Groovy world! If anyone is interested in helping out, I have a 1500USD bounty on porting a gradle.kts build to Mill, so we can do a fair up-to-date comparison https://github.com/com-lihaoyi/mill/issues/3670

Re: Mill: A fast JVM build tool for Java and Scala

#25
Author here! Hope you take a look at the project and find it cool. There's a lot of interesting stuff here. In particular, the Video linked on the landing page is a great intros from a Java developer point of view, and the following video is a great intro from a Build Tool Architect point of view:

* https://www.youtube.com/watch?v=UsXgCeU-ovI

While Mill is focusing on JVM for now, it is very extensible and I have a strawman demo of adding a Javascript toolchain in ~100 lines of code https://mill-build.org/mill/0.12.1/extending/new-language.ht...

For those of you who want to learn more about the design principles and architecture of Mill, and what makes it unique, you should check out the page on Design Principles which has links to videos and blog posts where I elaborate on what exactly makes Mill so different from Maven, Gradle, SBT, Bazel, and so on:

* Mill Design Principles https://mill-build.org/mill/0.12.1/depth/design-principles.h...

I've mentioned this in a few places, but the comparisons with other build tools are best-effort. I have no doubt they can be made more accurate, and welcome feedback so I can go back and refine them. Please take them with a grain of salt

I'm also trying to get the community involved, so it's not just me writing code and running the show. To that end, I have set up a bounty program, so pay out significant sums of money (500-2000USD a piece) for people who make non-trivial contributions. It's already paid out about 10kUSD and has another 20kUSD on the table, so if anyone wants to get involved and make a little cash, feel free to take a shot at one of the bounties! https://github.com/orgs/com-lihaoyi/discussions/6

Re: Mill: A fast JVM build tool for Java and Scala

#26
post #19

Why not compare it to bazel/pants/buck2 as well? Mill seems to have taken some inspiration from those as well.

Author here. It does! I started working on Mill when I started learning Bazel, during my first months at Databricks. There's a lot of cross-pollination of ideas there, from my 7 years adopting and maintaining the Bazel build at Databricks, but I haven't had time to do a proper head-to-head comparison. Hopefully someone else can though!

Re: Mill: A fast JVM build tool for Java and Scala

#27

It's not clear to me how this is better than Gradle. And I hate Gradle. At first glance, Mill looks like it has many of the pitfalls of Gradle: - Plugins: Creates the temptation to rely on plugins for everything, and suddenly you're in plugin dependency hell with no idea how anything actually works. - Build scripts written in a DSL on top of a new language: Now I have to learn Scala and your DSL. I don't want to do e…

There is basically no DSL. You simply write what a build needs, e.g. you write a function `collectCFiles()` that collects every file with extension `.c`. You then issue a command like `gcc ${collectCFiles()}`. And pretty much that’s it - you can use shell commands, or do anything in scala (or java or whathaveyou). You simply have your functions return either a value (e.g. a checksum) or a location, which is the only mill-specific logic. So your compileC() function will simply invoke your collectCFiles() function, and this invocation implicitly creates a dependency between these tasks. You have written literally the simplest way to describe your build logic. But in the background mill will cache your functions’ inputs outputs and parallelize those that need re-run, which is what a build tool should do.

The implementation may not be the theoretical best, but I think the idea is pretty much the perfect build system out there.

Re: Mill: A fast JVM build tool for Java and Scala

#28

Earlier quoted context omitted.

I'm working on a project that encompasses both JVM (Gradle, Kotlin) and Golang. My hot take: JVM build tools, especially Gradle, are a soup of unnecessary complexity, and people working in that ecosystem have Stockholm Syndrome. In Golang, I spend about 99% of my time dealing with code. In JVM land, I'm spending 30% just dealing with the build system. It's actually insane, and the community at large thinks this is no…

One note from having worked with both that I don’t see mentioned: Golang dependencies are sources you basically pull and compile with your own code. In JVM-land dependencies are precompliled packages (jars). This adds one little step.

...or a big step, if cross-compiling is required (e.g. Kotlin Multiplatform)

I'm surprised there is no source-only dependency solution for JVM -- it'd solve this issue. Pull down the source and build on the fly. Perhaps there is and I'm unaware?

Re: Mill: A fast JVM build tool for Java and Scala

#29
post #12

Earlier quoted context omitted.

The first advantage the homepage lists is: > Mill can build the same Java codebase 5-10x faster than Maven, or 2-4x faster than Gradle Speed per se can be a good selling point (having to wait for slow builds is really annoying). I can't really comment on anything else though as I just stumbled upon it here in HN ;)

The goal should be more like 50x faster than Gradle. Gradle is ludicrously slow (at least in every single Gradle project I’ve had to work with).

First invocation may be. Subsequent builds are very fast, unless someone decided to write random bullshit into the build scripts that execute at config time, making the config process impure.

Re: Mill: A fast JVM build tool for Java and Scala

#30
post #4

What tends to be complex about build requirements that necessitates special purpose tools? Golang seems to be doing fine with just go build and go test. What else are people doing with gradle/maven that requires static typing, DAGs, plugins etc.?

Author here!

`go build` and `go test` do work, at limited scale and complexity. In Scala there's Scala-CLI which is excellent. If they work for you, you probably aren't the target market for these build tools. Once you start layering on bash scripts, layering on make, layering on Python scripts, layering on manual steps written down in a readme.md somewhere, that's the time when you should consider a proper build tool. And if that has never happened to you in your career, count your blessings :)

Why not just write some boring, pure code to handle the build? Why not write my build system in vanilla LYAH Haskell? It turns out that builds do have some specific requirements that most programs do not need to care about: caching, parallelization, introspection, and so on. Check out the following blog/talk for more details:

* Blog Post: Build Tools as Pure Functional Programs https://www.lihaoyi.com/post/BuildToolsasPureFunctionalProgr...

* Video: Mill: a Build Tool based on Pure Functional Programming https://www.youtube.com/watch?v=j6uThGxx-18&list=PLBqWQH1Miw...

Thus "naively" building your project "directly with code" ends up not working, so you do need some additional support. While most build tools end up constructing a complete bespoke programming environment from scratch, Mill tries to leverage the Scala language and JVM as much as possible, so you can re-use all your expertise and tooling (e.g. IntelliJ, VSCode, Maven Central, etc.) almost verbatim while getting all the necessary build-tool stuff (parallelism, caching, introspection) for free. Check out those two links if you want to learn more!

Post reply on HN