[Maven Tutorial] (3) Basic Use: Getting Started Guide - POM Writing, Business Code, Test Code, Packaging and Running, Using Archetype to Generate Project Skeleton~

insert image description here


1️⃣ Write POM

So far, the Maven environment has been roughly understood and installed. Now, we start to create the simplest Hello Worldproject. If you are new to Maven, it is recommended to write and execute the code step by step according to the content of this article. You may encounter some concepts that are temporarily difficult to understand, but don’t worry, write down these difficult points, and I will go through them one by one in the follow-up articles answer.

Like Make, , the core Makefileof the Maven project is . Defines the basic information of the project, which is used to describe how the project is built, declare project dependencies, and so on. Now write the simplest one for the project .Antbuild.xmlpom.xmlPOM (Project Object Model, 项目对象模型)Hello Worldpom.xml

First create a hello-worldfolder named , open the folder, create a new pom.xmlfile named , and enter its content, as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven,apache.org/POM/4.0.0"
	xmins: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.xiaoshan.mvnbook</groupId>
	<artifactId>hello-world</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
</project>

The first line of code is an XML header specifying the version and encoding of the xml document. Next is projectthe element, projectwhich is pom.xmlthe root element of all , and it also declares some POM-related namespaces and xsdelements. Although these attributes are not required, using these attributes allows third-party tools (such as XML editors in the IDE) to help Let's quickly edit the POM.
The first child element under the root element modelVersionspecifies the version of the current POM model. For Maven 2 and Maven 3, it can only be 4.0.0.

The most important in this code are the three lines containing groupld, artifactldand version. These three elements define the basic coordinates of a project. In the world of Maven, any jaror pomall warare distinguished based on these basic coordinates.

groupldDefines which group the project belongs to, and this group is often associated with the organization or company where the project is located. For example, if you create a project called myapp on googlecode, then groupldit should be com. googlecode.myapp, if your company is mycom, and there is a project called myapp, then groupldit should be com.mycom.myapp. artifactldDefines the unique ID of the current Maven project in the group, which we define for this Hello Worldproject . And in the previous example of for , you might assign for different subprojects (modules) , such as , , etc. As the name suggests, specifies the current version of the project -- . SNAPSHOT means a snapshot, indicating that the project is still under development and is an unstable version. With the development of the project, it will be continuously updated, such as upgrading to , , , and so on. Later articles will introduce SNAPSHOT in detail and how to use Maven to manage the upgrade and release of project versions.artifactldhello-worldgroupIdcom. googlecode.myappartifactIdmyapp-utilmyapp-domainmyapp-web
versionHello World1.0-SNAPSHOTversion1.01.1-SNAPSHOT1.12.0

The last nameelement declares a more user-friendly project name, although it is not required, it is recommended to be declared for each POM nameto facilitate information exchange.

Without any actual Java code, we can define the POM of a Maven project, which reflects one of the great advantages of Maven, which can make the project object model independent of the actual code to the greatest extent, which we can call decoupling, or Orthogonality. This largely avoids the interaction of Java code and POM code. For example, when the project needs to upgrade the version, it only needs to modify the POM, without changing the Java code; after the POM is stable, the daily Java code development basically does not involve the modification of the POM.

2️⃣ Write business code

The business code of the project is different from the test code. The business code of the project will be packaged into the final component (such as jar), while the test code is only used when running the test and will not be packaged. By default, Maven assumes that the business code of the project is located in src/ main/javathe directory. We follow Maven's conventions, create this directory, and then create a file under this directory com/xiaoshan/mvnbook/helloworld/HelloWorld.java. The contents are as follows:

package com.xiaoshan.mvnbook.helloworld;

public class HelloWorld{
    
    
	public String sayHello(){
    
    
		return "Hello Maven";
	}
	public static void main(String[] args){
    
    
		System.out.print(new HelloWorld().sayHello());
	}
}

This is a simple Java class with one sayHello()method that returns a String. At the same time, this class also has a mainmethod to create an HelloWorldinstance, call sayHello()the method, and output the result to the console.

There are two things to note about this Java code. First of all, in most cases, the main code of the project should be placed src/main/java/in the directory (following the convention of Maven), without additional configuration, Maven will automatically search the directory to find the main code of the project. Second, the package name of the Java class is , which matches the and com.xiaoshan. mvnbook. helloworlddefined earlier in the POM . Generally speaking, the packages of Java classes in a project should be based on the project's sum , which is clearer and more logical, and it is also convenient to search for components or Java classes.groupIdartifactIdgroupIdartifactId

After the code is written, use Maven to compile and run the command in the project root directory mvn clean compile. will get the following output:

[INFO] Scanning for projects..
[INFO]
-----------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, compile]
[INFO]
-----------------------------------------------------------------------
[INFO] [clean:clean {
    
    execution:default-clean}]
[INF0] Deleting directory D:\code\hello-world\target
[INF0] [resources:resources {
    
    execution:default-resources}]
[INFO] skip non existing resourcepirectory D:\code\hello-world\src\main\resources
[INFO] [compiler:compile {
    
    execution:default-compile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\classes
[INFO]
-----------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-----------------------------------------------------------------------
[INFO]    Total time:1 second
[INFO]    Finished at: Fri oct 0902:08:09 CST 2009
[INFO]     Final Memory:9M/16M
-----------------------------------------------------------------------

cleanThe command tells Maven to clean up the output directory target/, compileand tells Maven to compile the main code of the project. From the output, we can see that Maven first executed clean:cleanthe task and deleted targel/the directory. By default, all the output of Maven builds are in target/the directory; then execute reources:resourcesthe task (the project resource is not defined, skip it for now); finally execute compiler:compilethe task to compile the main code of the project to target/classesthe directory (the compiled class is com/xiaoshan/mvnbook/helloworld/HelloWorld.class).

The mentioned above clean:clean, resources: resources 和 compiler:compilecorresponds to some Maven plug-ins and plug-in goals, for example, clean:cleanis the clean goal of the clean plug-in, and compiler:compileis the compile goal of the compiler plug-in. The Maven plugin and how to write it will be described in detail later.

So far, Maven has performed the cleaning and compiling tasks of the project without any additional configuration. Next, write some unit test code and let Maven execute the automated tests.

3️⃣ Write test code

In order to keep the project structure clear, business code and test code should be located in separate directories. As mentioned above, the default main code directory in the Maven project is src/main/java, and correspondingly, the default test code directory in the Maven project is src/test/java. Therefore, this directory should be created before writing test cases.

In Java, JUnit, established by Kent Beck and Erich Gamma, is the de facto standard for unit testing. To use JUnit, you first need to Hello Worldadd a JUnit dependency to the project, and modify the POM of the project as follows:

<?xml version="1.0" encoding="UTP-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>com.xiaoshan.mvnbook</groupld>
	<artifactId>helloworld</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>                            

A element is added to the code dependencies, which can contain multiple dependencyelements to declare the dependencies of the project. A dependency was added here - groupIdyes junityes yes 4.7. As mentioned earlier , and are the most basic coordinates of any Maven project, and JUnit is no exception. With this statement, Maven can download it automatically . You may ask, where does Maven download this jar? Before Maven, you can go to the official website of JUnit to download the distribution package. With Maven, it will automatically access the central warehouse ( ) and download the required files . You can also visit the warehouse by yourself, open the path , and you can see and . The Maven warehouse and central warehouse will be introduced in detail later.artifactIdjunitversiongroupIdartifactIdversionjunit-4.7.jarhttp://repol.maven.org/maven2/junit/junil/4.7/junit-4.7.pomjunil-4.7.jar

testThere is also an element whose value is in the above POM code scope, scopewhich is the dependency range. If the dependency range is test, it means that the dependency is only valid for the test. importIn other words, there is no problem with the JUnit code in the test code , but if you use import JUnit code in the main code, it will cause compilation errors. If you do not declare a dependency scope, then the default value is compile, which means that the dependency is valid for both the main code and the test code.

After configuring the test dependencies, you can write test classes. Looking back at the previous HelloWorldclass, now we need to test sayHello()the method of this class to check whether its return value is " Hello Maven". Create a file under src/test/javathe directory with the following contents:

package com.xiaoshan.mvnbook.helloworld;

import org.junit.Assert.assertEquals;
import org.junit.Test:

public class HelloWorldTest{
    
    
	@Test
	public void testSayHello(){
    
    
		He1loWorld helloWorld = new HelloWorld();
		String result = helloWorld.sayHello();
		assertEquals("Hello Maven",result);
	}
}

A typical unit test consists of three steps: ① prepare the test class and data; ② execute the behavior to be tested; ③ check the results. The above example first initializes an instance to be tested , then executes the method HelloWorldof the instance and saves the result to a variable, and finally uses the class of the JUnit framework to check whether the result is " " that we expect. In JUnit3, it is agreed that all methods that need to execute tests start with . JUnit4 is used here, but this convention is still followed. In JUnit4, all test methods that need to be executed should be marked.sayHello()resultAssertHelloMaventest@Test

After the test case is written, Maven can be invoked to execute the test. run mvn clean test:

[INFO] Scanning for projects.
[INFO]
-------------------------------------------------------------------
[INFO] Building Maven Hello World Project
[INFO] task-segment:[clean, test]
[INFO]
-------------------------------------------------------------------
[INFO] [elean:clean	{
    
    execution:default-clean}]
[INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target
[INFO] [resources:resources	{
    
    execution:default-resources)]
Downloading:http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom
	1K downloaded (junit-4.7.pom)
[INFO] [compiler:compile {
    
    execution: default-compile}]
[INFO]       Compiling 1 source file to D:\code\hello-world\target\classes
[INF0] [resources:testResources {
    
    execution:default-testResources}]
Downloading: http://repol,maven.org/maven2/junit/junit/4.7/unit-4.7.jar
	226K downloaded (Junit-4.7.jar) 
[INFO] [compiler:testCompile {
    
    execution:default-testCompile}]
[INFO] Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO]
-------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO]
-------------------------------------------------------------------
[INFO] Compilation failure
D:\code\hello-world\src\test\java\com\xiaoshan\mvnbook\helloworld\He11oWorldTest.java;[8,5]-source      1.3 中不支持注释(请使用-source 5 或更高版本以启用注释) @Test
[INFO]
[INFO For more information, run Maven with the switch

Unfortunately, the build failed. Please analyze this output patiently. The command line input is mvn clean test, and Maven actually executes more than these two tasks, as well as clean:clean, resources:resources, compiler:compile, resources:testResourcesand compiler:testCompile. What needs to be understood for the time being is that before Maven executes the test (test), it will automatically execute the project's main resource processing, main code compilation, test resource processing, and test code compilation. This is a feature of the Maven life cycle. Subsequent chapters will explain the Maven life cycle in detail.

It can also be seen from the output: Maven has downloaded junit-4.7.pomand junit-4.7.jarthese two files from the central warehouse to the local warehouse ( ~/. m2/repository) for use by all Maven projects.

compiler:testCompileThe build failed when executing the task, and the Maven output suggested that we need to use source5 or higher to start the annotation, which is the JUnit4 @Testannotation mentioned above. This is a problem Maven beginners often encounter. Due to historical reasons, one of Maven's core plug-ins, compilerthe plug-in, only supports compiling Java 1.3 by default, so the plug-in needs to be configured to support Java 5, as shown below:

<project>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5c/target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>           

This POM omits other parts than plugin configuration. We don't care about the details of the plug-in configuration for now, just know that compilerthe plug-in supports Java5 compilation. Now execute again mvn clean test, the output is as follows:

[INFO] [compiler:testCompile {
    
    execution:default-testCompile}]
[INFO]        Compiling 1 source file to D:\code\hello-world\target\test-classes
[INFO] [surefire:test {
    
    execution:default-test}]
[INFO]        Surefire report directory:D:\code\hello-world\target\surefire-reports
TESTS
Running com.xiaoshan.mvnbook.helloworld.He11oWorldTest
Tests run:1, Failures:0, Errors:0, Skipped:0,Time elapsed:0.055 sec
Results:
Tests run:1, Failures;0.Errors:0,Skipped:0
[INFO]
-------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO]
-------------------------------------------------------------------

We see that compiler:testCompilethe task is executed successfully. After the test code is compiled, a binary file is generated target/test-classesunder and then surefire:testthe task runs the test, surefirewhich is the plug-in responsible for executing the test in Maven. Here it runs the test case HelloWorldTest, and outputs the test report, showing that a total of How many tests, how many failed, how many went wrong, how many skipped. Clearly, our tests pass.

4️⃣ Package and run

After compiling and testing the project, the next important step is packaging ( package). HelloWorldThe packaging type is not specified in the POM, and the default packaging type jar is used. Simply execute the command mvn clean packageto package, you can see the following output:

...
Tests run:1,Failures:0, Errors:0, Skipped:0

[INFO] [jar:jar {
    
    execution: default-jar}]
[INFO] Building jar:D:\code\hello-worid\target\hello-wor1d-1.0-SNAPSHOT.Jar
[INPO]
-------------------------------------------------------------------
[INPO] BUILD SUCCESSFUL
...

Similarly, Maven will perform compilation, testing, etc. before packaging. Here we see jar:jarthat the task is responsible for packaging, in fact, the jar target of the jar plug-in packages the main code of the project into a hello-world-1.0-SNAP-SHOT.jarfile named . This file is also located target/in the output directory. It is artifact-version.jarnamed according to the rules. If necessary, you can also use finalNameto customize the name of the file. It will not be expanded here, and will be explained in detail later.

So far, we have obtained the output of the project. If necessary, we can copy this jar file to the Classpath of other projects to use the HelloWonldclass. However, how can other Maven projects directly reference this jar? An installation step is required, execute mvn clean install:

...
[INFO] [jar:jar {
    
    execution: default-jar}]
[INF0] Building jar:D:\code\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO] [install:install {
    
    execution:default-instal1}]
[INFO] Installing D:\code\hello-world\target\hello-wor1d-1.0-SNAPSHOT.jar to c:\Users\xiaoshan\.m2\repository\com\xiaoshan\mvnbook\hello-world\1.0-SNAPSHOTN\hello-world-1.0-SNAPSHOT.jar
[INFO]
-------------------------------------------------------------------
[INFO]   BUILD   SUCCESSFUL
...

After packaging, the installation task was performed install:install. From the output, you can see that the task has installed the jar output by the project into the Maven local warehouse, and you can open the corresponding folder to see the HelloWorldpom and jar of the project. When we talked about the download of JUnit's POM and jar, we said that only after the components are downloaded to the local warehouse, can they be used by all Maven projects HelloWorld. use it.

We have experienced the most important commands of Maven: mvn clean compile, mvn clean test, mvn clean package, mvn clean install. Executes testbefore executes compile, executes packagebefore executes test, and similarly, installbefore executes package. These commands can be executed in any Maven project, and we already know what they are used for.

So far, the HelloWorld project has not been run. Don't forget that the HelloWorld class has a mainmethod. The jar generated by default packaging cannot be run directly, because the class information with the main method will not be added to it manifest(open the file in the jar file META-INF/MANIFEST.MF, you will not be able to see Main-Classthe - line). In order to generate an executable jar file, you need to use it maven-shade-plugin. Configure the plug-in as follows:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>  
	<artifactId>maven-shade-plugin</artifactId> 
	<version>1.2.1</version>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>shade</goal>
			</goals>
			<configuration>
				<transformers>
					<transformer implementation="org.apache.maven.plugins.shade.resource. ManifestResourceTransformer">
						<mainClass>com.xiaoshan.mvnbook.helloworld.HelloWorld</mainclass>
					</transformer>	
				</transformers>
			</configuration>
		</execution>
	</executions>
</plugin>

pluginThe relative position of the element in the POM should be <project> <build> <plugins>below. We configured mainClassas com.xiaoshan.mvnbook.helloworld.HelloWorld, the project will put this information in when packaging MANIFEST. Execute now mvn clean install, open the directory after the build is complete target/, you can see hello-world-1.0-SNAPSHOT.jarand original-hello-world-1.0-SNAPSHOT.jar, the former is Main-Classan executable jar with information, the latter is the original jar, open hello-world-1.0-SNAPSHOT.jar, META-INF/ MANIFEST.MFyou can see that it contains such a line of information:

Main-Class:com.xiaoshan.mvnbook.helloworld.HelloWorld

Now, execute the jar file in the project root directory:

D:\code\hello-world>java-jartarget\hello-world-1.0-SNAPSHOT.jar
HelloMaven

The console output is HelloMaven, which is what we expect.

5️⃣ Use Archetype to generate project skeleton

There are some Maven conventions in the HelloWorld project: place in the root directory of the project pom.xml, src/main/javaplace the main code of the project in the directory, and src/test/javaplace the test code of the project in the directory. The reason why these steps are shown step by step is to let you, who may be a Maven beginner, get the most practical feeling. We call these basic directory structures and pom.xmlfile contents the skeleton of the project. When you create the project skeleton for the first time, you will be interested in understanding the ideas behind these default conventions. The second, third, You may still be satisfied with your proficiency, but the fourth or fifth time you do the same thing, you may be annoyed. To this end, Maven provides Archetypeto help us quickly outline the project skeleton.

Still taking HelloWorld as an example, we use maven archetypeto create the skeleton of the project, leaving the current Maven project directory.
In case of Maven3, simply run:

mvn archetype:generate

If it is Maven2, it is better to run the following command:

mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate

A lot of information will let you use simpler mvn archetype:generatecommands directly, but this is not safe in Maven2, because the command does not specify the version of the Archetype plug-in, so Maven will automatically download the latest version. In turn, an unstable SNAPSHOT version may be obtained, causing the operation to fail. However in Maven3, even if the user doesn't specify a version, Maven will only resolve the latest stable version, so this is safe.

We are actually running the plug-in maven-archetype-plugin, pay attention to the separation of the colon, its format is groupld:arifactld:version:goal, orgapache.maven.pluginsit is the maven official plug-in groupId, maven-archetype-pluginit is the Archetype plug-in artifactId, 2.0-alpha-5it is the latest stable version of the plug-in, and generateit is the plug-in target to be used.

Then you will see a long output, there are many available Archelypes to choose from, including the famous AppfuseArchetype of the project, JPAthe Archetype of the project, etc. Each Archetype will have a number in front of it, and the command line will prompt a default number, the corresponding Archetype is, press maven-archetype-quickstartEnter directly to select the Archelype, and then Maven will prompt you to enter the groupId, artifactId, versionand package name of the project to be created package. Enter and confirm as follows:

Define value for groupId:: com.xiaoshan.mvnbook
Define value for artifactId::hello-world
Define value for version::1.0-SNAPSHOT
Define value for package:com.xiaoshan.mvnbook::com.xiaoshan.mvnbook.helloworld
Confirm properties configuration:
groupId: com.juvenxu.mvnbook
artifactId: hello-world
version: 1.0-SNAPSHOT
package: com.xiaoshan.mvnbook.helloworld
Y::Y

The Archetype plugin will create a project skeleton based on the information we provide. In the current directory, the Archetype plugin will create a subdirectory named hello-world(we defined artifactId), from which you can see the basic structure of the project: the basic one pom.xmlhas been created, which contains the necessary information and a junit dependency; the main code directory src/main/javaIt has been created, and there is a Java class in this directory com.xiaoshan.mvnbook.helloworld.App. Note that the package name just defined is used here, and this class only has a simple output Hello World!method main; the test code directory src/test/javahas also been created, and contains a test case com.xiaoshan.mvnbook.helloworld.AppTest.

Archetype can help us quickly build the skeleton of the project. In the previous example, we can develop the project based on the skeleton generated by Archetype HelloWorldto save a lot of time.
In addition, here is just the simplest Archetype. If there are many projects with similar custom project structures and configuration files, you can develop your own Archetype once and for all, and then use the custom Archetype in these projects to quickly Generate project skeleton. Later I will elaborate on how to develop Maven Archetype.


Review the previous article (click to jump) :
"[Maven Tutorial] (2) Installation and Configuration: Teach you how to install and configure the Maven environment~"

Continue reading the next article (click to jump)
《》

Guess you like

Origin blog.csdn.net/LVSONGTAO1225/article/details/132453693