我正在使用Apache Flink开发推荐系统。当我在IntelliJ中测试它时,实现正在运行,但我现在想要进入集群。我还构建了一个jar文件并在本地测试它以查看是否一切正常但我遇到了问题。
java.lang.NoClassDefFoundError:org / apache / flink / ml / common / FlinkMLTools $
正如我们所看到的,在运行jar时找不到我的代码中使用的类FlinkMLTools
。
我使用Maven 3.3.3和mvn clean install
构建了这个jar,我使用的是Flink的0.9.0版本。
First Trail
事实是我的全球项目包含其他项目(这个推荐人是子项目之一)。这样,我必须在正确项目的文件夹中启动mvn clean install
,否则Maven总是构建一个其他项目的jar(我不明白为什么)。所以我想知道是否有办法明确地说maven来构建一个全球项目的特定项目。实际上,FlinkMLTools
的路径可能包含在全球项目的pom.xml
文件中的链接中。
还有其他想法吗?
答案 0 :(得分:5)
问题是Flink的二进制发行版不包含库(flink-ml,gelly等)。这意味着您必须将库jar文件与您的作业jar一起发送,或者您必须手动将它们复制到您的集群。我强烈推荐第一个选项。
制作不含不必要罐子的胖罐的最简单方法是使用Flink的快速启动原型来设置项目的pom。
mvn archetype:generate -DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-scala -DarchetypeVersion=0.9.0
将使用Scala API为Flink项目创建结构。生成的pom文件将具有以下依赖项。
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients</artifactId>
<version>0.9.0</version>
</dependency>
</dependencies>
您可以删除flink-streaming-scala
,而是插入以下依赖标记,以便包含Flink的机器学习库。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-ml</artifactId>
<version>0.9.0</version>
</dependency>
当您知道使用mvn package
构建作业jar时,生成的jar应包含flink-ml
jar及其所有传递依赖项。
Flink包含位于已执行作业的类路径中的<FLINK_ROOT_DIR>/lib
文件夹中的所有jar。因此,为了使用Flink的机器学习库,您必须将flink-ml
jar和所有需要的传递依赖放入/lib
文件夹。这是相当棘手的,因为你必须弄清楚你的算法实际需要哪些传递依赖,因此,你最终会复制所有传递依赖。
要从父项目构建特定的子模块X,您可以使用以下命令:
mvn clean package -pl X -am
-pl
允许您指定要构建的子模块,-am
告诉maven还构建其他所需的子模块。它还描述了here。
答案 1 :(得分:3)
在群集模式下,Flink不会将所有库JAR文件放入其worker的类路径中。在IntelliJ中本地执行程序时,所有必需的依赖项都在类路径中,但在集群上执行时则不行。
您有两种选择:
lib
文件夹有关详细信息,请参阅Cluster Execution Documentation。