启动期间的 Apache NiFi 自定义 NAR NoClassDefFoundError

Posted

技术标签:

【中文标题】启动期间的 Apache NiFi 自定义 NAR NoClassDefFoundError【英文标题】:Apache NiFi Custom NAR NoClassDefFoundError During Startup 【发布时间】:2019-07-24 14:23:37 【问题描述】:

我正在尝试在我的 NiFi 安装中安装自定义 NAR 控制器服务包,但在启动期间出现此错误。它的行为就像它无法从 nifi-record-serialization-service-api 中找到 RecordReaderFactory 类,即使它作为依赖项包含在内:

<dependency>
   <groupId>org.apache.nifi</groupId>
   <artifactId>nifi-record-serialization-service-api</artifactId>
   <version>1.9.0</version>
</dependency>

这里是项目: https://github.com/adamfisher/nifi-zonefile-record-serialization-service

运行 maven install 成功构建 NAR。就在我启动 NiFi 时,它给出了这个错误。我很确定这是一个 Maven POM 配置问题。我只是不太会使用 Java,希望有人能解释一下为什么它没有找到所需的依赖类?

nifi-app.log:

2019-03-02 15:22:15,245 INFO [main] org.apache.nifi.web.server.JettyServer Loading WAR: D:\nifi\NIFI-1~2.0\.\work\nar\framework\nifi-framework-nar-1.9.0.nar-unpacked\NAR-INF\bundled-dependencies\nifi-web-error-1.9.0.war with context path set to /
2019-03-02 15:22:15,261 INFO [main] org.apache.nifi.web.server.JettyServer Running in HTTP mode; host headers not restricted
2019-03-02 15:22:16,386 ERROR [main] org.apache.nifi.NiFi Failure to launch NiFi due to java.lang.NoClassDefFoundError: org/apache/nifi/serialization/RecordReaderFactory
java.lang.NoClassDefFoundError: org/apache/nifi/serialization/RecordReaderFactory
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:370)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.apache.nifi.nar.StandardExtensionDiscoveringManager.loadExtensions(StandardExtensionDiscoveringManager.java:152)
    at org.apache.nifi.nar.StandardExtensionDiscoveringManager.discoverExtensions(StandardExtensionDiscoveringManager.java:127)
    at org.apache.nifi.nar.StandardExtensionDiscoveringManager.discoverExtensions(StandardExtensionDiscoveringManager.java:113)
    at org.apache.nifi.web.server.JettyServer.start(JettyServer.java:925)
    at org.apache.nifi.NiFi.<init>(NiFi.java:158)
    at org.apache.nifi.NiFi.<init>(NiFi.java:72)
    at org.apache.nifi.NiFi.main(NiFi.java:297)
Caused by: java.lang.ClassNotFoundException: org.apache.nifi.serialization.RecordReaderFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 23 common frames omitted
2019-03-02 15:22:16,387 INFO [Thread-1] org.apache.nifi.NiFi Initiating shutdown of Jetty web server...
2019-03-02 15:22:16,387 INFO [Thread-1] org.apache.nifi.NiFi Jetty web server shutdown completed (nicely or otherwise).

【问题讨论】:

【参考方案1】:

NAR 依赖项在运行时用于创建父类加载器链。所以在你的例子中你有

nifi-zonefile-record-serialization-service-nar ->(取决于)

nifi-zonefile-record-serialization-service-api-nar ->(取决于)

nifi-standard-services-api-nar

在运行的应用程序中,当它从您的服务 NAR 实例化您的记录读取器的实例时,它需要加载来自您的服务 API NAR 的实现接口,然后需要加载来自标准服务 API NAR。

【讨论】:

【参考方案2】:

我在这方面花了很多时间。最后,我有一个可行的解决方案。我的自定义处理器将 RecordReader 用于传入流。但是,在 Maven 进程中编译或打包失败。我必须自定义 pom.xml 如下:

<dependency>
        <groupId>org.apache.nifi</groupId>
        <artifactId>nifi-record-serialization-service-api</artifactId>
        <version>$nifi.version</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.nifi</groupId>
        <artifactId>nifi-record-serialization-services-nar</artifactId>
        <version>$nifi.version</version>
        <type>nar</type>
    </dependency>

【讨论】:

我必须完全删除 RecordReaderFactory。我需要使用 commons-compress 1.19,但 nar 有一个旧版本,由处理器使用。使用 nars 时请注意 jar 依赖关系。【参考方案3】:

我最终还需要包含 API NAR 文件,即使它似乎没有在任何地方使用。它只是一个名为MyService 的通用模板类。

【讨论】:

【参考方案4】:

我遇到了与此处描述的相同的问题,我设法解决了它,包括 nar 模块(nifi-base-nar)pom.xml 中的依赖项

您需要包含的依赖项如下:

<dependency>
    <groupId>org.apache.nifi</groupId>
    <artifactId>nifi-standard-services-api-nar</artifactId>
    <version>$nifi.version</version>
    <type>nar</type>
</dependency>

【讨论】:

以上是关于启动期间的 Apache NiFi 自定义 NAR NoClassDefFoundError的主要内容,如果未能解决你的问题,请参考以下文章

NiFi 一键自动升级Nar包

NiFi 一键自动升级Nar包

NIFI 开发自定义Nifi Processor

Airbnb Airflow vs Apache Nifi [关闭]

apache nifi 总执行时间

Apache NiFi系统管理员指南 [ 一 ]