运行使用maven构建的jar时,FlinkMLTools NoClassDef

Ker*_*ial 4 jar noclassdeffounderror maven apache-flink flinkml

我正在使用Apache Flink开发推荐系统.当我在IntelliJ中测试它时,实现正在运行,但我现在想要进入集群.我还构建了一个jar文件并在本地测试它,看看是否一切正常但我遇到了问题.

java.lang.NoClassDefFoundError:org/apache/flink/ml/common/FlinkMLTools $

我们可以看到,FlinkMLTools在运行jar时没有找到我的代码中使用的类.我使用Maven 3.3.3构建了这个jar,mvn clean install我正在使用Flink的0.9.0版本.

第一道

事实是我的全球项目包含其他项目(这个推荐人是子项目之一).这样,我必须mvn clean install在正确的项目的文件夹中启动,否则Maven总是构建一个其他项目的jar(我不明白为什么).所以我想知道是否有办法明确地说maven来构建一个全球项目的特定项目.实际上,也许路径FlinkMLTools包含在pom.xml全球项目文件中的链接中.

还有其他想法吗?

Til*_*ann 5

问题是Flink的二进制发行版不包含库(flink-ml,gelly等).这意味着您必须将库jar文件与您的作业jar一起发送,或者您必须手动将它们复制到您的集群.我强烈推荐第一个选项.

建造一个包含库罐的胖罐

构建不包含不必要的罐子的胖罐子的最简单方法是使用Flink的快速启动原型来设置项目的pom.

mvn archetype:generate -DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-scala -DarchetypeVersion=0.9.0 
Run Code Online (Sandbox Code Playgroud)

将使用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>
Run Code Online (Sandbox Code Playgroud)

您可以删除flink-streaming-scala并插入以下依赖项标记,以包含Flink的机器学习库.

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-ml</artifactId>
    <version>0.9.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

当您知道构建作业jar时mvn package,生成的jar应该包含flink-mljar及其所有传递依赖项.

将库jar手动复制到群集

Flink包括位于<FLINK_ROOT_DIR>/lib已执行作业的类路径中的文件夹中的所有jar .因此,为了使用Flink的机器学习库,您必须将flink-mljar和所有需要的传递依赖项放入该/lib文件夹中.这是相当棘手的,因为你必须弄清楚算法实际需要哪些传递依赖,因此,你最终会复制所有传递依赖.

如何使用maven构建特定的子模块

要从父项目构建特定的子模块X,可以使用以下命令:

 mvn clean package -pl X -am
Run Code Online (Sandbox Code Playgroud)

-pl允许您指定要构建的子模块,并-am告诉maven还构建其他所需的子模块.这里也有描述.