Tutorial Apache Maven

1. Perkenalan

Membangun proyek perangkat lunak biasanya terdiri dari tugas-tugas seperti mengunduh dependensi, meletakkan jar tambahan pada jalur kelas, mengompilasi kode sumber ke dalam kode biner, menjalankan pengujian, mengemas kode yang dikompilasi ke dalam artefak yang dapat diterapkan seperti file JAR, WAR, dan ZIP, dan menerapkan artefak ini ke server aplikasi atau repositori.

Apache Maven mengotomatiskan tugas-tugas ini, meminimalkan risiko kesalahan manusia saat membangun perangkat lunak secara manual dan memisahkan pekerjaan kompilasi dan pengemasan kode kami dari pekerjaan konstruksi kode.

Dalam tutorial ini, kita akan menjelajahi alat yang ampuh ini untuk mendeskripsikan, membangun, dan mengelola proyek perangkat lunak Java menggunakan bagian utama informasi - Model Objek Proyek (POM) - yang ditulis dalam XML.

2. Mengapa Menggunakan Maven?

Fitur utama Maven adalah:

  • penyiapan proyek sederhana yang mengikuti praktik terbaik: Maven mencoba menghindari konfigurasi sebanyak mungkin, dengan menyediakan templat proyek (bernama arketipe )
  • manajemen ketergantungan: ini termasuk pembaruan otomatis, mengunduh dan memvalidasi kompatibilitas, serta melaporkan penutupan ketergantungan (dikenal juga sebagai ketergantungan transitif)
  • isolasi antara dependensi project dan plugin: dengan Maven, dependensi project diambil dari repositori dependensi sementara dependensi plugin apa pun diambil dari repositori plugin, menghasilkan konflik yang lebih sedikit saat plugin mulai mendownload dependensi tambahan
  • sistem repositori pusat: dependensi proyek dapat dimuat dari sistem file lokal atau repositori publik, seperti Maven Central
Untuk mempelajari cara menginstal Maven di sistem Anda, silakan lihat tutorial ini di Baeldung.

3. Model Objek Proyek

Konfigurasi proyek Maven dilakukan melalui Project Object Model (POM) , diwakili oleh file pom.xml . The POM menjelaskan proyek, mengelola dependensi, dan mengkonfigurasi plugin untuk membangun perangkat lunak.

The POM juga mendefinisikan hubungan antara modul proyek multi-modul. Mari kita lihat struktur dasar file POM :

 4.0.0 org.baeldung org.baeldung jar 1.0-SNAPSHOT org.baeldung //maven.apache.org   junit junit 4.12 test      //...    

Mari kita lihat lebih dekat konstruksi ini.

3.1. Pengidentifikasi Proyek

Maven menggunakan sekumpulan pengenal, juga disebut koordinat, untuk mengidentifikasi proyek secara unik dan menentukan bagaimana artefak proyek harus dikemas:

  • groupId - nama dasar unik perusahaan atau grup yang membuat proyek
  • artifactId - nama unik proyek
  • versi - versi proyek
  • pengemasan - metode pengemasan (misalnya WAR / JAR / ZIP )

Tiga yang pertama ( groupId: artifactId: version ) digabungkan untuk membentuk pengenal unik dan merupakan mekanisme yang Anda gunakan untuk menentukan versi pustaka eksternal (misalnya JAR) yang akan digunakan proyek Anda.

3.2. Dependensi

Pustaka eksternal yang digunakan proyek ini disebut dependensi. Fitur manajemen dependensi di Maven memastikan download otomatis library tersebut dari repositori pusat, jadi Anda tidak perlu menyimpannya secara lokal.

Ini adalah fitur utama Maven dan memberikan keuntungan sebagai berikut:

  • menggunakan lebih sedikit penyimpanan dengan secara signifikan mengurangi jumlah unduhan dari repositori jarak jauh
  • membuat memeriksa proyek lebih cepat
  • menyediakan platform yang efektif untuk bertukar artefak biner dalam organisasi Anda dan sekitarnya tanpa perlu membuat artefak dari sumber setiap saat

Untuk mendeklarasikan ketergantungan pada pustaka eksternal, Anda perlu menyediakan groupId, artifactId , dan versi pustaka. Mari kita lihat contohnya:

 org.springframework spring-core 4.3.5.RELEASE 

Saat Maven memproses dependensi, ia akan mengunduh pustaka Spring Core ke dalam repositori Maven lokal Anda.

3.3. Repositori

A repository in Maven is used to hold build artifacts and dependencies of varying types. The default local repository is located in the .m2/repository folder under the home directory of the user.

If an artifact or a plug-in is available in the local repository, Maven uses it. Otherwise, it is downloaded from a central repository and stored in the local repository. The default central repository is Maven Central.

Some libraries, such as JBoss server, are not available at the central repository but are available at an alternate repository. For those libraries, you need to provide the URL to the alternate repository inside pom.xml file:

  JBoss repository //repository.jboss.org/nexus/content/groups/public/  

Please note that you can use multiple repositories in your projects.

3.4. Properties

Custom properties can help to make your pom.xml file easier to read and maintain. In the classic use case, you would use custom properties to define versions for your project's dependencies.

Maven properties are value-placeholders and are accessible anywhere within a pom.xml by using the notation ${name}, where name is the property.

Let's see an example:

 4.3.5.RELEASE    org.springframework spring-core ${spring.version}   org.springframework spring-context ${spring.version}  

Now if you want to upgrade Spring to a newer version, you only have to change the value inside theproperty tag and all the dependencies using that property in their tags will be updated.

Properties are also often used to define build path variables:

 ${project.build.directory}/tmp/   //... ${project.resources.build.folder} //... 

3.5. Build

The build section is also a very important section of the Maven POM. It provides information about the default Maven goal, the directory for the compiled project, and the final name of the application. The default build section looks like this:

 install ${basedir}/target ${artifactId}-${version}  filters/filter1.properties  //... 

The default output folder for compiled artifacts is named target, and the final name of the packaged artifact consists of the artifactId and version, but you can change it at any time.

3.6. Using Profiles

Another important feature of Maven is its support for profiles. A profile is basically a set of configuration values. By using profiles, you can customize the build for different environments such as Production/Test/Development:

  production    //...      development  true     //...     

As you can see in the example above, the default profile is set to development. If you want to run the production profile, you can use the following Maven command:

mvn clean install -Pproduction

4. Maven Build Lifecycles

Every Maven build follows a specified lifecycle. You can execute several build lifecyclegoals, including the ones to compile the project’s code, create a package, and install the archive file in the local Maven dependency repository.

4.1. Lifecycle Phases

The following list shows the most important Maven lifecycle phases:

  • validate – checks the correctness of the project
  • compile – compiles the provided source code into binary artifacts
  • test – executes unit tests
  • package – packages compiled code into an archive file
  • integration-test – executes additional tests, which require the packaging
  • verify – checks if the package is valid
  • install – installs the package file into the local Maven repository
  • deploy – deploys the package file to a remote server or repository

4.2. Plugins and Goals

A Maven plugin is a collection of one or more goals. Goals are executed in phases, which helps to determine the order in which the goals are executed.

The rich list of plugins that are officially supported by Maven is available here. There is also an interesting article how to build an executable JAR on Baeldung using various plugins.

To gain a better understanding of which goals are run in which phases by default, take a look at the default Maven lifecycle bindings.

To go through any one of the above phases, we just have to call one command:

mvn 

For example, mvn clean install will remove the previously created jar/war/zip files and compiled classes (clean) and execute all the phases necessary to install new archive (install).

Please note that goals provided by plugins can be associated with different phases of the lifecycle.

5. Your First Maven Project

In this section, we will use the command line functionality of Maven to create a Java project.

5.1. Generating a Simple Java Project

In order to build a simple Java project, let's run the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=org.baeldung.java -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

The groupId is a parameter indicating the group or individual that created a project, which is often a reversed company domain name. The artifactId is the base package name used in the project, and we use the standard archetype.

Since we didn't specify the version and the packaging type, these will be set to default values — the version will be set to 1.0-SNAPSHOT, and the packaging will be set to jar.

If you don't know which parameters to provide, you can always specify interactiveMode=true, so that Maven asks for all the required parameters.

After the command completes, we have a Java project containing an App.java class, which is just a simple “Hello World” program, in the src/main/java folder.

We also have an example test class in src/test/java. The pom.xml of this project will look similar to this:

 4.0.0 org.baeldung org.baeldung.java jar 1.0-SNAPSHOT org.baeldung.java //maven.apache.org   junit junit 4.1.2 test   

As you can see, the junit dependency is provided by default.

5.2. Compiling and Packaging a Project

The next step is to compile the project:

mvn compile

Maven will run through all lifecycle phases needed by the compile phase to build the project's sources. If you want to run only the test phase, you can use:

mvn test

Now let's invoke the package phase, which will produce the compiled archive jar file:

mvn package

5.3. Executing an Application

Finally, we are going to execute our Java project with the exec-maven-plugin. Let's configure the necessary plugins in the pom.xml:

 src   maven-compiler-plugin 3.6.1  1.8 1.8    org.codehaus.mojo exec-maven-plugin 1.5.0  org.baeldung.java.App    

The first plugin, maven-compiler-plugin, is responsible for compiling the source code using Java version 1.8. The exec-maven-plugin searches for the mainClass in our project.

To execute the application, we run the following command:

mvn exec:java

6. Multi-Module Projects

The mechanism in Maven that handles multi-module projects (also called aggregator projects) is called Reactor.

The Reactor collects all available modules to build, then sorts projects into the correct build order, and finally, builds them one by one.

Let's see how to create a multi-module parent project.

6.1. Create Parent Project

First of all, we need to create a parent project. In order to create a new project with the name parent-project, we use the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=parent-project

Next, we update the packaging type inside the pom.xml file to indicate that this is a parent module:

pom

6.2. Create Submodule Projects

In the next step, we create submodule projects from the directory of parent-project:

cd parent-project mvn archetype:generate -DgroupId=org.baeldung -DartifactId=core mvn archetype:generate -DgroupId=org.baeldung -DartifactId=service mvn archetype:generate -DgroupId=org.baeldung -DartifactId=webapp

To verify if we created the submodules correctly, we look in the parent-project pom.xml file, where we should see three modules:

 core service webapp 

Moreover, a parent section will be added in each submodule’s pom.xml:

 org.baeldung parent-project 1.0-SNAPSHOT 

6.3. Enable Dependency Management in Parent Project

Dependency management is a mechanism for centralizing the dependency information for a muti-module parent project and its children.

When you have a set of projects or modules that inherit a common parent, you can put all the required information about the dependencies in the common pom.xml file. This will simplify the references to the artifacts in the child POMs.

Let's take a look at a sample parent's pom.xml:

   org.springframework spring-core 4.3.5.RELEASE  //...  

By declaring the spring-core version in the parent, all submodules that depend on spring-core can declare the dependency using only the groupId and artifactId, and the version will be inherited:

  org.springframework spring-core  //... 

Moreover, you can provide exclusions for dependency management in parent's pom.xml, so that specific libraries will not be inherited by child modules:

  org.springframework spring-context  

Finally, if a child module needs to use a different version of a managed dependency, you can override the managed version in child's pom.xml file:

 org.springframework spring-core 4.2.1.RELEASE 

Please note that while child modules inherit from their parent project, a parent project does not necessarily have any modules that it aggregates. On the other hand, a parent project may also aggregate projects that do not inherit from it.

For more information on inheritance and aggregation please refer to this documentation.

6.4. Updating the Submodules and Building a Project

We can change the packaging type of each submodule. For example, let's change the packaging of the webapp module to WAR by updating the pom.xml file:

war

Now we can test the build of our project by using the mvn clean install command. The output of the Maven logs should be similar to this:

[INFO] Scanning for projects... [INFO] Reactor build order: [INFO] parent-project [INFO] core [INFO] service [INFO] webapp //............. [INFO] ----------------------------------------- [INFO] Reactor Summary: [INFO] ----------------------------------------- [INFO] parent-project .................. SUCCESS [2.041s] [INFO] core ............................ SUCCESS [4.802s] [INFO] service ......................... SUCCESS [3.065s] [INFO] webapp .......................... SUCCESS [6.125s] [INFO] -----------------------------------------

7. Conclusion

Pada artikel ini, kami membahas beberapa fitur yang lebih populer dari alat build Apache Maven.

Semua contoh kode di Baeldung dibuat menggunakan Maven, jadi Anda dapat dengan mudah memeriksa situs web proyek GitHub kami untuk melihat berbagai konfigurasi Maven.