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.

I have a modular project, using Eclipse IDE. It requires a library that I wrote (which is also a modular project in Eclipse) and JavaFX. I can run the project from Eclipse, but so far have been unable to figure out how to create something that someone that I can ship someone who’s tech limit is installing Java and copy/pasting and running a cmd line like “java -jar myproject.jar”.

I’ve tried all the export executable jar options, but haven’t been able to figure out how to get them to run. I’ve had success with exporting runnable jars before, but only with a Maven project that used JavaFX and not another of my own libraries. I suppose as a next step I will try converting the project to a Maven project and bring in JavaFX, and see what happens.

For those of you who have figured this out, what was your process? Where you shown how by someone else? Were there particular documents that you found helpful?

Am really wishing we had some good tutorials on this subject here. Maybe I am overlooking them?

1 Like

If I understand your problem correctly there are multiple ways.
I just provide an run.sh/run.bat file with all the command line parameters.
There are also tools like:

Also check this thread: https://stackoverflow.com/questions/147181/how-can-i-convert-my-java-program-to-an-exe-file

2 Likes

Thanks for the reply. I am a bit flummoxed, though. Sure, it is possible to package a runnable, but these tools only work for creating images on the OS in which they are run. I’ve done this before, using JLINK and adding many manual steps, working from source code.

Is it no longer possible to just make a jar file that can run on multiple OS?

I have a project that uses JavaFX and another project that I created (pfaudio). I would like to make a jar file that can be run from the CLI. I would like to be able to give a friend the complicated command, presumably with module addresses for JavaFX and such, once I know where they installed JavaFX, that would run the project on their Mac or Windows PC.

I’ve gotten my project to compile and run as a modular project, but have been unable to figure out a way of creating a jar that can be run from the CLI.

As another attempt, trying to make use of Maven build tools, I’ve made a copy of the two projects, making both into Maven projects. I’ve set up the pfaudio project in the build configuration as a module dependency. But I can’t seem to even be able to get the run command to work–am getting a “module not found” error for pfaudio. I posted a question minutes ago about this on StackOverflow. Should I post the question here on jvm-gaming?

Am starting to feel stupid and discouraged. Am not giving up, though. It is too important to me to get this working.

EDIT: Found a good Maven video tutorial. In28Minutes. So far quite helpful.

EDIT 2: Success with both making an image via Maven goal “javafx:jlink” and with coming up with a workable syntax for a .jar file created via maven “install”. I’ll write this up and post it as a short tutorial as soon as I can make time, and will provide a link to it from here.

EDIT 3: I posted a tutorial, Making and Running a Jar, for a Modular JavaFX Project on creating a command line for running a modular JavaFX jar. Hopefully this will be helpful. As far as the issue of linking Java projects in a build, I decided to punt. For now, I’m going to copy/paste in the audio-library code that is needed for the project.

Javafx comes with its own packaging tool which provides a stand alone package for each o/s

Self-contained application packages are platform specific and can only be produced for the same system that you build on. If you want to deliver self-contained application packages on Windows, Linux and Mac you will have to build your project on all three platforms.

That’s because javafx is o/s specific binaries.

You could use open java fx and use their maven pom