If Maven is completely new to you, read:

Apache Maven 是一款 convention over configuration 构建自动化工具。
ImageJ、ImageJ2、Fiji和其他基于SciJava的项目使用Maven作为其项目基础设施。
Maven 工件发布到 Maven Central 或 SciJava Maven repository。
为什么我们使用 Maven?
- 我们需要一些东西来获取源代码并将其打包成可用的格式,即 jar 文件。
- Maven 为我们组织依赖关系,声明这些依赖关系……而不是手动跟踪每个单独的拼图。
- Maven 是所有开发人员的中央存储位置,为许多人提供相同的工具。
- Maven 有一个既定的不可变发布和开发版本控制概念——这两者对于可重复的科学都是至关重要的。
简介
Maven 是构建 Java 项目并管理其依赖项的强大工具。它可以从源构建依赖项,但如果源不可用,它将查找 Maven 存储库以从中下载依赖项。
示例:假设您想要为 ImageJ 构建一个新插件,该插件基于 3D Viewer 和 commons-math 等构建。您不想从头开始重建它们,除非您需要调试上述组件中可疑的错误。这就是 Maven 的用武之地:你告诉它依赖项是 ImageJ、3D Viewer 和 commons-math 以及你需要什么版本。 Maven 的工作就是找到并获取它们,无论您是否在本地构建它们。
许多方便的IDEs(集成开发环境)包括Eclipse、NetBeans和IntelliJ支持Maven项目;因此,当试图让每个开发人员选择自己喜欢的开发环境时,使用 Maven 是一个很好的选择。
创建一个新的 Maven 项目需要什么?
POM和目录结构
它真正需要的只是一个 pom.xml 文件和特定的目录结构:
pom.xml
src/
main/
java/
<package>/
<name>.java
...
resources/
<other-files>
...
从技术上讲,您可以覆盖pom.xml中的默认目录布局,但为什么要这样做呢?它只会打破期望,并且比它的价值更麻烦,真的。
因此目录结构是:将 .java 文件放在 src/main/java/ 下,将需要包含的其他文件放在 src/main/resources/ 下。如果您想应用称为“回归测试”甚至“测试驱动开发”的最佳实践:您的测试的.java文件将转到src/test/java/,而您可能需要的非.java文件毫不奇怪地会进入src/test/resources/。
那么pom.xml是什么样子的呢?这是一个非常简单的例子:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.mywebsite</groupId>
<artifactId>my-uber-library</artifactId>
<version>2.0.0-SNAPSHOT</version>
</project>
前 6 行当然只是表达“嗨,Maven?你今天好吗?这就是我希望你做的……”。
唯一相关的部分是 groupId,按照惯例,它类似于反向域名(类似于 Java 包约定)、要构建的工件的名称(它将被放入 target/ 中,名称为 <artifactId>-<version>.jar)。当然还有版本。
依赖关系
Maven不仅是一个构建工具,也是一个依赖管理工具。
要依赖另一个库,您必须在项目的 pom.xml 文件中声明依赖项。例如,每个 ImageJ 插件都依赖于 ImageJ。因此,让我们添加(在最后 </project> 行之前):
<dependencies>
<dependency>
<groupId>net.imagej</groupId>
<artifactId>ij</artifactId>
<version>1.45b</version>
</dependency>
</dependencies>
正如您所看到的,依赖项是使用您为项目本身声明的相同的 groupId、artifactId 和 version 三元组(也称为 GAV 参数)来引用的。
存储库
一旦声明了依赖项,Maven 就会根据需要从 Internet 下载它们。然而,为了让 Maven 找到依赖项,它必须知道去哪里寻找。
开箱即用,Maven 将查看所谓的 Maven Central repository。一些 ImageJ 和 SciJava 组件部署在那里,包括声明重要元数据的 pom-scijava parent POM,例如 Bill of Materials:旨在协同工作的当前工件版本。
然而,许多其他 SciJava 和 ImageJ 组件尚未部署到 Maven Central,而是部署到 SciJava Maven repository。要从您的项目访问此存储库,请将以下配置块添加到您的pom.xml中:
<repositories>
<repository>
<id>scijava.public</id>
<url>https://maven.scijava.org/content/groups/public</url>
</repository>
</repositories>
根据经验:组件versioned at 0.x部署到 SciJava Maven 存储库,而 1.x 或更高版本的组件部署到 Maven Central。
发布和快照
有两种不同类型的 Maven 工件(即 JAR 文件):版本和快照。快照版本是“正在进行的”版本。如果您在版本中声明带有 -SNAPSHOT 后缀的依赖项,Maven 将每天查找一次相同版本的新工件;否则,Maven 会查看是否已有该版本,而不会重新下载。
生成多个 JAR 文件
那么,如果您想在同一个项目中构建多个 .jar 文件怎么办?然后,这些需要位于它们自己的子目录中,并且需要有一个共同的父 POM,即所谓的聚合器 或多模块 POM(当然,只有这个 POM 需要将 SciJava POM 作为父项)。 Here is an example。基本上,它会在顶部添加 <packaging>pom</packaging> 条目,并将一些子目录名称添加到 <modules> 部分。
但请注意,SciJava component collection 的大多数项目(例如,SciJava、ImgLib2、SCIFIO、ImageJ2 和 Fiji)现在将每个组件构建为自己的 Git 存储库中自己的单模块项目,因为使用多模块项目会使版本控制变得复杂。
约定优于配置
您还可以使用 Maven 做更多事情,但很可能您不需要它们。
您需要的 pom.xml 的简单性来自于 Maven 定义隐式默认值的事实。它称之为“约定优于配置”。由于多种原因,强烈建议尽可能保留默认值。
在 SciJava 的上下文中,您很可能永远不会从头开始编写 pom.xml。您更有可能编辑现有的,可能是在复制它之后。我们建议使用 ImageJ “Load and Display a Dataset” tutorial 作为起点。
如何查找依赖项的 groupId/artifactId/version (GAV)?
您可能想要依赖的最流行的开源库存储在Maven Central repository中。但是,ImageJ 和 Fiji JAR 尚未存储在那里,而是存储在 SciJava Maven repository 中。幸运的是,您可以通过访问以下内容同时搜索两者:
例如,假设您想要依赖 snakeyaml 库。在 maven.scijava.org 的搜索框中输入“snakeyaml”会告诉我们使用 org.yaml 的 groupId、snakeyaml 的 artifactId,可用版本范围从 1.4 到 1.10。如果有很多结果,您可以单击“向下钻取”链接以查看该特定 GAV 组合的更多详细信息。您还可以单击一个条目来获取格式化的 dependency 块,以便直接复制粘贴到您的 POM 中。
If your dependencies are in Maven Central, you can use the quickdeps tool to quickly generate dependency blocks, by scanning your project’s bytecode.
依赖于核心存储库之外的库
如果您需要依赖 Maven Central 或 SciJava Maven 存储库中不存在的库,请首先仔细检查项目的网站,以获取有关在 Maven 中使用其库的任何文档。他们可能会提供自己的公共 Maven 存储库,您可以使用它(按照 adding a <repository> to the <repositories> section of your POM)。
如果没有包含您的依赖项的公共存储库,您有两个选择:
-
如果依赖项本身就是 ImageJ 插件,请考虑contributing it to Fiji。与斐济分发的插件是made available as Maven artifacts,因此将使用户和开发人员受益。
-
如果依赖关系的范围较窄,您可以contact the ImageJ & Fiji maintainers将所需的依赖关系添加到 SciJava Maven 存储库中。请注意,您将负责用您的代码分发依赖关系,因此请确保它是licensed appropriately。
最后,对于本地测试,您可以install the dependency into your local Maven repository cache yourself。命令是mvn install:install-file。例如,如果您要安装库 foo.jar,您可以运行:
mvn install:install-file -Dfile=/path/to/foo.jar -DgroupId=org.foo -DartifactId=foo -Dversion=1.0.0 -Dpackaging=jar
对于groupId,通常最好使用图书馆网站的反向域名。对于没有明确版本控制的库,您可能需要使用日期戳(例如“20120920”)作为 version,而不是发明自己的版本控制方案。
If you use install:install-file, others will not be able to build your code unless they also use install:install-file to install the library on their systems.
如有疑问,请contact the community提出您的问题。