Maven学习

尉迟景福
2023-12-01

1,概念

内置变量

Maven提供了三个隐式的变量可以用来访问环境变量、POM信息、Maven Settings。

env

env变量,暴露了你操作系统或者shell的环境变量。如在Maven POM中一个对 e n v . P A T H 的引用将会被 {env.PATH}的引用将会被 env.PATH的引用将会被{PATH}环境变量替换,在Windows中为%PATH%.

project

project变量暴露了POM。可以使用点标记(.)的路径来引用POM元素的值。例如:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<finalName>${project.groupId}-${project.artifactId}</finalName>
</build>
</project>

当你使用mvn help:effective-pom 查看时,你会看到<finalName>org.sonatype.mavenbook-project-a</finalName>

常见的还有:

${basedir} 项目根目录
${project.build.directory} 构建目录,缺省为target
${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${project.build.finalName} 产出物名称,缺省为${project.artifactId}-${project.version}
${project.packaging} 打包类型,缺省为jar
${project.xxx} 当前pom文件的任意节点的内容

settings

settings变量暴露了Maven settings信息。可以使用点标记(.)的路径来引用settings.xml文件中元素的值。例如${settings.offline}会引用~/.m2/settings.xml文件中offline元素的值。

2,Profile

Profile能让你为一个特殊的环境自定义一个特殊的构建;profile使得不同环境间构建的可移植性成为可能。Maven中的profile是一组可选的配置,可以用来设置或者覆盖配置默认值。有了profile,你就可以为不同的环境定制构建。profile可以在pom.xml中配置,并给定一个id。然后你就可以在运行Maven的时候使用的命令行标记告诉Maven运行特定profile中的目标。

2.1 profile激活

profile可以让我们定义一系列的配置信息,然后指定其激活条件。

2.1.1 场景

多个profile,对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。

如根据环境来激活profile:profile一个非常重要的特性就是它可以根据不同的环境来激活,比如说根据操作系统的不同激活不同的profile,也可以根据jdk版本的不同激活不同的profile,等等。

<profiles> 
    <profile> 
        <id>profileTest1</id> 
        <jdk>1.5</jdk> 
    </profile> 
<profiles>

2.1.2定义位置(作用范围)

所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。

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

    <!--父模块 继承父模块属性-->
    <parent>
        <groupId>org.sonatype.oss</groupId>
        <artifactId>oss-parent</artifactId>
        <version>9</version>
    </parent>
    <!--项目或者组织的唯一标志-->
    <groupId>com.github.mpusher</groupId>
    <!--项目的通用名称-->
    <artifactId>mpush</artifactId>
    <!--打包的机制-->
    <packaging>pom</packaging>
    <!--项目版本-->
    <version>0.8.1</version>
    <!--项目的名称,maven产生的文档用-->
    <name>mpush</name>
    <!--项目的描述-->
    <description>MPUSH消息推送系统</description>
    <!--哪些网站可以找到这个项目,提示如果maven资源没有的话,可以上该网站进行寻找,maven产生的文档用-->
    <url>https://github.com/mpusher/mpush</url>

    <!--版本许可,描述了采用的开源协议是什么-->
    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <!--允许配置我们自己的代码库,未maven web站点和其他插件使用-->
    <scm>
        <tag>v${project.version}</tag>
        <url>https://github.com/mpusher/mpush</url>
        <connection>scm:git:git://github.com/mpusher/mpush.git</connection>
       	<developerConnection>scm:git:ssh://github.com/mpusher/mpush.git</developerConnection>
    </scm>

    <!--定义相应的bug跟踪系统,-->
    <issueManagement>
        <system>GitHub Issues</system>
        <url>https://github.com/mpusher/mpush/issues</url>
    </issueManagement>

    <!--配置组织信息-->
    <organization>
        <name>MPusher, Inc.</name>
        <url>https://mpusher.io</url>
    </organization>

    <!--开发者信息-->
    <developers>
        <developer>
            <name>夜色</name>
            <email>ohun@live.cn</email>
            <organization>mpusher</organization>
        </developer>
    </developers>

    <!--子模块-->
    <modules>
        <module>mpush-api</module>
        <module>mpush-tools</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.encoding>UTF-8</java.encoding>
        <java.version>1.8</java.version>
        <netty.version>4.1.25.Final</netty.version>
        <slf4j.version>1.7.25</slf4j.version>
        <os.detected.classifier>linux-x86_64</os.detected.classifier>
    </properties>


    <!--用于父项目配置共同的依赖关系,主要配置依赖包相同因素-->
    <dependencyManagement>
        <dependencies>
            <!-- ======================================== -->
            <!-- netty依赖 -->
            <!-- ======================================== -->
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-codec</artifactId>
                <version>${netty.version}</version>
            </dependency>
            <!-- ======================================== -->
            <!-- 子模块依赖 -->
            <!-- ======================================== -->
            <dependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>mpush-test</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- 编译配置 -->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.2</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${java.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <encoding>${java.encoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.20</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>dev</id>
            <activation><!--指定激活条件。当没有指定条件,然后指定activeByDefault为true的时候就表示当没有指定其他profile为激活状态时,该profile就默认会被激活-->
                <activeByDefault>true</activeByDefault> 
            </activation>
            <properties>
                <deploy.env>dev</deploy.env>
            </properties>
        </profile>
        <profile>
            <id>pub</id>
            <properties>
                <deploy.env>pub</deploy.env>
            </properties>
        </profile>
    </profiles>
</project>


2.1.2.2 settings.xml(全局的profile配置)

构建配置文件大体上有三种类型:

类型在哪定义
项目级(Per Project)定义在项目的POM文件pom.xml中
用户级 (Per User)定义在Maven的设置xml文件中 (%USER_HOME%/.m2/settings.xml)
全局(Global)定义在Maven全局的设置xml文件中 (%M2_HOME%/conf/settings.xml)

2.1.3 profile激活

Maven的构建配置文件可以通过多种方式激活:

  • 使用命令控制台输入显式激活。
  • 通过maven设置。
  • 基于环境变量(用户或者系统变量)。
  • 操作系统设置(比如说,Windows系列)。
  • 文件的存在或者缺失。

3,shell常用命令

mvn

mvn deploy

配置settings.xml

因为nexus是需要登陆操作,当然可以通过配置免登陆,这是后话。在settings.xml

</servers>

<server>   
<id>thirdparty</id>   
<username>admin</username>
<password>admin123</password>   
</server>

当然如果你要上传包去其他仓库,可依照此例:

<server>   
<id>central</id>   
<username>admin</username>   
<password>admin123</password>   
</server>

如果进行deploy时返回Return code is: 401错误,则需要进行用户验证或者你已经验证的信息有误。

命令行操作

mvn deploy:deploy-file -DgroupId=com.xy.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.4.0 -Dpackaging=jar -Dfile=E:\ojdbc14.jar -Durl=http://localhost:9090/nexus-2.2-01/content/repositories/thirdparty/ -DrepositoryId=thirdparty

DgroupId和DartifactId构成了该jar包在pom.xml的坐标,项目就是依靠这两个属性定位。自己起名字也行。
Dfile表示需要上传的jar包的绝对路径。
Durl私服上仓库的位置,打开nexus > repositories菜单,可以看到该路径。
DrepositoryId服务器的表示id,在nexus的configuration可以看到。
Dversion表示版本信息,怎样得到一个jar包准确的版本呢?
解压该包,会发现一个叫MANIFEST.MF的文件,这个文件就有描述该包的版本信息。
比如Manifest-Version: 1.0可以知道该包的版本了。
上传成功后,在nexus界面点击3rd party仓库可以看到这包。

4,常见标签

1

5,插件 plugin

maven插件是在生命周期中某些阶段执行的任务。一个插件完成一项功能。

5.1 maven-jar-plugin:打包成jar

maven 默认打包插件,打成jar时,设定manifest的参数,比如指定运行的Main class,还有依赖的jar包,加入classpath中。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>/data/lib</classpathPrefix>
                <mainClass>com.zhang.spring.App</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

5.2 maven-shade-plugin:把多个jar包,打成1个jar包

用来打可执行包,executable(fat) jar。
一般Java项目都会依赖其他第三方jar包,最终打包时,希望把其他jar包包含在一个jar包里。
与assembly类似,使用assembly即可。以下详解assembly。

5.3 maven-assembly-plugin:定制化打包

支持定制化打包方式,例如 apache 项目的打包方式。

5.3.1 使用

5.3.1.1 首先我们需要在pom.xml中配置maven的assembly插件

<build>
    <plugins>
        <plugin>       
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>             
                <execution><!-- 配置执行器 -->
                    <id>make-assembly</id>
                	<phase>package</phase><!-- 绑定到package生命周期阶段上 -->
	                <goals>
	                    <goal>single</goal><!-- 只运行一次 -->   
	                </goals>
                    <configuration>
	                  	<finalName>${project.name}</finalName>
	                  	<appendAssemblyId>false</appendAssemblyId>
	                 	 ...   <!--主类入口等-->
	                 	 <descriptors>
									<descriptor>src/main/assembly/assembly.xml</descriptor><!--配置描述文件路径--> 
						</descriptors>
                	</configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
     </build>

a. <goals>

  • single

  • help
    可以执行如下命令完成动作:mvn assembly:single
    开发时较为常用的是:绑定到package生命周期阶段上(见上配置)触发。后续可以直接执行:mvn package
    b. <descriptor>
    要使用maven-assembly-plugin,需要指定至少一个要使用的assembly descriptor 文件。默认情况下,maven-assembly-plugin内置了几个可以用的assembly descriptor:

    bin : 类似于默认打包,会将bin目录下的文件打到包中;
    jar-with-dependencies : 会将所有依赖都解压打包到生成物中;
    src :只将源码目录下的文件打包;
    project : 将整个project资源打包。

上述4中预定义的assembly descriptor有对应的xml。要查看它们的详细定义,可以到maven-assembly-plugin.jar里去看。
一般来说,内置的assembly descriptor都不满足需求,这个时候就需要写自己的assembly descriptor的实现了。

5.3.1.2 自定义assembly.xml

使用 descriptors,指定打包文件 src/assembly/assembly.xml,即在配置文件内指定打包操作要使用这个自定义assembly descriptor(自定义的xml中配置),需要如下配置,即要引入描述文件:

<?xml version='1.0' encoding='UTF-8'?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0  
                    http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>demo</id> <!--id 标识符,添加到生成文件名称的后缀符。如果指定 id 的话,目标文件则是 artifactId−{id}.tar.gz-->
    <formats>  <!--指定打包类型:zip、tar、tar.gz (or tgz)、tar.bz2 (or tbz2)、jar、dir、war,可以同时指定多个打包格式-->
        <format>tar.gz</format>
    	<format>dir</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory> <!--tar.gz压缩包下是否生成和项目名相同的根目录-->
    <fileSets>
        <fileSet> <!--指定要打包的目录,可以定义多个fileSet。点对点打包,将某一个目录打包到某一个目录下,可以选择排除某些目录和包含某些目录-->
            <directory>${project.build.directory}/lib</directory> <!--指定要包含的目录-->
            <outputDirectory>${file.separator}lib</outputDirectory> <!--指定文件集合的输出目录,该目录是相对于根目录-->
            <includes><!--包含文件。对应的有excludes/exclude*标签,用于排除文件-->
				<include>*.jar</include>
			</includes>
			<fileMode>0755</fileMode><!--指定文件属性,使用八进制表达,分别为(User)(Group)(Other)所属属性,默认为 0644。4-读 2-写 1-执行-->
        </fileSet>
    </fileSets>
    <dependencySets><!--用来定制工程依赖 jar 包的打包方式-->
        <dependencySet>
             <useProjectArtifact>true</useProjectArtifact><!--是否把本项目添加到依赖文件夹下-->
             <outputDirectory>lib</outputDirectory><!--指定包依赖目录,该目录是相对于根目录-->
             <scope>runtime</scope><!--将scope为runtime的依赖包打包-->
             <!--includes/include* 	类型为List 	包含依赖 -->
			 <!--excludes/exclude* 	类型为List 	排除依赖 -->
         </dependencySet>
   </dependencySets>
    <files>
    <file> <!--指定目的文件名到指定目录-->
      <source>README.txt</source> <!--源文件,相对路径或绝对路径-->
      <outputDirectory>/</outputDirectory><!--输出目录-->
      <!-- destName  	目标文件名-->
	  <!-- fileMode  	设置文件 UNIX 属性-->
    </file>
  </files>
</assembly>

5.4 maven-compiler-plugin:编译Java源码

编译Java源码,一般只需设置编译的jdk版本。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
</plugin>

或者在properties设置jdk版本:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
 </properties>

5.5 tomcat7-maven-plugin:远程部署Java Web项目

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <url>http://59.110.162.178:8080/manager/text</url>
        <username>linjinbin</username>
        <password>linjinbin</password>
    </configuration>
</plugin>

5.6 Maven打包导致Excel资源文件损坏问题

主要现象:excel本地使用没有问题,放服务器上使用提示文件损坏。解决方案就是在maven打包里忽略某些后缀文件:

<build>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-resources-plugin</artifactId>
         <configuration>
            <encoding>UTF-8</encoding>
            <nonFilteredFileExtensions>
               <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
               <nonFilteredFileExtension>xls</nonFilteredFileExtension>
            </nonFilteredFileExtensions>
         </configuration>
      </plugin>
   </plugins>
   <resources>
      <resource>
         <directory>src/main/resources</directory>
         <filtering>true</filtering>
      </resource>
   </resources>
</build>

7)maven编译时如何忽略单元测试

共有两种种解决办法:

  1. 通过在命令行设置:
mvn clean install tomcat:run -Dmaven.test.skip=true
或者
mvn clean install tomcat:run -DskipTests
  1. 通过在pom.xml配置文件进行配置
<project>
	[...]
   <build>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
          <skipTests>true</skipTests>
         </configuration>
       </plugin>
     </plugins>
   </build>
   [...]
</project>
 类似资料: