

# 配置依赖关系，连接器，库

> 译者：[flink.sojb.cn](https://flink.sojb.cn/)


每个Flink应用程序都依赖于一组Flink库。至少，应用程序依赖于Flink API。许多应用程序还依赖于某些连接器库（如Kafka，Cassandra等）。运行Flink应用程序时（在分布式部署中或在IDE中进行测试），Flink运行时库也必须可用。

## Flink核心和应用程序依赖项

与大多数运行用户定义应用程序的系统一样，Flink中有两大类依赖项和库：

*   **Flink核心依赖关系**：Flink本身由运行系统所需的一组类和依赖项组成，例如协调，网络，检查点，故障转移，API， 算子操作（如窗口），资源管理等。这些类和依赖项构成了Flink运行时的核心，在启动Flink应用程序时必须存在。

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

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

*   所述**用户应用程序的依赖关系**是所有的连接器，格式或库，一个特定的用户应用需求。

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

    用户应用程序依赖项显式不包括Flink DataSet / DataStream API和运行时依赖项，因为它们已经是Flink核心依赖项的一部分。

## 设置项目：基本依赖项

每个Flink应用程序都需要最低限度的API依赖关系来进行开发。对于Maven，您可以使用[Java项目模板](https://flink.sojb.cn/dev/projectsetup/java_api_quickstart.html) 或[Scala项目模板](https://flink.sojb.cn/dev/projectsetup/scala_api_quickstart.html)来创建具有这些初始依赖项的程序框架。

手动设置项目时，需要为Java / Scala API添加以下依赖项（此处以Maven语法显示，但相同的依赖项也适用于其他构建工具（Gradle，SBT等）。

*   [**Java**](#tab_java_0)
*   [**Scala**](#tab_scala_0)



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





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



**重要提示：**请注意，所有这些依赖项都将其范围设置为_提供_。这意味着需要对它们进行编译，但不应将它们打包到项目生成的应用程序jar文件中 - 这些依赖项是Flink Core Dependencies，它们已在任何设置中提供。

强烈建议将依赖关系保持在_提供的_范围内。如果它们未设置为_提供_，则最好的情况是生成的JAR变得过大，因为它还包含所有Flink核心依赖项。最糟糕的情况是添加到应用程序的jar文件的Flink核心依赖项与您自己的一些依赖版本冲突（通常通过反向类加载来避免）。

**关于IntelliJ的注意事项：**要使应用程序在IntelliJ IDEA中运行，需要在范围_编译中_声明Flink依赖项，而不是_提供_。否则，IntelliJ不会将它们添加到类路径中，并且in-IDE执行将失败并带有`NoClassDefFountError`。为了避免必须将依赖范围声明为_compile_（不推荐使用，请参见上文），上面链接的Java和Scala项目模板使用了一个技巧：它们添加了一个配置文件，该应用程序在IntelliJ中运行时有选择地激活在不影响JAR文件打包的情况下，将依赖关系提升到范围_编译_。

## 添加连接器和库依赖项

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

下面是将Kafka 0.10的连接器添加为依赖项（Maven语法）的示例：



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



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

从[Java项目模板](https://flink.sojb.cn/dev/projectsetup/java_api_quickstart.html)或 [Scala项目模板](https://flink.sojb.cn/dev/projectsetup/scala_api_quickstart.html)创建的[项目](https://flink.sojb.cn/dev/projectsetup/java_api_quickstart.html)配置为在运行时自动将应用程序依赖项包含到应用程序jar中`mvn clean package`。对于未从这些模板设置的项目，我们建议添加Maven Shade插件（如下面的附录中所列）以构建具有所有必需依赖项的应用程序jar。

**重要：**对于Maven（和其他构建工具）将依赖项正确打包到应用程序jar中，必须在范围_编译中_指定这些应用程序依赖项（与核心依赖项不同，核心依赖项必须在_提供的_作用域中指定）。

## Scala版本

Scala版本（2.10,2.11,2.12等）彼此不是二进制兼容的。因此，Fala for Scala 2.11不能与使用Scala 2.12的应用程序一起使用。

例如，所有（传递上）依赖于Scala的Flink依赖项都以它们为其构建的Scala版本为后缀`flink-streaming-scala_2.11`。

只使用Java开发人员可以选择任何Scala版本，Scala开发人员需要选择与其应用程序的Scala版本匹配的Scala版本。

有关如何为特定Scala版本构建Flink的详细信息，请参阅[构建指南](https://flink.sojb.cn/flinkdev/building.html#scala-versions)。

**注意：**由于Scala 2.12中的重大更改，Flink 1.5目前仅针对Scala 2.11构建。我们的目标是在下一版本中添加对Scala 2.12的支持。

## Hadoop依赖项

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

如果要将Flink与Hadoop一起使用，则需要具有包含Hadoop依赖关系的Flink设置，而不是将Hadoop添加为应用程序依赖关系。 有关详细信息，请参阅[Hadoop设置指南](https://flink.sojb.cn/ops/deployment/hadoop.html)。

该设计有两个主要原因：

*   一些Hadoop交互发生在Flink的核心，可能在用户应用程序启动之前，例如为检查点设置HDFS，通过Hadoop的Kerberos令牌进行身份验证或在YARN上部署。

*   Flink的反向类加载方法隐藏了核心依赖关系中的许多传递依赖关系。这不仅适用于Flink自己的核心依赖项，也适用于Hadoop在设置中存在的依赖项。这样，应用程序可以使用相同依赖项的不同版本，而不会遇到依赖冲突（并且相信我们，这是一个大问题，因为Hadoops依赖树很大。）

如果在IDE内部的测试或开发过程中需要Hadoop依赖关系（例如，用于HDFS访问），请配置这些依赖关系，类似于要_测试_或_提供_的依赖关系的范围。

## 附录：用于构建具有依赖关系的Jar的模板

要构建包含声明的连接器和库所需的所有依赖项的应用程序JAR，可以使用以下shade插件定义：



```
<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>
```



