Building Java Projects with Maven

Original http://spring.io/guides/gs/maven/

Maven Install

  1. Download the latest binary file from http://maven.apache.org/download.cgi.
  2. Unzip and move the generated directory to the desired location.
  3. Add the Maven bin directory to the Path.
  4. Make sure you have the JAVA_HOME environment variable. Because Maven refers to the JAVA_HOME environment variable, it should be created if it does not exist. (See JDK Install)

Open a command prompt and check the Maven version with the following command:

C:\ Command Prompt
C:\Users\kim> mvn -v
Apache Maven 3.5.0
Maven home: C:\Program Files\apache-maven-3.5.0\bin\..
Java version: 10.0.1, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk-10.0.1\jre
..

Set up the project

There are two ways to create a Maven project.
The first is to manually create the maven project directory structure and the pom.xml file.
The second is to use the mvn archetype: generate command.

1. Create the directory structure

In a project directory of your choosing, create the following subdirectory structure

HelloWorld (root directory)
   └── src
        └── main
             └── java
                  └── hello

Create a file named pom.xml at the root of the project

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework.gs</groupId>
	<artifactId>gs-maven-initial</artifactId>
	<version>0.1.0</version>
	<packaging>jar</packaging>
	
</project>
  • <modelVersion> POM model version (always 4.0.0).
  • <groupId> Group or organization that the project belongs to. Often expressed as an inverted domain name.
  • <artifactId> Name to be given to the project’s library artifact (for example, the name of its JAR or WAR file).
  • <version> Version of the project that is being built.
  • <packaging> How the project should be packaged. Defaults to "jar" for JAR file packaging. Use "war" for WAR file packaging.

Within the src/main/java/hello directory, create these two classes: HelloWorld.java and Greeter.java.

HelloWorld/src/main/java/hello/HelloWorld.java
package hello;

public class HelloWorld {
    public static void main(String[] args) {
        Greeter greeter = new Greeter();
        System.out.println(greeter.sayHello());
    }
}
HelloWorld/src/main/java/hello/Greeter.java
package hello;

public class Greeter {
    public String sayHello() {
        return "Hello world!";
    }
}

Build Java code

To try out the build, issue the following at the command line:

mvn compile

This will run Maven, telling it to execute the compile goal. When it’s finished, you can find the compiled .class files in the target/classes directory.
mvn compile

Since it’s unlikely that you’ll want to distribute or work with .class files directly, you’ll probably want to run the package goal instead:

mvn package

Compile the Java code, test it, bundle it in a package (jar or war), and save it in the target directory.
According to the pom.xml configuration above, a file named gs-maven-initial-0.1.0.jar is created in the target directory.
mvn package

Maven also maintains a repository of dependencies on your local machine (usually in a .m2/repository directory in your home directory) for quick access to project dependencies. If you’d like to install your project’s JAR file to that local repository, then you have to invoke the install goal:

mvn install

The above command saves the packaged jar file in the local repository.
mvn install

mvn clean

The above command deletes all artifacts generated by the build.
mvn clean

You can invoke multiple goals as follows:

mvn clean compile

You can run the HelloWorld program with the following command:

mvn exec:java -Dexec.mainClass=hello.HelloWorld

Declare Dependencies

Most applications depend on external libraries.
Modify HelloWorld.java as follows.

HelloWorld/src/main/java/hello/HelloWorld.java
package hello;

import org.joda.time.LocalTime;

public class HelloWorld {
  public static void main(String[] args) {
    LocalTime currentTime = new LocalTime();
    System.out.println("The current local time is: " + currentTime);

    Greeter greeter = new Greeter();
    System.out.println(greeter.sayHello());
  }
}

Here HelloWorld uses Joda Time’s LocalTime class to get and print the current time.
If you were to run mvn compile to build the project now, the build would fail because you’ve not declared Joda Time as a compile dependency in the build.
Modify pom.xml as shown below.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>org.springframework</groupId>
    <artifactId>gs-maven</artifactId>
    <version>0.1.0</version>
    <packaging>jar</packaging>
    
    <dependencies>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.2</version>
        </dependency>
    </dependencies>
	
</project>

The scope element can be added as a sub-element of dependency.
The value of scope is either compile, provided, or test.
(The default value is compile)

  • provided: Required at compile time but provided by the container at runtime (eg Servlet API)
  • test: Required for compilation and testing, but not needed for build or run.

If you add the dependency and run mvn compile again, it succeeds.

2. Creating a Maven project using mvn archetype:generate

mvn archetype: generate allows you to interactively create a maven project.
(Archetype has a lexical meaning of prototype, which in Java stands for project prototype)
This method automatically creates the maven directory and the pom.xml file, as well as the prototypes of various Java projects.
From the C:\maven directory, run:

C:\ Command Prompt
C:\maven> mvn archetype:generate

In the screen below, press enter to select maven-archetype-quickstart.

C:\ Command Prompt
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 990: 

In the screen below, press enter to select the latest version.

C:\ Command Prompt
Choose org.apache.maven.archetypes:maven-archetype-quickstart version:
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.1
Choose a number: 6:

Give groupId and artifactId the values shown below. (for version and package, press enter to accept the default)

C:\ Command Prompt
Define value for property 'groupId': : org.springframework.gs
Define value for property 'artifactId': : gs-maven-initial
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  org.springframework.gs: :

On the screen below, press the Enter key.

C:\ Command Prompt
Confirm properties configuration:
groupId: org.springframework.gs
artifactId: gs-maven-initial
version: 1.0-SNAPSHOT
package: org.springframework.gs
 Y: :

The gs-maven-initial directory, such as the artifactId value, is created and the pom.xml file and maven directory are created in this directory.
(C:\maven\gs-maven-initial is the root directory)

C:\ Command Prompt
C:\maven>cd gs-maven-initial
C:\maven\gs-maven-initial>

Spring framework Quick Start

Original http://projects.spring.io/spring-framework/#quick-start

Create a directory for the Maven project as shown below.

quick-start
   └── src
        └── main
             └── java
                  └── hello

Create a pom.xml file in the root directory.
(Check the latest release version at http://projects.spring.io/spring-framework/)

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>net.java_school</groupId>
	<artifactId>quick-start</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>quick-start</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.1.5.RELEASE</version>
		</dependency>
		
	</dependencies>
	
</project>

Spring is the key to the bean container's ability to manage beans.
Spring-context dependencies have been added to pom.xml.
Here is a brief description of Maven's dependency management features:
If the project relies on the A library and A depends on B, then Maven will store both A and B in the repository with only the A dependency configuration.
Thus, even if only the spring-context is added, other libraries dependent on spring-context are also stored in the repository.

At the command prompt, run Notepad to create the MessageService.java, MessagePrinter.java, and Application.java files in the hello folder as shown below.

C:\ Command Prompt
C:\maven\quick-start\src\main\java\hello>notepad MessageService.java
MessageService.java
package hello;

public interface MessageService {
    String getMessage();
}
C:\ Command Prompt
C:\maven\quick-start\src\main\java\hello>notepad MessagePrinter.java
MessagePrinter.java
package hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MessagePrinter {

    @Autowired
    private MessageService service;

    public void printMessage() {
        System.out.println(this.service.getMessage());
    }
}
C:\ Command Prompt
C:\maven\quick-start\src\main\java\hello>notepad Application.java
Application.java
package hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

@Configuration
@ComponentScan
public class Application {

	@Bean
	MessageService mockMessageService() {
		return new MessageService() {
			public String getMessage() {
				return "Hello World!";
			}
		};
	}

	public static void main(String[] args) {
		ApplicationContext context = 
			new AnnotationConfigApplicationContext(Application.class);
		MessagePrinter printer = context.getBean(MessagePrinter.class);
		printer.printMessage();
	}
}

Run the following commands in order.

C:\ Command Prompt
mvn compile
mvn exec:java -Dexec.mainClass=hello.Application

In the code, MessagePrinter and MessageService are not combined.
But Spring Framework combines them.

Check which libraries are stored in Maven's local repository.

C:\ Command Prompt
C:\Users\kim\.m2\repository\org\springframework>dir /w

[spring-aop]  [spring-beans]  [spring-context]  [spring-core]  

[spring-expression]

The spring-aop, spring-beans, spring-core, and spring-expression dependent on spring-context are also installed.

References