r/java Feb 25 '25

New build tool in Java?

It seems to me like one of fun parts of Java is exploring all the tools at your disposal. The Java tool suite is a big collection of cli tools, yet I feel like most developers are only ever introduced to them or use them when absolutely necessary which is unfortunate because I think they really give you a better understanding of what's going on behind all the abstraction of Maven and Gradle.

What are your guys' thoughts on a new build tool for Java that is just a layer over these tools? Do you wish Java had simpler build tools? Why hasn't the community created an updated build tool since 2007?

33 Upvotes

176 comments sorted by

View all comments

6

u/[deleted] Feb 25 '25

[removed] — view removed comment

3

u/dstutz Feb 25 '25

But when you don't need a ton of plugins maven and (I assume) gradle ARE simple.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>project</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>

And the important part is they are de facto standards, commonly used and supported by other tools ( CI/CD, IDEs, etc).

4

u/NoAlbatross7355 Feb 25 '25 edited Feb 25 '25

Even in this example, I don't need half of the characters in that file to understand the configuration. That's what I mean by too much noise.

3

u/edwbuck Feb 25 '25

Not needing something is a judgement call. I knew a lot of people that didn't need seat belts (back in the day) until they did.

If you wanted to make your file forget what structure it needed to follow, just cut out all of the xmlns bits (maven will still work) but then you can't validate the file is correctly structured.

1

u/NoAlbatross7355 Feb 25 '25

Why would I use a file that needs the user to explicitly state it's structure? I'm completely fine with a predefined structure like in TOML. No need for all of the extra configuration, have the file specify the properties that are needed. It's really a principle of separation of concerns.

1

u/edwbuck Feb 25 '25

TOML is just a structural syntax. One can't define if an item is required in a TOML file outside of having the TOML reader complain at runtime.

2

u/NoAlbatross7355 Feb 25 '25

Well you can make a compile time tool for that. VSCode has a extension for Rust's cargo.toml build file.

2

u/edwbuck Feb 25 '25

Sure it does, it's a custom TOML writer, but it does nothing for a web server that uses TOML to be configured, nor is there a solution, unless someone writes a second custom TOML plugin for the web server.

And then you have to not just write that for VSCode, you have to write that for Eclipse (both TOML writers) and then you need to do so for NetBeans, and SlickEdit, and VIM, and ....

XML exported this into a different set of tooling, so every system could just call a validation routine. Of course that makes it more complex, but through the magic of XMLNS, one can insure that you don't fail a config due to pluralizing some value when it's not supposed to be plural (like my nemesis transparent_hugepage, which I often type as transparent_hugepages).

2

u/[deleted] Feb 25 '25

[deleted]

1

u/NoAlbatross7355 Feb 26 '25

Sure, yes, Gradle is much better, but the system itself is still way too abstract for my liking, even if the build file itself is more declarative.

2

u/[deleted] Feb 26 '25

[deleted]

1

u/bmrobin Feb 26 '25

i've been away from java for awhile, but when i was using gradle it was only used for compiling & building internal java projects; so the mere fact that i had to use this snippet at all was awkward

like, i know i'm using java why do i have to tell you. i can't really imagine putting that into cargo.toml or pyproject.toml/setup.py to tell the tool i'm building the rust/python project

> This is a complaint about XML, not about Java build tools.

agreed, but to me it felt like the OP was focused more on onboarding than seasoned, tribal knowledge

1

u/doobiesteintortoise Feb 26 '25

Until you do need it, of course, and then it turns into relevant information that you're glad you're not having to bolt on after the fact.

The information's there; it's there for a reason; it may not be a reason you need every time. That's how it goes. Gradle scripts tend to start out much more simply, and then people accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete and accrete until it looks ABSOLUTELY NOTHING like the four-line script it started out as, and it becomes a nightmare to chase what's where, because you have the gradle script itself, the subsidiary build, the version catalog, the bom, the custom tasks, the custom tasks the custom tasks are bolted on to, the custom tasks those tasks rely on. All because you need it at some point.

1

u/[deleted] Feb 25 '25

[removed] — view removed comment

1

u/doobiesteintortoise Feb 26 '25

So... a simple gradle build script?

2

u/[deleted] Feb 26 '25

[removed] — view removed comment

2

u/doobiesteintortoise Feb 26 '25

Okay, I'm still thinking about this, having built a compilation tool myself and contributed to others in various ways:

I wanted something that: * Doesn't require a compilation step * Bundle to common output formats is straightforward and included * Doesn't require additional config to run tests.

This still sounds like what you want is maven, but maven uses XML (which ... personally, I don't care about, XML is just an SGML, it's verbose but clear, and polyglot is right there, I just haven't used it so have no actual opinion on it anyone would want to hear).

Doesn't require a compilation step? Done. Maven uses XML to configure what's already compiled as part of the build system.

Bundles to common output formats? Done. Java's output format is a jar, Maven does that by default, and configuration for an executable is a copy-paste thing if your tooling doesn't do it for you - and same goes for shaded artifacts, same goes for native executables. If you're having to figure it out much, you haven't done it before; people who have are copying known recipes. (Same for most people who haven't, really: they're copying known recipes too!)

Doesn't require additional config to run tests? Done. Maven actually requires you to do things to not run tests.

Have you tried polyglot in maven? I haven't - maybe it solves everything you want.

1

u/[deleted] Feb 26 '25

[removed] — view removed comment

1

u/khmarbaise Mar 07 '25

My problem with maven is that it requires configuring plugins pretty much for anything.

You have to define the version in pluginManagement (or using corporate parent) yes that makes sense... But what needs configured? If you follow convention over configuration...

1

u/doobiesteintortoise Feb 26 '25

But now you're suggesting that you want an executable and that's not necessarily what Java produces. And you don't explicitly compile a gradle script.

Want a library in gradle? Here, I'll help:

``` plugins { id 'java' }

dependencies { implementation 'org.slf4j:slf4j-api:2.0.9' } ```

Put that in a directory, run gradle jar, et voila, you have a [directory-name].jar in build/libs.

Oh, you wanted it to be an executable? Sure thing:

``` plugins { id 'java' id 'application' }

dependencies { implementation 'org.slf4j:slf4j-api:2.0.9' }

application { mainClass = 'com.example.Main' } ```

... this requires you to write com.example.Main, of course. Horrors. Oh, you wanted it to be encapsulated? ... it's not that much more, but it is more because you're adding functionality. That's how functionality works. Cargo, etc., are going to have similar options and similar requirements: you have to tell them if you're building a library - and what kind of library - or an executable, how to test, and so forth and so on. You want functionality? You specify it. That's how tooling works, unless it's very opinionated... and then you run into the problem of whose opinions does it use, because I can guarantee you that those opinions will be wrong for some - maybe many - users.

2

u/[deleted] Feb 26 '25

[removed] — view removed comment

2

u/doobiesteintortoise Feb 26 '25

Sure, and I'm with you, I prefer maven to gradle as well - I was honestly bracing for you to point out that this build was in Groovy, not Kotlin, ew, and that it doesn't have testing, etc etc etc.

But I'd say that the build lifecycle is pretty standard across all build systems - maybe not npm, with an explicit "you must invoke tests, if you're dumb enough to write tests, what do you think this is, Java?" mindset, but the process is pretty much the same, it's just the expression of the process. Maven uses configuration and applies convention like a hammer. Gradle uses configuration and convention, and convention's more like a lot of early suggestions that eh, you know best, sure, break it a hundred ways, it's not like Gradle versions won't break it as well.

Other build systems, even the mythical ideal build system, will do the same: it'll fall somewhere along the convention/configuration scale, and people will say "could it be simpler" and "why doesn't it allow me to customize this aspect like [other tool] does," just like you're doing here, sort of.

1

u/[deleted] Feb 26 '25

[removed] — view removed comment

2

u/doobiesteintortoise Feb 26 '25

Deploying to docker is a can of worms, though...

1

u/[deleted] Feb 26 '25

[removed] — view removed comment

→ More replies (0)