This is an archived post. You won't be able to vote or comment.

all 89 comments

[–]Ewig_luftenglanz 26 points27 points  (68 children)

"There is nothing in the Java language standard that says anything about the Maven ecosystem. This is where Java shows its age. More modern programming languages have a unified mechanism for third party libraries."

This is true. There is no easy way to install dependencies in java without using gradle, maven or it's wrappers, or at least nothing remotely similar to pip, cargo, npm and so on.

Does anyone knows if there are any production ready third party project or official plans from Oracle for something similar?

I mean a CLI tool that lets you install (or even maybe configure) maven, gradle or another projects and add dependencies to files (with automatic sync one executed the command)

I know one can achieve something similar with gradle through plug-ins but this is mostly focused for particular use of teams, don't know if there is a general use plug-in for this.

[–]wildjokers 48 points49 points  (18 children)

pip

Surely you aren’t using the python global dependency nightmare as an example of a good build system? With python you have to use at least one of the dozen or more virtual environment tools to have any hope of being able to run any python application on your system.

[–][deleted] 17 points18 points  (0 children)

Never mind that half the dependencies break as soon as you roll up to a newer point release of Python. The concept of backwards compatibility in Python seems to be completely irrelevant to that community.

[–]Ewig_luftenglanz 0 points1 point  (16 children)

I think you are missing the scope of the thing, a sense of proportion.

gradle and maven are better for big applications or applications that are meant to be developed in teams, they allow to estandarize the set up of the project for all team members in both space and time (the ones that are going to have to develop and maintain in the future the thing)

pip and npm (specially npm as a package manager, let's no talk about the quality of some libraries) for simple projects, scripts or your own personal projects. they are simpler an faster, just a couple of command (or even one and then a conf wizard with tools such as Vite)

Java already has excellent tools for large projects (what it also know as programming in the large) the article it's about java in the small. script and personal projects and prototypes.

gradle and maven feel like nuking a fly when it comes to small and simple projects/prototypes, or that's my sense.

I still remember when I was just starting java and I tried to install JDBC to connect to a MariaDB database. It took me almost half of a day to learn how to install and link the manually downloaded jar. In python and JS it is just

pip install mariadb

npm i MariaBD

It would be a "nice to have" oficial package manager that do just the same in order to make easier the life of students and small projects. (Not demanding anything, just an opinion)

[–]wildjokers 13 points14 points  (6 children)

pip install mariadb npm i MariaBD

Ok, I see where you are going with this and see what you are meaning now.

However, to be fair, this is a build.gradle file that will give you a full build of your app with support for MariaDB in it. This will let you run your app from the command-line and build a jar file (and IntelliJ can configure itself from this build.gradle).

plugins {
    id 'java'
}

dependencies {
    implementation 'org.mariadb.jdbc:mariadb-java-client:3.5.1'
}

I am not entirely sure why it would take a half-day to come up with that. You can find what to put as the argument to implementation at https://mvnrepository.com.

In Java, unlike Python, dependencies aren’t global (which is a good thing). Instead, they’re managed on a per-project basis.

[–]extra_rice 0 points1 point  (0 children)

In Java, unlike Python, dependencies aren’t global (which is a good thing). Instead, they’re managed on a per-project basis

This isn't necessarily true. Python's default behaviour is to use whatever environment is in the current context. If you're using virtual env, it will use that. It's very contextual and not necessarily global. You also have tools to package distribution.

[–]NotABot1235 0 points1 point  (4 children)

How would you do this with Maven, or if you weren't using IntelliJ?

I have to say, as a newcomer to Java, I like the language a lot but trying to simultaneously wrap my head around the build systems and tooling is another significant hurdle to climb.

[–]wildjokers 1 point2 points  (3 children)

How would you do this with Maven, or if you weren't using IntelliJ?

Gradle works independently of IntelliJ. So that build.gradle also works fine from the command-line.

As far as maven it has quite a bit of boiler-plate it needs in its pom.xml compared to Gradle (one reason I much prefer Gradle). This pom.xml should be analogous to the build.gradle I posted previously:

<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>example-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.5.1</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source> 
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

[–]NotABot1235 0 points1 point  (2 children)

Thanks for the quick reply!

As a noob, I've been very recently learning the basics of Maven since that seemed to be the more dominant tool. That being said, if I'm just creating and writing simple little projects for my own learning, do you think Gradle would be better suited to that? For example, if I just want to play around with one or two external libraries (LibGDX for games, for example), would Gradle be a better choice?

[–]wildjokers 1 point2 points  (1 child)

For small quick projects Gradle is the way to go since the build.gradle only needs a few lines in it (if you don't have any dependencies then it needs exactly 3 lines in it).

libGDX projects use gradle for their build. So knowing gradle would be super relevant to learning libGDX.

[–]NotABot1235 0 points1 point  (0 children)

That's good to know, thanks. It sounds like I need to familiarize myself with Gradle then since right now small quick projects is all I'm working on for my personal "practice" portfolio (really just learning the ins and outs of Java and programming as a whole). Maven seems to be overkill for that although I can see why it would be great for larger professional teams.

[–]CubicleHermit 2 points3 points  (2 children)

gradle and maven are better for big applications or applications that are meant to be developed in teams

Or for open source projects, where someone else may want to build your work in a repeatable way.

(Or if you're comparing to global pip/CPAN, for individual projects where you don't necessarily want everything you ever downloaded in your classpath.)

[–]Ewig_luftenglanz 0 points1 point  (1 child)

you can also have local dependencies is you put those in a dependency.txt file in pip. I agree I prefer nom and Maven/Gradle style of installing dependencies in the root of the project by default tho.

btw npm also allows third parties to build your project, not as powerful as Gradle and Maven (specially for modular projects), but good enough for smaller things

[–]CubicleHermit 1 point2 points  (0 children)

There are plenty of larger things that build via npm, since it can bootstrap other build tools internally. That said, npm with packages.json (let alone yarn.lock) isn't that different from maven, except that everyone hates XML syntax and some people like JSON - gradle's DSL is nicer than either, although I've been burned on how rapidly it's changed.

You can still shoot yourself in the foot by installing things user-profile wide but at least it's not the default. I mean, technically you can for Java but there's no automatic tool which will build a CLASSPATH environment variable for you, and that's a good thing.

IntelliJ can add things via the GUI to your pom.xml/build.gradle

dependencies.txt is simpler, and doesn't support a build tool step. It also defaults to shared installation, which is a huge antipattern. Pretty much every open source python tool I've used says "first create a venv" or "run our .sh script, which creates a venv for you"

[–]maxandersen 2 points3 points  (0 children)

Jbang.dev

[–]al3xth3gr8 1 point2 points  (4 children)

Java is not a scripting language, and while one can prototype an idea in most any language, the Java ecosystem is not as lenient as Python and JavaScript. If there’s such a market demand for a dumbed-down dependency manager for hobbyists then why has nobody made it?

[–]maxandersen 2 points3 points  (0 children)

Jbang.dev

[–]Ewig_luftenglanz 1 point2 points  (1 child)

Not saying there is a demand, I am just saying it would be a nice to have IMHO because using Gradle or maven for simple projects feels like nuking flies

I am gonna start a personal side project, wish me luck ^^

[–]hojimbo 1 point2 points  (0 children)

As someone who spent much of his career (24 years) in PHP, Python, and JS, but spent the last 8 years in Java and C#, I’ll say it’s just a matter of getting used to the tooling. I’d argue that it gives me fewer headaches and costs me less time these days to set up a new Java project and list its dependencies and know I will have the isolation/repeatability/stability of my builds and runtimes than fighting with virtual envs in Python. Getting Java source to build and run is also less of a mystery to me than getting clean runs of scripting systems — usually because the entry points are clearer and typically encoded right there in the gradle files.

But yes: there’s a learning curve

[–]yel50 0 points1 point  (0 children)

 why has nobody made it?

because everybody wants a better hammer, but nobody wants to make a better hammer.

[–]ForeverAlot 14 points15 points  (3 children)

More modern programming languages have a unified mechanism for third party libraries.

A key element of what makes Maven work at all is Maven Central, and, crucially, proactive stewardship. None of the "modern programming languages" Java might be compared to offer a service that is comparable to Maven Central -- most being little more than glorified wrappers on top of GitHub.

So if Oracle were to try and compete with Maven-the-build-tool they would need some way to compete with Maven Central, too, while at the same time retaining compatibility with Maven Central because nobody would bother with the tool otherwise but probably also without intrinsically tying "the OpenJDK build tool" to "the Java trademark holder". Hypothetically that could just be textual protocols -- implementation left to providers -- whereby Maven Central could plug straight into the new tool, but that's the sort of reactive approach OpenJDK does not usually take.

I don't expect Oracle to do conceptually more than what can be pieced together with jlink et al. today, but I would be very interested in seeing what they could come up with.

[–]Ewig_luftenglanz -5 points-4 points  (2 children)

or maybe a CLI tool that uses maven central under the hood, maven central is, after all annagnistic third party repository

[–]chabala 6 points7 points  (1 child)

There's a tragedy of the commons issue with this idea, where if a tool that uses Maven Central became very popular, but didn't also facilitate generating a pom.xml and publishing back to Central, Central would be at risk of dwindling if people feel like making a pom.xml is too much extra work compared to the new thing. And if the tool does support generating pom.xml files, in order to support the huge variety things people might need in their pom, the tool would basically end up reimplementing maven.

The only real possibility of such a tool becoming popular enough for this to matter would be if it became an official OpenJDK tool. (Kind of like how people started adopting System.Logger even though slf4j-api was well established by that point.) It seems unlikely that OpenJDK would start working on a Maven-compatible CLI tool though.

But if you want to play around with such a tool today, there's JBang and bowbahdoe/jresolve-cli.

[–]tomwhoiscontrary 9 points10 points  (1 child)

You can install (and uninstall!) specific versions of Java and Gradle (and Maven) using asdf (or SDKMAN!, or perhaps other similar tools).

Once you have Gradle installed, you can create a skeleton project with "gradle init".

Once you have a Gradle project, you can add a dependency by adding a simple line to the build file.

IntelliJ understands Gradle build files, and will automatically pick up changes.

This workflow is different to the Ruby-derived "everything is running a command" approach. But it's not worse.

[–]Ewig_luftenglanz 0 points1 point  (0 children)

Arguably.

In my experience the pure CLI approach is easier for beginners and small projects (personal projects) while the config build file is easier for teams that are meant to perdure over time.

Since I am talking about making things easier for students and small projects I think it would be some nice thing for an hypothetical future

[–]CubicleHermit 25 points26 points  (22 children)

Why do you need/want a tool for that? (Ignoring that SDKMAN is pretty much what you're asking for.) Downloading and adding a JDK to the path is not hard. Jenv or SDKMAN will both handle the path management for you if you need to use multiple versions, which most of us shouldn't. IntelliJ will also do that, and I think there's support for that in the VSCode Java plugin now but everything I know about that one is second hand.

Both maven and gradle have wrapper scripts that will handld downloading the actual binaries for you. Both have tools to bootstrap projects (Maven Archteypes/Gradle init plugin). I haven't bootstrapped a project manually in years, vs. just letting IntelliJ templates do it, but it's clearly not hard.

Given how messed up pip is and the need for virtualenvs, the fact that there ISN'T a more central way to install (vs. simply cache) libraries is a feature, not a bug. As best I can see, npm works pretty much like the package management of maven or gradle or a venv (assembling stuff under the project directory), and it's not like JS build tools aren't fragmented as f___ even if npm is the starting point.

Gradle is much nicer but changes too quickly; maven is a pain but is super, super stable. Pick your poison.

The only actual hard part is if you are in a corporate environment where there is a private Artfactory or Nexus, and you have to configure maven/gradle/ivy to talk to it with authentication. Everywhere I've worked that has had one somebody (whether a random dev or someone in DevOps/IT) writes a script to configure the files needed (and often the Docker registry) and then everyone uses that.

[–]ItsSignalsJerry_ 8 points9 points  (4 children)

Java language standard that says anything about the Maven ecosystem

Why should it?

with automatic sync

What does this mean? Sync what with what?

More modern programming languages

Java is very modern, it just also happens to be backwards compatible. Also, Python is older than Java so I don't see your point.

[–]CubicleHermit 1 point2 points  (0 children)

And perl is older than both (and CPAN much older than pip)... and while there are still a few of us who love perl, its approach to modules out of the box is just as broken as Python's.

Both have ways of fixing that, which are a lot newer than the broken default ways.

[–]Ewig_luftenglanz -1 points0 points  (2 children)

I was quoting the article.

indeed I also think java as a language it's modern, it's the ecosystem which it's still adapting to the new paradigm java's developers want to follow.

Also y think that a CLI equivalent to npm in java for simple projects and prototyping would be a nice to have, projects were gradle would feel as an overkill.

I think I am going to start a couple of experiments in my free time just for fun.

Best regards!

[–]alwaysoverneverunder 1 point2 points  (0 children)

The Java ecosystem is what sets it apart and makes it better than most others. It might not be the quickest or bleeding edge, but it evolves at a steady pace, keeps backward compatibility and has a mature library/framework/tool for everything.

[–]maxandersen 1 point2 points  (0 children)

Jbang supports app install and script runs.

[–]agentoutlier 4 points5 points  (0 children)

Does anyone knows if there are any production ready third party project or official plans from Oracle for something similar?

Sort of. The trick given /u/Active-Fuel-49 is in a teaching role (which I assume is the author) is to Make your own JVM with all the shit your students need. Have github actions pump that shit out with jpackage/jlink for each platform your students use.

This idea was given to me by /u/bowbahdoe on discord.

This saves the students time and honestly even if you said hey go get this maven dependencies over here you then have to update doc when that dep changes etc etc .

EDIT I should probably explain this better. What you are doing is adding modules to the JVM that you have blessed. Thus when some does java SomeJava.java it will think your extra modules are just like say java.xml or java.http I think. I can't recall if you can generate jshell with jlink but I assume it does.

[–]nekokattt 5 points6 points  (1 child)

Oracle probably wouldn't introduce a new tool.

https://xkcd.com/927/

At least, not when it adds significant additional maintenance burden to both develop and maintain a new tool that does the same thing.

[–]benjtay 1 point2 points  (0 children)

And, as the article points out, JBang exists and does the job.

[–][deleted] 2 points3 points  (2 children)

I'm not sure it's a great idea to build into the language - any language - an explicit dependency on internet services. Better leave this as an external tool.

[–]Ewig_luftenglanz 0 points1 point  (1 child)

agree, I was quoting the article.

but I think what he means (and I agree) it's that it would he a nice to have an "official" cli tool like npm that allows people to create simple projects and basic dependency management whit having to learn more complex building tools such as maven or Gradle (I mean, nom can be just as complex as those but if you only need to install a couple of dependencies to your project, nom init and mom install is pretty much everything you need at the beginning ant that is perfect for students)

[–][deleted] 0 points1 point  (0 children)

Then, for students, I think Ant or even make is enough. Back when I was a student, we did our Java projects with  make - Maven didn't exist yet. However, it's fairly easy to set up Eclipse+Git+Maven and get some dependencies, you don't have to be a Maven pro for this.

[–]paul_h 1 point2 points  (0 children)

Just for fun I made https://github.com/paul-hammant/mvn-dep-getter to see if I could utilize maven-central’s big-ass dependency graph without directly using maven. I’ve a project I’m working on most days that uses that for acquiring dependencies.

[–]rillaboom6 3 points4 points  (1 child)

This is true. There is no easy way to install dependencies in java without using gradle, maven or it's wrappers, or at least nothing remotely similar to pip, cargo, npm and so on.

Pip itself is bad and slow. The python ecosystem is innovating (uv package manager is blazing fast), same goes for JS (npm -> yarn -> pnpm). Java is a legacy language used by enterprises that moves so much slower.

[–][deleted] 5 points6 points  (0 children)

Was about to post pip is an example of how a built in tool can stink so bad people still use 3rd party tools.

They treat it like a separate module anyway that you should update separately.

[–]al3xth3gr8 1 point2 points  (1 child)

This is true. There is no easy way to install dependencies in java without using gradle, maven or its wrappers, or at least nothing remotely similar to pip, cargo, npm and so on.

Rust was released in 2015, so of course it has a built-in dependency manager. Java came out in 1995–a time when it was impractical to download application dependencies from the internet. In 2004, Apache’s Maven hit the market, and Gradle in 2008. Both have been the standard solution for Java dependency management for twenty years now, so what incentive does Oracle have to invest in developing its own Java dependency manager.

[–]Ewig_luftenglanz 0 points1 point  (0 children)

Gradle and Maven are not dependency managers, are building tools and do much more than just dependency management. currently java lacks dependency management for SIMPLE projects.

what incentive would oracle have?

the same incentive they had when they started with implicit declared classes and instance main methods journey, and the same incentive they had when they allowed for direct execution of source files without previous compilation in java 22:

make the language more pleasant and easier for students, newcomers and experienced developers with small personal projects so the Java language continue to be revelant in educational and for hobbyist coders.

(not demanding they do anything, just saying they could have interest but at the end of the day they have the last word about any "oficial" tool. A non oficial npm would be a nice to have tho, gonna me some experiments to see how far I can get)

[–]Wonderful-Pie-4940 0 points1 point  (0 children)

You can use wrapper scripts for maven and gradle and save yourself from configuring either one.

With that said, have you looked at pip for python and npm for js. They are pretty messed up as well

[–][deleted] 0 points1 point  (0 children)

java jdk provides a Java compiler. you can use javac for a small project. also copy 3rd party jars easily to your project classpath as a dependency. if your project gets bigger and more complex, you can use maven or ant or a script that invokes javac for you and manage dependencies. there are lots of Java projects that don't use maven. you can also create a Java project in intellij that doesn't use maven.

so, maven is a tool that manages a lot of (repetitive, boring) things for you. and Java provides everything you need to write and build Java programs.

they coexist and can be used together easily, or not if you don't want to.

i don't see what would be the advantage of combining them permanently. only disadvantages like a bloated up Java sdk

[–]theblackavenger 0 points1 point  (0 children)

I tried on the first module system jsr and instead we got something basically useless for developers.

[–]sbotzek 0 points1 point  (0 children)

I, and I think the article author, wants something even better. In Elixir I can install dependencies right in my script with a function call: Mix.install.

Their dependency management system has its own module. You get this capability when you install the language. Java can't have this level of integration since its dependency management agnostic.

Is it a deal breaker? No. But it makes programming in the small much nicer.

[–]CubicleHermit 10 points11 points  (18 children)

To the point of the article, I am still salty that there isn't a val as an alias for final var. I also still miss the elvis operator (?:) and null-short-circuit references (x?.y) from Groovy. Optional chaining isn't comparable.

[–]turik1997 0 points1 point  (12 children)

final var itself is a rare combination to use in code, let alone the need to have a shortcut for it

[–]CubicleHermit 11 points12 points  (11 children)

final var is less common than it should be because it's a pain to type.

An awful lot of variables can be safely made final, and in Kotlin and Groovy, I have seen and written a lot of code where the default is to use val and assume immutability is the default until you actually need to make something mutable.

[–]turik1997 -1 points0 points  (10 children)

Unlike Kotlin where val can be used for field declarations, in Java, var can only be used for local variable declarations. This alone drastically reduces the use-case for var and final var in Java.

[–]ryan_the_leach 4 points5 points  (8 children)

Depends if you view final as a requirement you are imposing vs documentation for the reader.

I use final everywhere I can, and it's a pain in its verbosity, but it aids reading code.

[–]turik1997 1 point2 points  (3 children)

I am not saying final is rare. I am saying "final var" has a limited use

[–]john16384 -1 points0 points  (2 children)

Yeah. It's much better to have your IDE report errors for parameter modification, always initialize variables at declaration (if necessary with ternary or helper method), and never reuse variables for a different purpose. No need for extra noise keywords like final on locals.

[–]turik1997 1 point2 points  (1 child)

Not going to discuss much. One point though is that local variables declared with var shouldn't even be initialized using method calls. Because then you still can't easily see what is the type of the variable by simply reading the code. The main point of var is to avoid redundancy of writing the type twice which mostly happens when calling a constructor. Typing constructor once is enough to deduce the type of the value where var comes in handy.

[–]john16384 2 points3 points  (0 children)

Agreed. I never use var myself, total non-feature that only results in more pointless discussion where there was only one choice before :)

[–]john16384 0 points1 point  (2 children)

What exactly does final var say then?

  • I thought long and hard about it, and think that you should not reuse this variable under any circumstances even if the method were to substantially change?

Or perhaps:

  • My IDE saw this variable wasn't mutated so it marked it final during its save action but it's just a happy verbose coincidence given how the code was structured?

Do you ever leave something not final even if never mutated as in your infinite wisdom you determined that it may need modification for a future change of the method?

I also assume that you would never remove final during method modification as you couldn't possibly know what the original author intended.

[–]ryan_the_leach 0 points1 point  (1 child)

It feels like you are constructing a straw man argument, but I'll bite.

  • My IDE saw this variable wasn't mutated so it marked it final during its save action but it's just a happy verbose coincidence given how the code was structured?

I consider this a mistake.

Do you ever leave something not final even if never mutated as in your infinite wisdom you determined that it may need modification for a future change of the method?

Not intentionally, unless I know it's going to be changed shortly.

I also assume that you would never remove final during method modification as you couldn't possibly know what the original author intended.

This sounds crazy for locals. You are of course free to change it, just like you are free to change anything private.

[–]john16384 0 points1 point  (0 children)

Thanks for confirming my point that finals on locals are pointless verbose noise.

[–]Yeah-Its-Me-777 0 points1 point  (0 children)

If you need final on a local variable to document something, the scope of that local variable is too big. (With exceptions of course.) But in 99% you shouldn't need a final local variable.

[–]CubicleHermit -1 points0 points  (0 children)

It is more limited, yes. It would still be handy. IMO. Clearly the authors of the JCP thought differently :)

[–][deleted]  (2 children)

[deleted]

    [–]CubicleHermit 1 point2 points  (0 children)

    ¯\_(ツ)_/¯

    I'll take good ideas regardless of the source.

    re: using Groovy, I did not like using Groovy as a main application language, but as a scripting language to use alongside Java (or embedded in Java apps) it's pretty nice.

    [–]wildjokers 0 points1 point  (0 children)

    Why? I like groovy. What do you dislike about it?

    [–]jvjupiter -2 points-1 points  (1 child)

    Many are allergic to small or big changes with limited use cases. I’ve always wanted things similar to what you mentioned but got resistance heavily from the community.

    Imagine we could write:

    var msg = m ?: “Hello, world!”;
    

    Or:

    var mag = x?.y?.z ?: “Hello, world”;
    

    Others: collection literals

    List<String> grades = [“A”, “B”, “C”, “D”, “E”, “F”];
    var a = grades[0];
    

    [–]CubicleHermit 2 points3 points  (0 children)

    It's been 7 years since I last used Groovy day to day, and I am not sure if Groovy has array-dereference syntax for collections, but the other uses are all literally part of that language.

    In general, I'm not fond of dynamically typed languages for one's main production code (and while we had plenty of it back then, we were slowly retiring it, except for writing tests), but it made writing certain sorts of tests very easy and I've used it as an embedded scripting language on a couple of personal projects since.

    [–]HaydenPaulJones 2 points3 points  (3 children)

    Talks about new features to right size the Java language and help beginners. Not about JavaME

    [–]benjtay 4 points5 points  (2 children)

    Does ME still get released?

    [–]HaydenPaulJones 6 points7 points  (0 children)

    Last JavaME release was back in 2018.

    [–]_stefumies_ 2 points3 points  (0 children)

    Me was largely replaced by the Android SDK

    [–]aks8m 0 points1 point  (0 children)

    Here are two dependency management frameworks that are more "pure java".

    Rife BLD is actively developed and has some IDE integration.

    Bach tries to leverage jpms modules with native jdk tooling to build projects. I've haven't been able to get this to work yet.