• Maven快照版本要这样用才真的香!


    Bug的身世之谜

    今天又分享一个问题解决的故事。请看下图框起来的错误,明显就是找不到这个class嘛!

    下面我们按照正常人的思路去排查这个问题,既然找不到class那就先看这个依赖的jar包有没有,如果没有那就是铁证如山。

    但是事与愿违啊,编译后的lib目录下真的有这个包o****rder-api-2.0-SNAPSHOT.jar

    还是不相信,于是将order-api-2.0-SNAPSHOT.jar解压了,看看里面到底有没有我们需要的class,真的有,此处心情沉重。

    一般人到这里就会懵圈了,但我还年轻啊,脑袋还够用。接下来看看classpath的配置有没有问题,如果order-api-2.0-SNAPSHOT.jar不在classpath中,那么自然就是找不到class啊,机智的我。

    于是查看了META-INF/MANIFEST.MF文件,发现里面依赖的是order-api-2.0-20200225.024541-15.jar,什么情况,还加上时间戳了。

    终于真相大白了,classpath中指向的是order-api-2.0-20200225.024541-15.jar,但lib中只有order-api-2.0-SNAPSHOT.jar。所以找不到class是没有错的。

    打包配置信息

    Maven deploy的时候会自动给快照版本加时间戳,从下图可以看的出来:

    下面来看下目前项目的打包配置,如下:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.3.1</version>
      <configuration>
        <archive>
          <manifest>
            <mainClass>com.xxx.web.WebApp</mainClass>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
          </manifest>
        </archive>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-assembly-plugin</artifactId>
    </plugin>
    

    用了assembly插件,对应的配置如下:

    assembly.xml

    <assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>bin</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <unpack>false</unpack>
            <includes>
                <include>${artifact}</include>
            </includes>
            <outputFileNameMapping>xxx-web.jar</outputFileNameMapping>
        </dependencySet>
        <dependencySet>
            <outputDirectory>/lib</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>false</unpack>
        </dependencySet>
    </dependencySets>
    </assembly>
    

    打包后目录中会有一个jar包和一个lib目录,如下:

    -xxx-web.jar
    -lib
      -xxx.jar
      -yyy.jar
    

    解决方案

    现在需要解决的问题是classpath中的快照依赖和lib目录中实际的jar包不一致的问题。

    主要是两个插件,所以才会有不一致的情况。

    maven-jar-plugin插件中可以加上false来强制打包时 MANIFEST.MF文件不记录的Jar时间戳版本。

    maven-assembly-plugin插件需要在assembly.xml中进行修改,在dependencySet中增加outputFileNameMapping=${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}

    来固定名称,这样就可以去掉时间戳了。

    下面贴一下修改之后完整的配置:

    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <version>2.3.1</version>
      <configuration>
        <archive>
          <manifest>
            <mainClass>com.xxx.web.WebApp</mainClass>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <useUniqueVersions>false</useUniqueVersions>
          </manifest>
        </archive>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-assembly-plugin</artifactId>
    </plugin>
    

    assembly.xml

    <assembly
    xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>bin</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <unpack>false</unpack>
            <includes>
                <include>${artifact}</include>
            </includes>
            <outputFileNameMapping>xxx-web.jar</outputFileNameMapping>
        </dependencySet>
        <dependencySet>
            <outputFileNameMapping>
      ${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}  
            </outputFileNameMapping>
            <outputDirectory>/lib</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>false</unpack>
        </dependencySet>
    </dependencySets>
    </assembly>
    

    虽然解决了,但感觉还是挺麻烦的。还是spring-boot-maven-plugin插件好用啊,至少没有出现过这个时间戳的问题,新项目建议大家用spring-boot-maven-plugin插件打包。

    关于作者:尹吉欢,简单的技术爱好者,《Spring Cloud微服务-全栈技术与案例解析》, 《Spring Cloud微服务 入门 实战与进阶》作者, 公众号 猿天地 发起人。

  • 相关阅读:
    315,谁来保护手游开发者的利益
    微信小程序之提高应用速度小技巧
    Python-爬虫-Beautifulsoup解析
    Python-爬虫-requests
    Python-form表单标签
    设计模式のTemplatePattern(模板模式)----行为模式
    链接
    python入门007
    007作业
    005作业
  • 原文地址:https://www.cnblogs.com/yinjihuan/p/12685149.html
Copyright © 2020-2023  润新知