Maven Java Example Application

In this application, we will create a simple adder that computes the sum of two integers. During this process, we will:

  1. Generate a Maven project using the Maven command-line tool
  2. Configure the pom.xml file
  3. Create main and test source code files
  4. Execute a Maven build
  5. Execute the resulting JAR file

Generating a Project

The first step to create our application is to generate the basic project structure. While we could do this manually, Maven includes a goal that will generate a quickstart project for us.

To generate this project, we execute the following command:

mvn archetype:generate \
  -DgroupId=com.dzone.albanoj2.maven.java \
  -DartifactId=adder \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.4 \
  -DinteractiveMode=false

Maven will then generate the following project structure for us:

adder/
  |- src/
  |  |- main
  |  |  +- java/
  |  |     +- com/dzone/albanoj2/maven/java
  |  |        +- App.java
  |  +- test
  |     +- java/
  |        +- com/dzone/albanoj2/maven/java
  |           +- AppTest.java
  +- pom.xml

Configuring the POM

Although the pom.xml file has been generated for us, it contains boilerplate configuration that is unnecessary for our purposes. Instead, we will replace the entire contents of the pom.xml file with the following configuration:

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dzone.albanoj2.maven.java</groupId>
    <artifactId>addr</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <junit.version>5.6.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                         <mainClass>com.dzone.albanoj2.maven.java.Application</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
        </pluginManagement>
    </build>

</project>

Starting from the top, we have our standard model version and GAV. After the GAV, we have our properties. These properties are key-value pairs, where the element name is the key, and the element value is the value. For example, the entry <maven.compiler.target>11</maven.compiler.target> creates a property where maven.compiler.target is the key and 11 is the value.

从顶部开始,我们有标准模型版本和GAV。GAV之后,我们拥有属性。这些属性是键-值对,其中元素名称是键,元素值是值。例如,条目<maven.compiler.target> 11 </maven.compiler.target>创建一个属性,其中maven.compiler.target是键,而11是值

Generally, properties can be any arbitrarily-named entry — so long as the key is a valid XML element name— and can be used elsewhere in the POM using the ${<key>} syntax. For example, we declare a property <junit.version> 5.6.2</junit.version> and use it in the element of our dependency: ${junit.version}.

通常,属性可以是任意命名的条目(只要键是有效的XML元素名称),并且可以使用$ {}语法在POM中的其它位置使用。例如,我们声明一个属性<junit.version> 5.5.2 </junit.version>并将其用于依赖项的元素: $ {junit.version} </ version>。

Other properties, such as maven.compiler.source, have special meaning. We have four of these special-case properties in our POM:

其它属性,例如maven.compiler.source,具有特殊含义。POM中有以下四个特殊情况属性:

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>

The first two define the encoding type of our source code and reporting output, respectively. If we omit these encoding types, Maven will warn us during compilation that our build is platform-dependent:

前两个分别定义了源代码和报告输出的编码类型。如果省略这些编码类型,则Maven将在编译期间警告我们,我们的构建依赖于平台:

[WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent!
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform dependent!

The last two properties configure the JDK version of our source code and the expected target JDK version, respectively. These keys are known by the Java compiler plugin for Maven and will, in turn, set the source and target JDK versions of the compiler.

最后两个属性分别配置我们的源代码的JDK版本和预期的目标JDK版本。这些密钥是Maven的Java编译器插件已知的,它们将依次设置编译器的源JDK版本和目标JDK版本

Next, we declare our JUnit dependency (under the dependencies element), which allows us to execute our automated tests. Note that the scope is test, which ensures that this dependency is not compiled or resolved in our executable application — only during the test phase.

接下来,我们声明JUnit依赖项(在依赖项下),这使我们能够执行自动化测试。请注意,作用域是test,这可以确保仅在测试阶段就不会在我们的可执行应用程序中编译或解析此依赖项

Lastly, we add the build element to override the default build configuration. In this case, we override the configuration for the maven-jar-plugin plugin to set the fully-qualified name of the main class that will be executed when we run our generated JAR file. While this is a concise override, there is an array of other options that can be overridden if needed. For more information, see the official Maven JAR Plugin documentation.

最后,我们添加构建元素以覆盖默认的构建配置。在这种情况下,我们将覆盖maven-jar-plugin插件的配置,以设置运行生成的JAR文件时将执行的主类的全限定名称

Creating the Main & Test Source Code

With our project structure and POM established, we can now add the source code to our project. The first step is to delete the App.java and AppTest.java files in src/main/java/com/dzone/albanoj2/maven/java and src/test/java/com/dzone/albanoj2/maven/java, respectively. We will then create a new file called Adder.java in src/main/java/com/dzone/albanoj2/maven/java:

Adder.java

package com.dzone.albanoj2.maven.java;

public class Adder {

    public int add(int a, int b) {
        return a + b;
    }
}

Next, we create an Application class in the same directory that includes a basic main method:

Application.java

package com.dzone.albanoj2.maven.java;

public class Application {

    public static void main(String[] args) {
        Adder adder = new Adder();
        System.out.println("2 + 2 = " + adder.add(2, 2));
    }
}

Lastly, we will create a new file called AdderTest.java in src/test/java/com/dzone/albanoj2/maven/java that will act as our unit test for our Adder class:

AdderTest.java

package com.dzone.albanoj2.maven.java;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.dzone.albanoj2.maven.java.Adder;
public class AdderTest {
    private Adder adder;
    @BeforeEach
    public void setUp() {
        adder = new Adder();
    }
    @Test
    public void whenAddTwoZeros_ThenSumIsZero() {
        assertEquals(0, adder.add(0, 0));
    }
    @Test
    public void whenAddFirstZeroSecondNegative_ThenSumIsEqualToSecond() {
        assertEquals(-1, adder.add(0, -1));
    }
    @Test
    public void whenAddFirstNegativeSecondZero_ThenSumIsEqualToFirst() {
        assertEquals(-1, adder.add(-1, 0));
    }
    @Test
    public void whenTwoNegatives_ThenSumIsCorrect() {
        assertEquals(-3, adder.add(-1, -2));
    }
    @Test
    public void whenAddFirstZeroSecondPositive_ThenSumIsEqualToSecond() {
        assertEquals(1, adder.add(0, 1));
    }
    @Test
    public void whenAddFirstPositiveSecondZero_ThenSumIsEqualToFirst() {
        assertEquals(1, adder.add(1, 0));
    }
    @Test
    public void whenTwoPositives_ThenSumIsCorrect() {
        assertEquals(3, adder.add(1, 2));
    }
    @Test
    public void whenAddFirstPositiveSecondNegative_ThenSumIsCorrect() {
        assertEquals(0, adder.add(1, -1));
    }
    @Test
    public void whenAddFirstNegativeSecondPositive_ThenSumIsCorrect() {
        assertEquals(0, adder.add(-1, 1));
    }
}

This results in the following directory structure:

adder/
  |- src/
  |  |- main
  |  |  +- java/
  |  |     +- com/dzone/albanoj2/maven/java
  |  |        |- Adder.java
  |  |        +- Application.java
  |  +- test
  |     +- java/
  |        +- com/dzone/albanoj2/maven/java
  |           +- AdderTest.java
  +- pom.xml

Executing the Build

We now have all of the components necessary to execute our Maven build. Our goal for this build will be to generate a JAR file that we can execute from the command-line. Therefore, we will use the Maven package goal to generate our JAR.

现在,具有执行Maven构建所需的所有组件。此构建的目标是生成可以从命令行执行的JAR文件。因此,我们将使用Maven package目标来生成JAR。

Before starting the build, we must change the directory to our project root (the adder/ directory). Once inside the project root, we then execute the following command:

开始构建之前,我们必须将目录更改为项目根目录(adder/)。进入项目根目录后,我们将执行以下命令:

mvn package

Finding & Running Packaged JAR

Once the build completes, we can find the packaged JAR — adder-1.0.0.jar — in the target/ directory. To execute this JAR, we change directory to target/ and execute the following command:

java -jar target\addr-1.0-SNAPSHOT.jar

This execution results in the following output:

2 + 2 = 4
posted @ 2020-06-09 17:53  PrimerPlus  阅读(191)  评论(0编辑  收藏  举报