我知道编辑这个网站吗?

梅文

If Maven is completely new to you, read:

icons/maven

Apache Maven 是一款 convention over configuration 构建自动化工具。

ImageJImageJ2Fiji和其他基于SciJava的项目使用Maven作为其项目基础设施。

Maven 工件发布到 Maven CentralSciJava Maven repository

为什么我们使用 Maven?

  • 我们需要一些东西来获取源代码并将其打包成可用的格式, jar 文件。
  • Maven 为我们组织依赖关系,声明这些依赖关系……而不是手动跟踪每个单独的拼图。
  • Maven 是所有开发人员的中央存储位置,为许多人提供相同的工具。
  • Maven 有一个既定的不可变发布和开发版本控制概念——这两者对于可重复的科学都是至关重要的。

简介

Maven 是构建 Java 项目并管理其依赖项的强大工具。它可以从源构建依赖项,但如果源不可用,它将查找 Maven 存储库以从中下载依赖项。

示例:假设您想要为 ImageJ 构建一个新插件,该插件基于 3D Viewer 和 commons-math 等构建。您不想从头开始重建它们,除非您需要调试上述组件中可疑的错误。这就是 Maven 的用武之地:你告诉它依赖项是 ImageJ、3D Viewer 和 commons-math 以及你需要什么版本。 Maven 的工作就是找到并获取它们,无论您是否在本地构建它们。

许多方便的IDEs(集成开发环境)包括EclipseNetBeansIntelliJ支持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>

正如您所看到的,依赖项是使用您为项目本身声明的相同的 groupIdartifactIdversion 三元组(也称为 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 的大多数项目(例如,SciJavaImgLib2SCIFIOImageJ2Fiji)现在将每个组件构建为自己的 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 中。幸运的是,您可以通过访问以下内容同时搜索两者:

https://maven.scijava.org/

例如,假设您想要依赖 snakeyaml 库。在 maven.scijava.org 的搜索框中输入“snakeyaml”会告诉我们使用 org.yamlgroupIdsnakeyamlartifactId,可用版本范围从 1.41.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)。

如果没有包含您的依赖项的公共存储库,您有两个选择:

最后,对于本地测试,您可以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提出您的问题。

进一步阅读