125

As I have worked with npm which looks for dependencies in package.json file and download it for you. Similarly, I see a pom.xml file in Java project. Does maven looks in this file and download dependencies for me. Can I pass around this pom.xml file like package.json, rather than giving the dependency jars ? Are these tools similar and just build for different platforms ?

Shubham Jain
  • 1,864
  • 2
  • 14
  • 24

4 Answers4

179

Same tool, different language?

Maven is the most popular build and dependency resolution tool for Java, just like NPM is for JS. But it's not just the same tool for a different language. There are obviously huge differences between Java and JS builds, and these differences are directly visible in the way Maven operates. For example, while many JS tools rely on Git to do some heavy-lifting, Maven works with custom filesystem-based Maven repositories, as Maven predates Git and needs to handle binary artifacts, which Git historically didn't handle well. In Maven there's a clear separation between sources and binaries, while they are often the same thing in JS world.

Maven basics

Maven in its purest form follows a declarative model, where pom.xml (similar to package.json) defines different properties of the build, but contains no scripts. The disadvantage is it can be a challenge to fine-tune some aspects of the build without using scripts as you have to rely on plugins. The advantage is it can be easier to understand other builds just by looking at pom.xml, as they usually follow the same approach without too much customization. Gradle is a popular Groovy-based tool built on top of Maven standards and conventions, and is specifically designed to simplify pom.xml and break this "no script" barrier.

Referencing your dependencies

Similarly to package.json, you don't work with pom.xml of your dependency directly, but rather define dependency coordinates and let your build tool handle the rest. In Maven the basic form of these coordinates is GAV (groupId, artifactId, version).

Flat dependency tree?

Based on comments in the other answer, Maven provides "flat dependency tree", not "nested dependency tree" that NPM provides by default. Maven does not allow multiple versions of the same dependency. If it happens that different versions are requested, Maven uses dependency resolution to pick a single version. This means that sometimes your transitive dependencies will get a different version than they require, but there are ways to manage this. However, this limitation comes from Java, not Maven, as (normally) in Java a class loader will only provide access to a single class definition even if multiple definitions are found on the classpath. Since Java is not particularly good at handling this, Maven tries to avoid this scenario in the first place.

Note: since npm v3 the dependencies are flatten. The alternative package manager yarn also does the same.

Maturity

Furthermore, Maven is considerably older than NPM, has a larger user base, huge number of custom plugins, and so far could probably be considered more mature overall. Sometimes Maven is used for non-Java or even polyglot projects, as there are plugins for handling other languages or specific environments, such as Android. There are plugins that bridge Maven and other build tools, such as frontend-maven-plugin that actually handles multiple JS build tools.

aymericbeaumet
  • 6,853
  • 2
  • 37
  • 50
Anton Koscejev
  • 4,603
  • 1
  • 21
  • 26
  • 4
    In addition to the information above, the following [Youtube Playlist](https://www.youtube.com/watch?v=al7bRZzz4oU&list=PL92E89440B7BFD0F6) does a great job describing Maven's use as a package manager – Tommy Thompson May 12 '17 at 03:59
  • 2
    I often visit npmjs.com to search for a package that might be helpful. It took quite a bit of googling to find a link for doing this on Maven (https://search.maven.org). However, searches don't point me to docs, don't show me popularity metrics, don't point to github. I don't find it helpful, suggesting that this is something people expect of NPM but not of Maven. – Joe Lapp Nov 07 '17 at 14:38
  • A pretty good statistical comparison between NPM & Maven is here: https://stackshare.io/stackups/npm-vs-gradle – Clifford Fajardo Jan 28 '18 at 21:59
  • 5
    An update to this answer: "Furthermore, Maven is considerably older than NPM, has a larger user base..." This was probably true when the question was originally answered in 2017, but is no longer accurate. According to the link posted by @cacoder, NPM's user base is now about 11x larger than that of Maven. Source: https://stackshare.io/stackups/gradle-vs-maven-vs-npm – mnutsch Mar 26 '19 at 18:30
  • How does one get started creating a project with Maven though? This answer is thorough but it sounds like it's describing a situation where there's a `pom.xml` file already. But what about if you want to create a new project? In Node.js, I'd do `mkdir ; cd ; npm init -f`. The `npm` tool, out of the box, can create a new project, and I'm not required to choose an archtype to start from. – Matt Welke May 02 '21 at 02:29
  • Maven's site says "Calling archetype:generate the plugin will first ask to choose the archetype from the internal catalog", but when I run `mvn archtype:generate`, I don't get a prompt. I get an error: `No plugin found for prefix 'archtype' in the current project`. This is confusing because I don't have a project yet. I'm trying to use Maven to make the project in the first place. – Matt Welke May 02 '21 at 02:29
  • Found my typo. If I type `mvn archetype:generate`, it works, and it displays a few thousand archetypes for me to choose from. The Maven docs (https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) include an example where they pick an archetype called "maven-archetype-quickstart" so I could try to just remember that. The syntax is a bit hard to remember though, having to run `mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false` instead of `npm init`'. – Matt Welke May 02 '21 at 02:43
58

Below I provide the common features and differences. I use | to separate between maven | npm terms respectively:

Common features:

  • Both tools support dynamic fetch of dependencies ( artifacts | packages ) based on a descriptor file pom.xml|package.json, and also allow you to deploy | publish your own artifacts | packages.

  • They both have a default public repository | registry ( http://repo.maven.apache.org/maven2/ | https://registry.npmjs.org), but 3rd-party can also be used (via settings.xml|.npmrc ).

  • They both support the concept of build-level dependencies (plugins | devDependencies used in scripts). *Maven supports provided dependencies also but this does not seem to apply to npm, since javascript is rarely deployed into containers.

  • They both support dependency namespacing: groupId|scope

Differrences:

  • maven has an additional local repository(cache):

    • No need to fetch again the same dependency for differrent projects.
    • Artifacts that are installed locally, are automatically accessible by other local projects.
  • dependencies from a project build in maven are downloaded in <homedir>/.m2. With npm they are downloaded in <projectdir>/node_modules.

  • Building in maven is commonly a one-step process: mvn package (fetch deps , build). In npm it is a 2-step process: npm install (fetch deps) , npm build (build)

  • maven defines build lifecycles (for building,testing,deploying) consisted of phases, to which default operations(plugin goals) attach, based on differrent packaging options(.jar,.war,.ear e.t.c). You can then overwrite these operations, or inject new ones (via the plugin system). This provides kind of an out-of-the box solution for build,docgen,test,deploy e.t.c.
    npm approach is more simplistic ( see: scripts)

  • Due to the above, npm is labeled as a package-management tool for javascript while maven is labeled as a build-automation and dependency-management tool for java.

  • In maven setting-up the build process more commonly involves editing the pom.xml.
    In npm it involves writing code or configuring complementary build tools like gulp,webpack e.t.c

  • For some reason version ranges defined by users in npm modules, are much more loose than in maven. This can cause issues with transitive dependencies, that is why an additional file was recently added: package-lock.json

  • With npm it is much more straightforward to start a new project: npm init. With maven, you need to know how to write a minimal pom.xml, or read about archetypes.

  • In general it is much more common to edit pom.xml than package.json. E.g. adding dependencies in maven is done manually (or via IDE) while in npm via command line.

  • As with all build tools, you can call one tool from inside the other, but I think its much more common to call npm from inside maven, than the opposite.

  • npm supports dev,production builds. In maven this needs to be defined through profiles.

Marinos An
  • 9,481
  • 6
  • 63
  • 96
  • I am a Java developer who recently started working in some Angular projects. You mentioned one of the differences between mvn and npm is that mvn supports "Artifacts that are installed locally, are automatically accessible by other local projects." Is there any way to accomplish this with npm in a convenient way? It seems like I typically have to build a sub component and manually copy it over to the consuming applications node_modules or release to npm before I can use it. – decal Feb 02 '23 at 20:42
6

yes. it's a similar packaging tool for java. look for gradle also which gives you more liberty with groovy language, but for start you can use maven to organize your dependencies. you include them as tags there and maven does the job for you.

it traverses the dependency tree and downloads all the appropriate jars.

Apostolos
  • 10,033
  • 5
  • 24
  • 39
  • 1
    not sure because i'm not so familiar with all these js tools. `gradle` is `maven + ant` together let's say. it does what maven does but it gives you also the freedom to write code and scripts apart from all the de-facto jobs that it does. i had a look at `gulp` just now. maybe it's the same, from what i read. if you want to start using maven vs gradle, i'd suggest starting with `maven` which is more clear and easier to understand and then mess up with `gradle`! – Apostolos Jul 15 '16 at 06:20
  • Thanks. Does maven have flat dependency tree or nested dependency tree ? – Shubham Jain Jul 15 '16 at 06:21
  • didnt understand what you mean. do you mean about the issue npm had with dependencies stored in sub-node_modules directories and having file path problems with over 256 characters, which was fixed in npm 3? maven stores all the jars in a repo and each jar is stored in its package. – Apostolos Jul 15 '16 at 06:26
  • http://stackoverflow.com/questions/18641899/what-is-the-difference-between-bower-and-npm. npm has nested dependency tree, that means all versions of a single module required by different modules is downloaded. Flat dependency tree doesn't allows that ! – Shubham Jain Jul 15 '16 at 06:27
  • 1
    e.g. see here https://mvnrepository.com/artifact/org.hibernate/hibernate-core/5.2.1.Final. hibernate depends on various other libraries, but these jars wont be stored in local maven repo inside hibernate library but in their own packages. – Apostolos Jul 15 '16 at 06:27
  • 1
    I think there is a difference in the handling of nested (transitive) dependencies. every node module can contain its own version of a dependency while maven will try to resolve to a single common dependency if several dependencies require the same third dependency but in a different version. I also would say grunt matches gradle since its task based. gradle is more of ant+ivy while maven is strongly convention driven. maybe closer to webpack but nothing too similar. – wemu Jul 15 '16 at 06:48
  • @wemu if you have 2 different versions of a library inside a pom.xml war, it will include them both, but that's sth you have to take care because it will end up in some incosistency probably. – Apostolos Jul 15 '16 at 06:53
  • 1
    sorry, you are correct. confused it with the profile building procedure that i sometimes use and define the versions. – Apostolos Jul 15 '16 at 09:51
1

Yes, same with gradle, but they are not user friendly as npm.

LEMUEL ADANE
  • 8,336
  • 16
  • 58
  • 72