Java equivalent of NPM?

OK, I’m late to experiencing NPM because of my aversion to Javascript. But I just tried it out (installed MailDev for dev part of handling the registration/email-activation of new users on a Spring Boot project) and the ease of using it makes me wonder why there isn’t something this easy for Java? Also, what would such a program look like?

I guess a big hurdle is that compilation of a Java program (e.g., into a self-contained runnable via JLINK) has to be done on the target OS. This isn’t currently a factor with Javascript.

Well, NPM basically handles two things:

  • reading the dependencies and devDependencies sections of a package.json file and the package-lock.json file to figure out which dependencies to download into ./node_modules when npm i/install or npm ci is called
  • being able to run cmd lines, declared under the scripts section of the package.json file with ./node_modules/.bin as part of PATH to lookup referenced binaries, with a few shortcuts, like npm start instead of npm run start for executing the scripts/start cmd line

There are of course dependency management and build systems for Java/JVM as well:

  • Maven: package.json is basically the pom.xml file
  • Gradle: package.json is a Groovy and Kotlin script: build.gradle
  • Ivy: the dependencies part of the package.json are custom xml tags usable inside an Apache Ant build.xml file

Maven, Gradle and Ivy make use of the Maven artifact repositores (i.e. Maven Central). Maven reads the dependencies and dependencyManagement sections of a pom.xml file, whereas Gradle uses a Groovy or Kotlin internal DSL/API to declare dependencies. Maven and Gradle dependency declarations are also more powerful than NPM’s (or rather the package.json format), where NPM/package.json only knows about DEV and non-DEV dependency scopes.

Also, Maven and Gradle are more comprehensive build systems, unlike NPM or Ivy (Ivy only being for dependency declaration and download in the context of an Apache ANT build file).

1 Like

Main thing I was thinking of was the difficulty in providing a jar and having someone be able to run it. This used to be a lot easier.

I’ve not seen Maven used except for compiling from source. Well, that, and I use it from within Eclipse.

Trying to think how, with Maven installed, one would give someone a jar or some such and instructions so they could compile and run the program. I think the instructions would be multistep, at the least. Maven is much more a dev tool than a means of distribution of executable programs. Maybe this is easier to do than I realize? Or you are mostly citing Maven as something that part way accomplishes the functions of NPM?

Maven and Gradle, at their cores, basically provide build “lifecycle” management, dependency management and a plugin system for plugins to inject their functionality.
I may also not be clear on what you think NPM actually accomplishes for you. It doesn’t give you an executable program of your JavaScript sources.
Or are you not talking about server-side JavaScript programs but client-side/browser websites?

Trying to think how, with Maven installed, one would give someone a jar or some such and instructions so they could compile and run the program.

What do you mean here? That doesn’t make much sense, because if you gave someone a jar, then the assumption is that this jar is executable (i.e. has a manifest entry of the main class to run) and already contains the compiled classes and resources needed. So, they’d merely have to execute java -jar the.jar given a Java runtime environment.

There are, of course, plugins for Maven and Gradle that provide you a very easy way to generate a single executable jar (including all their transitive dependencies).
Google for “Maven Shadow plugin” or “Gradle shade plugin”.

This will give you an executable jar file (if you specified the proper declarations of course, such as which is the main class to run its main method).

It’s the same story with NPM. npm gives you dependency management and the ability to run scripts.

And if you end here, you get the same out of NPM as you get with Maven and Gradle: With npm it’s a bunch of files for which you need an execution environment to run them.
With npm (or rather JavaScript) the execution environment would be Node (which you’d need to run npm in the first place).

Same goes for Maven/Gradle: You need a Java runtime environment to run those and likewise the executable jar they can produce of your application.

If you want to take it a step further and not rely on the end user having to have an execution environment (like Node/Deno or a JRE), then you need to bundle that as well.
For NPM/JavaScript with Node there is e.g. “nexe” which can bundle you your application with a Node runtime environment.

For Maven/Gradle the story is a bit more difficult, since you have things like classpath (pre-Java9) vs. modulepath. Basically, from here on it doesn’t matter anymore whether you use Maven/Gradle or not: You just need a way to turn an executable jar together with its runtime environment (JRE) into a native OS executable.

2 Likes

JPackage (use --main-jar if you really want to use a JAR instead of modules in input) and JNDT do it, you probably know the former.

I’d like to suggest using Maven as well cause you may treat NPM packages with its help. Webjars is one of the most widely used if we are talking about WAR/JAR. If needed you may refer to NPM API.