

# 配置依赖项、连接器、库

每个Flink应用程序都依赖于一组Flink库。至少，应用程序依赖于Flink API。许多应用程序还依赖于某些连接器库(如Kafka、Cassandra等)。在运行Flink应用程序时(无论是在分布式部署中还是在用于测试的IDE中)，Flink运行时库也必须可用。
## Flink核心与应用依赖关系
与大多数运行用户定义应用程序的系统一样，Flink中有两大类依赖关系和库：

*   **Flink核心依赖关系**: Flink本身包括一组运行系统所需的类和依赖关系，例如协调、联网、检查点、故障转移、API、操作（如窗口）、资源管理等。所有这些类和依赖项的集合构成Flink运行时的核心，并且在启动Flink应用程序时必须存在。

    这些核心类和依赖项被打包在 `flink-dist` jar中。它们是Flinks `lib` 文件夹的一部分，也是Flink容器基本图像的一部分。认为这些依赖关系类似于Java的核心库（`rt.jar`、`charset.jar`等）。），其中包含`String`和`List`等类。

    Flink核心依赖项不包含任何连接器或库（CEP、SQL、ML等）为了避免默认情况下类路径中有过多的依赖项和类。事实上，我们试图保持核心依赖项尽可能小，以保持默认类路径的小，并避免依赖冲突。

*   The **用户应用程序依赖项** 是特定用户应用程序需要的所有连接器、格式或库。

    用户应用程序通常打包到 _application jar_ 中，其中包含应用程序代码以及所需的连接器和库依赖项。

    用户应用程序依赖关系显式不包括FlinkDataSet/DataStreamAPI和运行时依赖关系，因为它们已经是Flink的CoreDependencies的一部分。
## 设置项目：基本依赖项

每个Flink应用程序都需要作为API依赖关系的最小值来进行开发。对于Maven，您可以使用[JavaProject Template](//ci.apache.org/projects/flink/flink-docs-release-1.7/dev/projectsetup/java_api_quickstart.html)或[ScalaProject Template](//ci.apache.org/projects/flink/flink-docs-release-1.7/dev/projectsetup/scala_api_quickstart.html)]来创建具有这些初始依赖项的程序框架。

手动设置项目时，您需要为Java/ScalaAPI添加以下依赖项(这里是Maven语法，但同样的依赖项也适用于其他构建工具(Gradle、SBT等)。也是。

<figure class="highlight">

```
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-java</artifactId>
  <version>1.7.1</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-streaming-java_2.11</artifactId>
  <version>1.7.1</version>
  <scope>provided</scope>
</dependency>
```

</figure>

<figure class="highlight">

```
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-scala_2.11</artifactId>
  <version>1.7.1</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.apache.flink</groupId>
  <artifactId>flink-streaming-scala_2.11</artifactId>
  <version>1.7.1</version>
  <scope>provided</scope>
</dependency>
```

</figure>

**重要:** 请注意，所有这些依赖项的作用域都设置为_provided_。这意味着需要它们来编译，但是不应该将它们打包到项目的应用程序jar文件中-这些依赖项是FlinkCore依赖项，这些依赖项在任何设置中都已经可用。

强烈建议将依赖项保持在作用域 _provided_ 中。如果它们不设置为 _provided_ ，最好的情况是结果JAR变得过大，因为它还包含所有Flink核心依赖项。最坏的情况是，添加到应用程序的jar文件中的Flink核心依赖项与您自己的一些依赖版本发生冲突（通常通过倒类加载来避免）。

**关于IntelliJ:** 要使应用程序在IntelliJIDEA中运行，Flink依赖关系需要在 SCOPE_COMPILE__ 而不是 _REVITY_ 中声明。否则，IntelliJ将不会将它们添加到类路径中，使用“NoClassDefFountError”执行in-IDE将失败。为了避免将依赖关系范围声明为_COMPILE_(不建议这样做，见上文)，上面链接的Java和Scala项目模板使用了一个技巧：它们添加了一个配置文件，当应用程序在IntelliJ中运行时有选择地激活它，然后将依赖关系提升到Scope_COMPILE_，而不影响JAR文件的打包。

## 添加连接器和库依赖关系

大多数应用程序需要特定的连接器或库来运行，例如卡夫卡、卡桑德拉等的连接器。这些连接器不是Flink的核心依赖项的一部分，因此必须作为依赖项添加到应用程序中。

下面是一个示例，将Kafka 0.10的连接器添加为依赖项(Maven语法)：

<figure class="highlight">

```
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-kafka-0.10_2.11</artifactId>
    <version>1.7.1</version>
</dependency>
```

</figure>

我们建议将应用程序代码及其所有必需的依赖项打包到一个 _jar-with-dependencies_，我们称之为 _application jar_。应用程序JAR可以提交给已经在运行的Flink集群，也可以添加到Flink应用程序容器映像中。

从[JavaProject Template](//ci.apache.org/projects/flink/flink-docs-release-1.7/dev/projectsetup/java_api_quickstart.html)或[scala项目Template](//ci.apache.org/projects/flink/flink-docs-release-1.7/dev/projectsetup/scala_api_quickstart.html)]创建的项目被配置为在运行 `mvn clean package` 时自动将应用程序依赖项包含到应用程序JAR中。对于没有从这些模板中设置的项目，我们建议添加Maven Shade插件(如下面的附录所示)，以构建具有所有所需依赖项的应用程序JAR。

**重要:** 要使Maven(和其他构建工具)正确地将依赖项打包到应用程序JAR中，这些应用程序依赖项必须在SCOPE_COMPILE_(与核心依赖项不同，必须在Scope_Providing_)中指定)。

## Scala 版本

Scala版本(2.10、2.11、2.12等)不是二进制兼容的。因此，Scala2.11的Flink不能与使用Scala2.12的应用程序一起使用。

依赖于Scala的所有Flink依赖关系都是Suffix的，Scala版本为它们构建，例如`flink-streaming-scala_2.11`。
只有Java的开发人员可以选择任何Scala版本，Scala开发人员需要选择与其应用程序Scala版本匹配的Scala版本。
有关如何为特定Scala版本构建Flink的详细信息，请参阅[Build guide](//ci.apache.org/projects/flink/flink-docs-release-1.7/flinkDev/building.html#scala-versions)]。
**Note:** 由于Scala2.12中的重大中断更改，Flink 1.5目前只为Scala2.11构建。我们的目标是在下一个版本中增加对Scala2.12的支持。

## Hadoop Dependencies

**一般规则：永远不必将Hadoop依赖项直接添加到应用程序中。** _(唯一的例外是在Flink的Hadoop兼容性包装器中使用现有Hadoop输入/输出格式时)_

如果您想在Hadoop中使用Flink，您需要一个包含Hadoop依赖项的Flink设置，而不是将Hadoop作为应用程序依赖项添加。有关详细信息，请参阅[Hadoop设置Guide](//ci.apache.org/projects/flink/flink-docs-release-1.7/ops/deployment/hadoop.html)]。
这种设计有两个主要原因：
*  一些Hadoop交互发生在Flink的核心中，可能是在用户应用程序启动之前，例如为检查点设置HDFS、通过Hadoop的Kerberos令牌进行身份验证或在纱线上部署。
*   Flink的反向类加载方法从核心依赖项中隐藏了许多传递依赖项。这不仅适用于Flink自己的核心依赖项，而且也适用于Hadoop在安装过程中的依赖关系。这样，应用程序可以使用相同依赖项的不同版本，而不会遇到依赖冲突(相信我们，这很重要，因为Hadoops依赖树很大)。
如果在IDE内部测试或开发过程中需要Hadoop依赖项(例如，对于HDFS访问)，请将这些依赖项配置为与依赖关系范围类似的 _test_ 或 _Providing_ 。
## 附录：用依赖关系构建JAR的模板
要构建包含声明的连接器和库所需的所有依赖项的应用程序JAR，可以使用以下阴影插件定义：
<figure class="highlight">

```
<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-shade-plugin</artifactId>
			<version>3.0.0</version>
			<executions>
				<execution>
					<phase>package</phase>
					<goals>
						<goal>shade</goal>
					</goals>
					<configuration>
						<artifactSet>
							<excludes>
								<exclude>com.google.code.findbugs:jsr305</exclude>
								<exclude>org.slf4j:*</exclude>
								<exclude>log4j:*</exclude>
							</excludes>
						</artifactSet>
						<filters>
							<filter>
								<!-- Do not copy the signatures in the META-INF folder.
								Otherwise, this might cause SecurityExceptions when using the JAR. -->
								<artifact>*:*</artifact>
								<excludes>
									<exclude>META-INF/*.SF</exclude>
									<exclude>META-INF/*.DSA</exclude>
									<exclude>META-INF/*.RSA</exclude>
								</excludes>
							</filter>
						</filters>
						<transformers>
							<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
								<mainClass>my.programs.main.clazz</mainClass>
							</transformer>
						</transformers>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>
```

</figure>

