最近让不同JAVA版本的容器maven打包折腾的不行,终于理出了一点头绪。在这里记录下备忘。

1. Maven与jdk版本的关系

先明确一个概念,关高版本JDK运行maven,是可以打出低版本的JAVA目标二进制文件的。比如用jdk 1.8运行maven,可以编译1.8,1.7.1.6等的代码,并输出相应版本的二进制文件。

当然,用低版本的jdk运行maven,是不可能输出高版本的JAVA二进制文件的。

另外:maven用哪个版本的JDK运行,取决于环境变量JAVA_HOME指向的是哪个版本。

2. 如何用Maven打出不同版本的JAVA二进制文件

我们可以在项目内的pom.xml和全局配置setings.xml内配置:

2.1 项目内的pom.xml内定义:

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

上面的配置就定义了通过jdk 1.8来构建

2.2 maven全局配置文件

在maven全局配置文件conf/settings.xml内配置:

<settings>
    <profile>
        <profile>
            <id>jdk-1.8</id> <!-- profile 名 -->
            <activation>
                <activeByDefault>false</activeByDefault> <!-- 此profile是否活动 -->
                <jdk>1.8</jdk> <!-- 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>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            </properties>
        </profile>

        <profile>
            <id>jdk-1.7</id>
            <activation>
                <activeByDefault>false</activeByDefault>
                <jdk>1.7</jdk>
            </activation>
            <properties>
                <maven.compiler.source>1.7</maven.compiler.source>
                <maven.compiler.target>1.7</maven.compiler.target>
                <maven.compiler.compilerVersion>1.7</maven.compiler.compilerVersion>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            </properties>
        </profile>
  </profiles>
  <activeProfiles>
        <activeProfile>jdk-1.7</activeProfile> <!-- 这个参数是定义活动的profile -->
  </activeProfiles>
</settings>

上面的配置是通过定义根据使用不同的jdk来选择不同的打包方案。
那么定义的profile如何使用呢?可以使用-P参数来指定。
mvn package -P jdk-1.7

3. 全局配置中profile的激活

3.1 使用activeByDefault激活

<id>jdk-1.7</id>
<activation>
    <activeByDefault>false</activeByDefault>
    <jdk>1.7</jdk>
</activation>

3.2 使用activeProfiles激活

<activeProfiles>
    <activeProfile>jdk-1.7</activeProfile> <!-- 这个参数是定义活动的profile -->
    <activeProfile>jdk-1.8</activeProfile>
</activeProfiles>

当定义了多个profile为激活的时候,它是根据profile定义的先后顺序来进行覆盖取值的,然后后面定义的会覆盖前面定义的。

3.3 使用-P参数激活

使用-P参数来激活。
mvn package -P jdk-1.7

4. profile的生效顺序

全局配置setting.xml内定义的激活的profile会优先于项目内的pom.xml。

  1. 如果maven setting.xml 配置<activeByDefault>true</activeByDefault>,并且pom中maven-compiler-plugin 未指定版本则优先生效;
  2. 如果maven setting.xml 配置<activeByDefault>false</activeByDefault>,并且pom未指定target,则根据环境变量JAVA_HOME生效;
  3. 如果 pom.xml 中的 maven-compiler-plugin 指定版本则优先生效;
  4. maven(ver 3.3.x)默认target 版本是1.6;
  5. 运行的maven 的 JAVA_HOME 版本要 >= 生效的target版本;
  6. 可以使用mvn help:active-profiles来查看哪些profile处于激活状态

5. 包依赖问题

有时候经常会发生包不对的问题,可以用以下命令查看项目的包依赖。
mvn dependency:tree