前言

有时我们在构建项目时,希望能自动生成版本号或者生成不同操作系统标识的版本后缀,这时我们可以通过os-maven-plugin、buildnumber-maven-plugin这两个插件来完成。
如果我们想在构建完成后再进行上传操作,比如将打包后的文件上传到固定的发布目录,或者直接进行自动更新操作,这时我们可以使用wagon-ssh插件来完成这样的功能。


一、os-maven-plugin的使用

严格来说os-maven-plugin算不上一个插件,它只是一个编一阶段的依赖库,他的主要作用是提供本机的操作系统信息,方便我们在编译代码时引用相关的属性。
具体使用如下:

<build>
  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>1.7.0</version>
    </extension>
  </extensions>
</build>

然后我们就可以在pom.xml中来使用它提供的一些系统属性,目前主要提供了下面这些属性:

下面我们使用maven-antrun-plugin插件来打印相关信息,添加如下配置:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <phase>test</phase>
            <configuration>
                <target>
                    <echo message="os.detected.name: ${os.detected.name}"/>
                    <echo message="os.detected.arch: ${os.detected.arch}"/>
                    <echo message="os.detected.bitness: ${os.detected.bitness}"/>
                    <echo message="os.detected.version: ${os.detected.version}"/>
                    <echo message="os.detected.version.major: ${os.detected.version.major}"/>
                    <echo message="os.detected.version.minor: ${os.detected.version.minor}"/>
                    <echo message="os.detected.classifier: ${os.detected.classifier}"/>
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

然后运行maven命令:

mvn clean -DskipTests compile

输出结果:

[INFO] os.detected.name: osx
[INFO] os.detected.arch: x86_64
[INFO] os.detected.bitness: 64
[INFO] os.detected.version: 10.16
[INFO] os.detected.version.major: 10
[INFO] os.detected.version.minor: 16
[INFO] os.detected.classifier: osx-x86_64

另外在maven的dependency标签中有一个classifier属性,这个属性其实就是上面提供的os.detected.classifier,表示当前依赖的库是某个特定操作系统下的库。
比如:

<project>
  <dependencies>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>my-native-library</artifactId>
      <version>1.0.0</version>
      <classifier>${os.detected.classifier}</classifier>
    </dependency>
  </dependencies>
</project>

这样会根据你当前的操作系统的classifier去加载对应的库。

如果我们要发布特定操作系统下的一个依赖库,我们可以配合maven-jar-plugin插件来使用,添加如下配置:

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <classifier>${os.detected.classifier}</classifier>
    </configuration>
</plugin>

运行打包命令:

mvn clean -DskipTests package

打包成功后,生成的jar文件会自动加上os.detected.classifier的值,如下所示:

maven插件wagon-ssh、os-maven-plugin、buildnumber-maven-plugin使用详解-LMLPHP

二、buildnumber-maven-plugin使用

默认情况下,当我们不去修改build.finalName的值时。maven打包会自动带上项目的名称和version属性,如果我们想要对项目进行版本管理,这样每次打包就需要手动去修改版本号。buildnumber-maven-plugin能帮我们实现自动添加版本号的功能,但总的来说如果想要高度定制自己的版本号策略,这个插件还是不太能满足,下面我们来看下buildnumber-maven-plugin提供了哪些版本号策略。

取名叫buildnumber-maven-plugin的插件有很多,而且资料很乱,下面我们使用org.codehaus.mojo。还有其他的groupId,大家可以自行去研究。
使用配置:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>buildnumber-maven-plugin</artifactId>
      <version>3.1.0</version>
      <executions>
        <execution>
          <phase>validate</phase>
          <goals>
            <goal>create</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <doCheck>true</doCheck>
        <doUpdate>true</doUpdate>
      </configuration>
    </plugin>
  </plugins>
</build>

我们通过案例来介绍他的版本号策略。

1、时间戳策略

插件会提供一个buildNumber的全局属性,我们可以直接在pom.xml中使用。
时间戳就是根据当前的时间来生成版本号。

配置如下:

<build>
    <finalName>pkg-sb-${timestamp}</finalName>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>buildnumber-maven-plugin</artifactId>
            <version>1.4</version>
            <configuration>
                <timestampFormat>yyyyMMddHHmmss</timestampFormat>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>create-timestamp</goal>
                    </goals>
                </execution>
            </executions>
            <inherited>false</inherited>
        </plugin>

    </plugins>
</build>

这样我们会生成pkg-sb-20240223104052.jar这样的文件,在timestampFormat中,可以根据自身情况来进行格式化。

添加全局时间变量:

<properties>
	<maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
</properties>

然后修改build.finalName:

<build>
    <finalName>pkg-sb-${maven.build.timestamp}</finalName>
</build>

这样就会生成pkg-sb-2024-02-23 02:44:43.jar文件。

2、数字策略

如下所示在pom.xml中添加:

<scm>
    <connection>scm:git:https://github.com/xxx.git</connection>
    <developerConnection>scm:git:https://github.com/xxx.git</developerConnection>
    <tag>HEAD</tag>
    <url>https://github.com/xxx.git</url>
</scm>

上面的xxx替换成你实际的项目,当然出了github,还可以是任意的支持git仓库的私有库或者其他平台。
然后添加插件配置:

<build>
    <finalName>pkg-sb-${buildNumber}</finalName>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>buildnumber-maven-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>generate-buildnumber</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>create</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <format>1.0.{0,number}</format> 
                <items>
                    <item>buildNumber</item> 
                </items>
                <doCheck>false</doCheck>
                <doUpdate>false</doUpdate>
            </configuration>
        </plugin>

    </plugins>
</build>

然后运行打包命令:

mvn clean -DskipTests package
  1. 第一次打包生成文件:pkg-sb-1.0.1.jar
  2. 第二次打包生成文件:pkg-sb-1.0.2.jar
    同时在项目目录下,还生成了一个buildNumber.properties的文件,内容如下:
#maven.buildNumber.plugin properties file
#Fri Feb 23 11:23:27 CST 2024
buildNumber=2

也就是说,每次打包,这个文件都会更新

format标签可以进行任意的字符串格式化操作,比如下面的这段配置:

<configuration>
    <format>At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.</format>
    <items>
        <item implementation="java.lang.Integer">7</item>
        <item>timestamp</item>
        <item>a disturbance in the Force</item>
    </items>
</configuration>

生成的最终文件格式为:
pkg-sb-At 11:29:09 on 2024-2-23, there was a disturbance in the Force on planet 7…jar

三、wagon-ssh使用

打包后,如果我们要把相应的文件上传到服务器,或者直接进行自动更新操作,那么我们可以使用wagon-ssh来完成。
wagon-ssh的功能很强大,能进行File、HTTP、HTTP lightweight、FTP、SSH/SCP、WebDAV、SCM (in progress)操作,下面我们主要介绍SSH/SCP的相关操作。其他使用方式大家可以参照官网
在maven中使用wagon-ssh配置如下:

<project>
  [...]
  <build>
    [...]
    <extensions>
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
        <artifactId>wagon-ssh</artifactId>
        <version>${wagonApiVersion}</version>
      </extension>
    </extensions>

    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>wagon-maven-plugin</artifactId>
        <version>2.0.2</version>
        <executions>
          <execution>
            <id>upload-javadoc</id>
            <phase>deploy</phase>
            <goals>
              <goal>upload</goal>
            </goals>
            <configuration>
              <fromDir>local.dir</fromDir>
              <includes>*</includes>
              <excludes>pom.xml</excludes>
              <url>scp://your.remote.host/</url>
              <toDir>remote.dir</toDir>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

下面我们通过实际的使用实例来介绍。

1、上传文件/文件夹

<build>
    <finalName>pkg-sb</finalName>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>2.0.2</version>
            <executions>
                <execution>
                    <id>upload-javadoc</id>
                    <phase>package</phase>
                    <goals>
                        <goal>upload</goal>
                    </goals>
                    <configuration>
                        <includes>*</includes>
                        <excludes>pom.xml</excludes>
                        <fromDir>conf</fromDir>
                        <url>scp://root:tomcat@192.168.101.170</url>
                        <toDir>/root/test</toDir>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

上面的配置我们将项目下的conf文件夹下面的文件上传到了192.168.101.170的/root/test目录下。这里可以通过includes和excludes来进行文件过滤操作。

2、执行Linux命令或者shell脚本

如果我们要进行操作,可以添加如下配置:

 <build>
    <finalName>pkg-sb</finalName>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>2.0.2</version>
            <executions>
                <execution>
                    <id>execute-test-commands</id>
                    <phase>package</phase>
                    <goals>
                        <goal>sshexec</goal>
                    </goals>
                    <configuration>

                        <url>scp://root:tomcat@192.168.101.170</url>
                        <!-- 显示运行命令的输出结果 -->
                        <displayCommandOutputs>true</displayCommandOutputs>
                        <commands>
                            <command>ls -alh</command>
                            <command>/usr/share/tomcat/bin/tomcat stop</command>
                            <command>rm -rf /usr/share/tomcat/webapps/ROOT</command>
                            <command>unzip -o /usr/share/tomcat/webapps/myapp.zip -d /usr/share/tomcat/webapps/</command>
                            <command>/usr/share/tomcat/bin/tomcat start</command>
                        </commands>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

上面我们进行了命令操作和脚本操作,可以配置自己的项目情况来实现对项目的自动更新和重启

当然我们可以把两个execution合并,然后依次来执行。

注意:上面我们添加的execution的phase都是在package阶段,所以我们运行mvn package时会自动执行,如果要单独执行wagon-ssh,或者修改phase。可以使用下面命令来完成:

mvn -e  clean  wagon:upload wagon:sshexec

总结

上面三个插件大家可以根据自己的项目情况来配合使用,如有错误的地方欢迎大家留言提醒。

02-24 17:05