FlinkMLTools NoClassDef при запуске jar, созданной с помощью Maven

Я работаю над системой рекомендаций, используя Apache Flink. Реализация работает, когда я тестирую ее в IntelliJ, но я бы хотел сейчас перейти на кластер. Я также собрал jar-файл и протестировал его локально, чтобы увидеть, все ли работает, но я столкнулся с проблемой.

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

Как мы видим, класс FlinkMLTools используемый в моем коде не найден во время работы банки. Я построил эту банку с Maven 3.3.3 с mvn clean install и я использую версию 0.9.0 Flink.

Первый Тропа

Дело в том, что мой глобальный проект содержит другие проекты (и этот рекомендатель является одним из подпроектов). Таким образом, я должен запустить mvn clean install в папке нужного проекта, в противном случае Maven всегда создает банку другого проекта (и я не понимаю, почему). Поэтому мне интересно, может ли быть способ явно сказать maven для создания одного конкретного проекта глобального проекта. Действительно, возможно, путь к FlinkMLTools содержится в ссылке, представленной в pom.xml файл глобального проекта.

Есть другие идеи?

2 ответа

Решение

Проблема в том, что бинарный дистрибутив Flink не содержит библиотек (flink-ml, gelly и т. Д.). Это означает, что вам необходимо либо отправить файлы библиотеки JAR вместе с файлом JAR, либо скопировать их вручную в кластер. Я настоятельно рекомендую первый вариант.

Создание фляги, чтобы включить фляги библиотеки

Самый простой способ создать толстый флягу, которая не содержит ненужных фляг, состоит в том, чтобы использовать архетип быстрого запуска Флинка, чтобы настроить pom проекта.

mvn archetype:generate -DarchetypeGroupId=org.apache.flink \
-DarchetypeArtifactId=flink-quickstart-scala -DarchetypeVersion=0.9.0 

создаст структуру для проекта Flink, используя Scala API. Сгенерированный файл 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 и вместо этого вы вставляете следующий тег зависимости, чтобы включить библиотеку машинного обучения Флинка.

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-ml</artifactId>
    <version>0.9.0</version>
</dependency>

Когда вы знаете, построить банку с mvn packageсгенерированная банка должна содержать flink-ml кувшин и все его переходные зависимости.

Копирование библиотечных банок вручную в кластер

Flink включает в себя все банки, которые расположены в <FLINK_ROOT_DIR>/lib папка в classpath выполненных заданий. Таким образом, чтобы использовать библиотеку машинного обучения Флинка, вы должны поставить flink-ml банку и все необходимые переходные зависимости в /lib папка. Это довольно сложно, поскольку вы должны выяснить, какие транзитивные зависимости на самом деле нужны вашему алгоритму, и, следовательно, вам часто придется копировать все транзитивные зависимости.

Как построить конкретный субмодуль с Maven

Чтобы построить конкретный подмодуль X из вашего родительского проекта, вы можете использовать следующую команду:

 mvn clean package -pl X -am

-pl позволяет указать, какие подмодули вы хотите построить и -am говорит maven также собирать другие необходимые подмодули. Это также описано здесь.

В кластерном режиме Flink не помещает все JAR-файлы библиотеки в путь классов своих рабочих. При локальном выполнении программы в IntelliJ все необходимые зависимости находятся в пути к классам, но не при выполнении в кластере.

У вас есть два варианта:

  1. скопируйте файл FlinkML Jar в lib папка всех Flink TaskManager
  2. Создайте толстый файл Jar для своего приложения, который включает в себя зависимости FLinkML.

Подробности смотрите в документации по выполнению кластера.

Другие вопросы по тегам