10.2 Apache Maven
JVM Kotlin开发人员通常使用JVM和Java领域常用的构建工具,其中的两个是Gradle 公司出品的Gradle和Apache Software Foundation出品的Maven,它们都能够管理依赖和构建项目。考虑到第4章开发小型Java应用程序时使用过Gradle,本章将使用Apache Maven。
Maven使用XML构建文件来构建项目,并严格地遵守“约定优先于配置”的范式。只要你遵守Maven的约定,就无需频繁地修改构建文件,但如果你想冲破藩篱,在构建项目中使用自定义动作,情况可能非常复杂甚至麻烦不断。大多数流行的插件都会在构建过程中添加新的功能或操作,但要找到满足需求的插件可能很难。就Kotlin开发而言,必须添加Kotlin Maven插件,让Maven知道如何编译Kotlin代码。
Eclipse IDE Kotlin插件不支持从GUI创建基于Maven的项目,但由于Eclipse IDE本身支持Maven,因此可手动创建一个项目,再将其导入到Eclipse IDE中。本节介绍如下主题:
- 安装Apache Maven;
- 下载预制的Kotlin基本套件(starter kit);
- 在Eclipse IDE中导入项目。
10.2.1 安装Apache Maven
鉴于基于JVM的既有项目大量地使用了Maven,因此志向远大的JVM开发人员最好安装这个工具,而不管以后是否在Kotlin项目中使用它。有关Maven的更详细信息,请参阅其主页http://maven.apache.org。
Maven的安装步骤与本书介绍的其他JVM工具很像。
(1) 访问Maven的项目主页以下载Maven。在这个主页的Download部分,从列表中找到附近的下载镜像,并下载最新的版本。编写本书期间,最新版本为3.5.0。Windows用户应下载ZIP文件(编写本书期间,这个文件名为apache-maven-3.5.0-bin.zip),而Linux和macOS用户应下载tar.gz归档文件(编写本书期间,这个文件名为apache-maven-3.5.0-bin.tar.gz)。
(2) 在你的系统中,将下载的归档文件解压缩到一个方便的目录中。
(3) 将其中的目录bin添加到环境变量Path中。
为了检查安装情况,在命令提示符(Windows)或终端窗口(macOS和Linux)中输入mvn --help并按回车,控制台窗口将出现一个长长的选项列表:

10.2.2 下载预制的Kotlin基本套件
Kotlin开发小组提供了一个基本套件,其中包含一个可使用Gradle或Maven进行构建的项目。你可从Kotin小组的官方GitHub仓库下载这个基本套件:https://github.com/JetBrains/kotlin-examples。
通过使用你喜欢的浏览器访问这个GitHub页面,并单击Clone or download按钮,可下载一个ZIP文件,其中包含该仓库主分支的最新版本。请将这个文件解压缩到Eclipse workspace目录中。

如果你安装了Git,也可检出这个文件,方法是在命令提示符或终端窗口中切换到Eclipse的workspace目录,再执行命令
git clone。
下面通过编译并运行这个项目来检查Maven的安装情况。在命令提示符(Windows)或终端窗口(macOS和Linux)中,切换到目录kotlin-examples/maven/hello-world,并执行如下命令:
mvn compile
这将启动Maven并执行构建文件中的compile目标(goal)。Maven将下载编译这个项目所需的依赖项(其中包括Kotlin Maven插件),开始编译项目源代码文件,并指出成功地完成了这个任务。在这个过程中,Maven创建了一个target目录,该目录包含子目录classes,而这个子目录包含编译得到的类文件。
Maven基本套件中的构建文件经过了配置,使得使用Maven也可启动它。为了运行这个项目,请执行如下命令:
mvn exec:java
虽然这是一个Kotlin项目,但也可使用Maven的默认执行任务java,因为普通JVM命令java用于启动应用程序:

除Maven的输出外,你还应看到问候语“Hello, World”。
10.2.3 在Eclipse IDE中导入项目
在JVM领域,Maven可谓家喻户晓,因此所有的Java版Eclipse IDE本身都支持Maven。因此,在Eclipse IDE中导入这个项目易如反掌。
(1) 在Eclipse IDE中,右击Package Explorer的空白区域并选择Import…。
(2) 在出现的Import对话框中,选择Projects from Folder or Archive并单击Next按钮。
(3) 单击文本框Import Source旁边的Directory按钮,切换到Eclipse的workspace目录(通常在你的用户主目录中),找到目录kotlin-examples-master并切换到其子目录maven,再选择目录hello-world并单击OK按钮。
(4) 最后,单击Finish按钮导入这个项目。
由于Eclipse IDE熟知Maven指定的约定,因此能够妥善地导入项目,并将最重要的Maven任务映射到正确的GUI元素。下面来核实它是否像期望的那样工作。在Package Explorer中,展开项目hello-world,并打开目录src/main/kotlin中的文件Hello.kt。将问候语“Hello, world!”修改为其他内容,将文件存盘,再单击工具栏中工具提示为“Run Hello.kt”的按钮:

你将在Eclipse的Console选项卡中看到修改后的消息,这说明Eclipse IDE能够编译文件Hello.kt并运行其中的函数main()。
10.2.4 探索构建文件pom.xml
接着往下介绍前,先来看看Maven构建文件——通常名为pom.xml。在Package Explorer中,打开项目hello-world的文件pom.xml。默认将显示一个概述(overview)页面,但我们要查看的是XML文件本身,因此请单击概述页面所在窗口底部的标签pom.xml,这将显示原始XML文件:

POM是Project Object Model(项目对象模型)的首字母缩写。从Maven 2开始,使用的就是POM文件格式的最新版4.0.0。
下面来讨论这个文件中的一些重要元素。
<projectxsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">...</project>
这是POM的根节点。前面说过,最新的POM版本为4.0.0。
<groupId>org.jetbrains.kotlin.examples</groupId><artifactId>hello-world</artifactId><version>1.0-SNAPSHOT</version>
groupId应为标识项目的字符串,它必须遵守JVM包名约定。artifactId指出了创建的JAR文件的文件名,但不包含版本号。版本是使用version元素定义的。
<properties><kotlin.version>1.0.3</kotlin.version><junit.version>4.12</junit.version><main.class>hello.HelloKt</main.class><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
属性为键-值对,其中键是由元素名定义的,而值由内容定义。根据约定,以属性的方式定义依赖项的版本号,这样更新版本时只需修改一个属性,而无需查找并替换多个XML元素。
<dependencies><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-stdlib</artifactId><version>${kotlin.version}</version></dependency>...</dependencies>
元素内的元素定义了项目的各个依赖项,其中一个依赖项是Kotlin标准库(kotlin-stdlib),它使用属性kotlin.version来指定版本。
<build><sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory><testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory><plugin><artifactId>kotlin-maven-plugin</artifactId><groupId>org.jetbrains.kotlin</groupId><version>${kotlin.version}</version>...</plugin>...</build>
这个构建文件的大部分内容都位于标签和之间,其中定义了多个插件,这里显示的是插件kotlin-maven-plugin,它让Maven能够支持Kotlin。Maven包含多个阶段(phase),而每个Maven插件都可修改阶段以及定义目标。
目标是在从命令行执行命令mvn时指定的;例如,当你从命令行运行命令mvn compile时,指定的目标为compile。
10.2.5 在Eclipse中更新构建文件
编写本书期间,Kotlin 1.1已经推出,但这个基本套件指定的Kotlin版本为1.0.3。为了修改Kotlin版本,我将属性kotlin.version的值从1.0.3改为1.1.0:
<properties><kotlin.version>1.1.0</kotlin.version>...</properties>
默认情况下,Kotlin编译器编译得到的是Java 1.6字节码,因此推荐添加下面的属性,让编译器生成更高效的Java字节码:
<properties><kotlin.version>1.1.0</kotlin.version><kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>...</properties>
Eclipse IDE存在的一个问题是,如果在Maven构建文件中没有显式地指定Java编译器,它将默认使用Java 1.5编译器。由于我们的项目将使用这个Java编译器,因此这其实不是问题。
不幸的是,这意味着在开发这个项目的过程中,对于主项目和测试资源,Problem选项卡中将显示警告“Build path specifies execution environment J2SE-1.5…”。
编辑文件pom.xml后,必须让Eclipse刷新项目。为此,可右击项目名,并选择Maven>Update Project,再在出现的对话框中单击OK按钮。
