Maven was the next generation build tool that was created to address a lot of the problems that tools like Ant had. It instituted a few rules and concepts that helped make projects more organized and uniform:

  • By default, projects have a strict structure - java code files go under src/main/java, resource files gounder src/main/resources, and the equivalent test java files and resources go under src/test/java and src/test/resources. This makes it easy to bootstrap a build file because it is clear where the source files are.
  • Project code is built into a maven package that has a package group id, artifact id, and version. These packages can be installed in Maven repositories, and this makes it easy to reuse the packages because you only needed the group id, artifact id, and version to pull the appropriate package.
  • Maven builds go through a series of phases that are standard for all builds. You can customize what happens in each phase with plugins (and you can even write your own plugins), and some phases may not do anything, but understanding the phases makes it easy to understand what order things happen in.
  • Maven introduced the concept of goals to specify what the objective of the build is. Normally the goal is either to compile, test, package, or install, but other goals can be specified as well. These goals can determine how far through the build process Maven will go before stopping. For example, running a mvn compile command will only go as far as compiing the code and not do any testing or packaging.
  • Maven added profiles which allows developers to define different build processes as necessary. For example, you might want to build in additional code for testing purposes in lower environments but then leave out that code in production environments.

There were some additional features that really helped developers when they ran into problems:

  • You can get a dump of the dependency tree, which allows you to see all the Maven packages that will be included in the project. One major problem that developers often run into is conflicting versions of libraries, and looking at the dependency tree can help pinpoint the source of the conflict.
  • Maven has the ability to generate build files and even source code based on archetypes. These are templates that include a lot of the boilerplate code that you need to get a project to the state where you can start working on business logic. Leveraging these templates can make projects more uniform and easier to start.
  • Maven projects can be nested or inherit from other Maven projects, which makes it so that you can define common dependencies and build configurations in one place and then just add specific dependencies or configurations for individual modules. This makes it easier to add new modules to an existing project or base a new project off an existing project.

I'm less familiar with Gradle, so I can't speak to that, but my understanding is that it builds upon the things that Maven does and takes it further. The point, however, is that build tools like Maven and Gradle have set stricter standards on how code is built so that developers can easily pick up code from any project, know how it is structured, and easily modify it to their needs. These tools also empower developer communities to share libraries. A lot of other languages like Python and NodeJS have similar tools that use standard project structures for the same purpose. If you aren't using one of these tools, there is a good chance you are spending valuable time managing your build process instead of writing code.