如何在Maven项目中设置Java 9

595 阅读3分钟
原文链接: zhuanlan.zhihu.com

在这个简短的教程中,我想向你展示如何配置新的Java 9启用的Maven项目。

TL; DR

您可以在这里找到一个示例项目:https//github.com/springuni/springuni-java9

模块

我们以前也可以在Maven(也有Gradle,Ant等)中创建了多个模块项目,但是它们并不是严格的模块。他们似乎是独立的代码库,没有一个标准的方法来定义这些模块提供和需要的功能。使用构建系统,您可以声明依赖关系,但是模块本身并不负责管理自己的依赖关系并提供服务。

在大型项目中,当多个版本的同一个库被拉入作为传递依赖关系的副作用时,开发人员很快就会遇到jar-hell

Java 9的变化如何减轻这一点,您现在可以正式声明module-info.java封装以下信息的模块。

  • 模块名称
  • 该模块依赖的其他模块
  • 该模块提供了其他模块

许多知名的库(library )预计将迁移到Java 9的模块系统,因此他们可以共享其公共API并使用此机制来隐藏其内部。

但有一点值得注意的是,如果您将来需要使用这样的库(library)那么您将要做什么呢?这是一个合理的问题,这里就是模块类型。

模块类型

模块只是以前的简单的旧JAR文件,但是从Java 9开始,它们将包含一个我上面提到的一个特殊的module-info.java。还有一个称为模块路径的新概念,它是众所周知的类路径的兄弟。

说到这里有四种模块类型

  • 命名的模块(也称为应用程序模块)包含上述module-info.java
  • 平台模块(类似于前者,但这些都是随JDK一起发货)
  • 自动模块是在模块路径上提供的那些旧JAR
  • 未命名的模块是标准类路径上列出的所有内容

对Maven用户的影响

像Maven这样的构建工具必须要处理JDK的新结构,也就是module-info.java模块路径。他们有一个Wiki页面,其中列出了Java 9的所有插件要求。

编译器插件

为了能够使用JDK 9的模块系统maven-compiler-plugin版本3.6.1或更高版本是必需的。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.6.1</version>
  <configuration>
    <showWarnings>true</showWarnings>
    <showDeprecation>true</showDeprecation>
  </configuration>
</plugin>

工具链插件

这或多或少是可选的,但是我强烈建议您使用它。Java 9尚未发布,我们仍在使用Java 8(或Java 7)进行生产项目,并且不舒服地更改所有的环境变量,并将其指向JDK 9的主目录,我们一直想要实验它。 maven-toolchains-plugin使您能够轻松地使用各种环境。

创建$HOME/.m2/toolchains.xml(或 %USERPROFILE%\.m2\toolchains.xml在Windows上),如果你还没有的话。

<toolchains>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>9</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <!-- Change path to JDK9 -->
      <jdkHome>/opt/oracle/jdk-9</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.8</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>/opt/oracle/jdk-1.8.0.65</jdkHome>
    </configuration>
  </toolchain>
</toolchains>

将路径更改为实际的JDK安装。之后,工具链插件可以添加到您的项目中。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-toolchains-plugin</artifactId>
  <version>1.1</version>
  <configuration>
    <toolchains>
  	<jdk>
	    <version>9</version>
	    <vendor>oracle</vendor>
  	</jdk>
    </toolchains>
  </configuration>
  <executions>
    <execution>
	  <goals>
	    <goal>toolchain</goal>
  	</goals>
    </execution>
  </executions>
</plugin>

启用Java 9语言支持

从JDK 9 b72开始,有个新功能将成为可用:javac –release命令行选项。简而言之,要使用javac交叉编译到较旧版本的平台,将设置-source和-target选项设置为较旧的值是不够的; 在bootclasspath也必须设置对应于旧版本了。设置bootclasspath经常被遗忘并获取所需的信息可能不方便。

该--release标志着javac解决了这两个缺点。在交叉编译时仅需要设置单个标志,相比以前需要设置三个标志(source,-target,-bootclasspath)和这样所需要的信息都被包括在JDK。接受的参数值为--release6,7,8和9。

<properties>
  <maven.compiler.release>9</maven.compiler.release>
  <maven.compiler.source>1.9</maven.compiler.source>
  <maven.compiler.target>1.9</maven.compiler.target>
  ...
</properties>

属性 maven.compiler.release直接映射到该--release标志javac,而另外两个属性只对IntelliJ有必要 ,用来了解源码兼容性。

已知的问题

不幸的是,在写作时有测试编译失败。这是由于JDK-8178012引入的一个突破性的改变 ,它删除了-Xmodule编译器标志。希望MCOMPILER-294可以很快得到修复,但同时也可以禁用编译测试源。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>${maven-compiler-plugin.version}</version>
  <!--
    Fix breaking change introduced by JDK-8178012: Finish removal of -Xmodule
    Reference:  http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8178012
  -->
  <executions>
    <execution>
      <id>default-testCompile</id>
      <phase>test-compile</phase>
      <goals>
        <goal>testCompile</goal>
      </goals>
      <configuration>
        <skip>true</skip>
      </configuration>
    </execution>
  </executions>
  <configuration>
    <showWarnings>true</showWarnings>
    <showDeprecation>true</showDeprecation>
  </configuration>
</plugin>
原文:如何在Maven项目中设置Java 9