Using Maven to maintain and build your Java projects has a lot of advantages including automatically resolving dependencies, running tests and packaging.

In this article you will learn about a complete development cycle using Maven from creating the project to building it.

Installing Maven

You can install Maven on most Linux distributions using the default installer. In Ubuntu you can use apt like this.

apt-get install maven

On Mac you can install it with Homebrew:

brew install maven

For Windows, download it manually and unpack it. Then add the unpacked directory your executable path.

Creating a new Maven Project

Once you have Maven installed, you can start your new project like this:

mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.knowledgebasement.example -DartifactId=example

This will create a new directory called example and generate all the necessary artefacts for a new Java project under the package com.knowledgebasement.example. Make sure that you run this command in your usual development workspace such as the directory eclipse-workspace.

Inside the newly created directory (example in our case), you will find your automatically generated pom.xml, the file with all essential details about your project. It will look like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.knowledgebasement.example</groupId>
  <artifactId>example</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>example</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Note that junit was automatically added as a dependency.

Adding Dependencies to Your Project

Unless you intend to write everything by yourself from scratch, chances are that you will use external libraries and dependencies. For the current example, let's use javax.mail which would allow us to send mails from our Java code.

Open your pom.xml and go to the dependencies part. After the junit dependenice, add javax.mail with the latest current version 1.5.0-b01:

    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.5.0-b01</version>
    </dependency>

Before starting coding and being able to use the javax classes, you will have to resolve this dependency, i.e. download it, with the help of Maven like this:

mvn dependency:resolve

Running the above command will download the needed javax.mail files to your local Maven repo, i.e. in your home directory .m2/repository/javax/mail/mail/1.5.0-b01/mail-1.5.0-b01-sources.jar.

Import the New Project in Your IDE

After that you are ready to import the new project in your IDE and start coding. For Eclipse, use Import -> Maven -> Existing Maven Project. Point it to the directory of the new project, example in our case.

Now you are ready to start coding. Let's create a simple class which sends mails and looks like this:

package com.knowledgebasement.example;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class Example {
	public static void main(String[] args) throws Exception {
		System.out.println("Going to send mail.");
		sendMail("[email protected]", "[email protected]", "Test mail subject", "Test mail body");
	}

	public static void sendMail(String from, String to, String subject, String msgBody) throws Exception {

		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		try {
			Message msg = new MimeMessage(session);
			msg.setFrom(new InternetAddress(from));
			msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
			msg.setSubject(subject);
			msg.setText(msgBody);
			Transport.send(msg);
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
}

Provided you have resolved your dependencies correctly with Maven, the above imports should work fine.

If you try executing the above code in your IDE (Eclipse), it should compile correctly and print "Going to send mail". If you have a local smtp server, it will even try to send email to [email protected]. If you don't have, it will print an exception. Either way is fine for the testing.

Packaging the Code in a Single Jar

For convenience let's assume that we want our project bundled in a single jar file which we can easily transport and execute. To accomplish this aim, open again the project's pom.xml file and add a new build configuration part which looks like this:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>com.knowledgebasement.example.Example</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

Notice two important things:

  • mainClass will be our main entry point when we execute the jar.
  • the jar file will contain all the needed dependencies as per the descriptorRef property.

Now you are able to build your example application and test it. For this purpose use Maven as follows:

mvn clean compile assembly:single

This will produce a new jar file inside the target directory of your project example-1.0-SNAPSHOT-jar-with-dependencies.jar. Besides our own code, this jar file will contain also all the necessary libraries, javax.mail in our case.

The automatically generated example-1.0-SNAPSHOT-jar-with-dependencies.jar name comes from the property  <version> inside your pom.xml and SNAPSHOT hints that this is still a development version. With each new code change, ensure to increment the version number and remove the snapshot string when it is going to be a production-ready version.

Executing the Jar

Finally, you can execute your new Example application by just running:

java -jar example-1.0-jar-with-dependencies.jar

From this point on, just copy the jar file to wherever you need it and execute it. You don't have to worry whether:

  • the needed libraries (javax.mail in our case) have been copied already there.
  • the same libraries are in the java's build path.

This is one example of going through a complete development lifecyle with Maven and of what great help it can be.