# Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

# Maven实用小技巧

Posted on 2020-02-16 In Java , Maven Views: Views: Disqus:

Maven 翻译为”专家”、”内行”，是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型（缩写：POM）概念，Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

Maven 是一个项目管理工具，可以对 Java 项目进行构建、依赖管理。

Maven 也可被用于构建和管理各种项目，例如 C#，Ruby，Scala 和其他语言编写的项目。Maven 曾是 Jakarta 项目的子项目，现为由 Apache 软件基金会主持的独立 Apache 项目。

maven也是我们日常项目中实用的包管理工具，相比以前需要用把包下载下来，放进 lib 中，在平时工作中使用的话，其实像 idea 这样的 ide 工具都会自带 maven 工具和插件

### maven的基本操作

- `mvn -v`
  查看 maven 信息
- `mvn compile`
  将 Java 编译成 class 文件
- `mvn test`
  执行 test 包下的测试用例
- `mvn package`
  将项目打成 jar 包
- `mvn clean`
  删除package 在 target 目录下面打出来的 jar 包和 target 目录
- `mvn install`
  将打出来的 jar 包复制到 maven 的本地仓库里
- `mvn deploy`
  将打出来的 jar 包上传到远程仓库里

### 与 composer 对比

因为我也是个 PHP 程序员，所以对比一下两种语言，很容易想到在 PHP 的 composer 跟 Java 的 maven 是比较类似的作用，有一点两者是非常相似的，就是原仓库都是因为某些原因连接拉取都会很慢，所以像 composer 会有一些国内源，前阵子阿里也出了一个，类似的 maven 一般也会使用阿里的镜像仓库，通过在 setting.xml 文件中的设置

    <mirrors>
        <mirror>
            <id>aliyun</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>

这算是个尴尬的共同点，然后因为 PHP 是解释型脚本语言，所以 php 打出来的 composer 包其实就是个 php 代码包，使用SPL Autoload等方式加载代码包，maven 包则是经过编译的 class 包，还有一点是 composer 也可以直接使用 github 地址作为包代码的拉取源，这点也是比较大的区别，maven使用 pom 文件管理依赖

### maven 的个人小技巧

- maven 拉取依赖时，同时将 snapshot 也更新了，就是 `mvn compile`加个`-U`参数，如果还不行就需要将本地仓库的 snapshot 删掉，
  这个命令的 help 命令解释是 -U,–update-snapshots Forces a check for missing releases and updated snapshots on
  remote repositories，这个在日常使用中还是很经常使用的
- maven 出现依赖冲突的时候的解决方法
  首先是依赖分析，使用`mvn dependency:tree`分析下依赖关系，如果要找具体某个包的依赖引用关系可以使用`mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-webmvc`命令进行分析，如果发现有冲突的依赖关系，本身 maven 中依赖引用有相对的顺序，大致来说是引用路径短的优先，pom 文件中定义的顺序优先，如果要把冲突的包排除掉可以在 pom 中用

      <exclusions>
        <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
      </exclusions>

  将冲突的包排除掉
- maven 依赖的 jdk 版本管理
  前面介绍的`mvn -v`可以查看 maven 的安装信息
  比如

      Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
      Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
      Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/jre
      Default locale: zh_CN, platform encoding: UTF-8
      OS name: "mac os x", version: "10.14.6", arch: "x86_64", family: "mac"

  这里可以看到用了 mac 自带的 jdk1.8，结合我之前碰到的一个问题，因为使用 homebrew 升级了 gradle，而 gradle 又依赖了 jdk13，因为这个 mvn 的 Java version 也变成 jdk13 了，然后 mvn 编译的时候出现了 `java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags`这个问题，所以需要把这个版本给改回来，但是咋改呢，网上搜来的一大堆都是在 pom 文件里的
  source和 target 版本

      <build>
        <plugins>
      <plugin>
      	<groupId>org.apache.maven.plugins</groupId>
      	<artifactId>maven-compiler-plugin</artifactId>
      	<configuration>
      		<source>1.8</source>
      		<target>1.8</target>
      		<encoding>UTF-8</encoding>
      	</configuration>
      </plugin>
        </plugins>
      <build>

  或者修改 maven 的 setting.xml中的

      <profiles>
            <profile>
                <id>ngmm-nexus</id>
              <activation>
                <jdk>1.8</jdk>
              </activation>
              <properties>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
            </properties>
            </profile>
      </profiles>

  但是这些都没啥用啊，真正有办法的是建个 `.mavenrc`，这个顾名思义就是 maven 的资源文件，类似于 `.bashrc`和`.zshrc`，在里面添加 MAVEN_HOME 和 JAVA_HOME,然后执行 `source .mavenrc`就 OK 啦

Related Posts

- 聊聊 Java 中绕不开的 Synchronized 关键字-二
- Apollo 的 value 注解是怎么自动更新的
- G1收集器概述
- mybatis 的 $ 和 # 是有啥区别
- mybatis 的缓存是怎么回事