【问题标题】:NoClassDefFoundError for io.netty.buffer.PooledByteBufAllocatorio.netty.buffer.PooledByteBufAllocator 的 NoClassDefFoundError
【发布时间】:2018-06-25 11:41:49
【问题描述】:

我创建了一个 Cassandra 客户端,用 java 中的 Achilles 对象映射编写(使用 IntelliJ + Gradle)。我的客户端在 IntelliJ 中本地运行良好,但在部署到 docker 容器中时抛出异常。我目前在我的 docker 容器中遇到以下异常。

java.lang.NoClassDefFoundError: 无法初始化类 io.netty.buffer.PooledByteBufAllocator 在 com.datastax.driver.core.NettyOptions.afterBootstrapInitialized(NettyOptions.java:144) 在 com.datastax.driver.core.Connection$Factory.newBootstrap(Connection.java:903) 在 com.datastax.driver.core.Connection$Factory.access$100(Connection.java:751) 在 com.datastax.driver.core.Connection.initAsync(Connection.java:139) 在 com.datastax.driver.core.Connection$Factory.open(Connection.java:807) 在 com.datastax.driver.core.ControlConnection.tryConnect(ControlConnection.java:252) 在 com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:201) 在 com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79) 在 com.datastax.driver.core.Cluster$Manager.negotiateProtocolVersionAndConnect(Cluster.java:1631) 在 com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1549) 在 com.datastax.driver.core.Cluster.init(Cluster.java:160) 在 com.datastax.driver.core.Cluster.connectAsync(Cluster.java:342) 在 com.datastax.driver.core.Cluster.connectAsync(Cluster.java:317) 在 com.datastax.driver.core.Cluster.connect(Cluster.java:259) 在 java.util.Optional.orElseGet(Optional.java:267) 在 info.archinnov.achilles.configuration.ArgumentExtractor.initSession(ArgumentExtractor.java:186) 在 info.archinnov.achilles.configuration.ArgumentExtractor.initConfigContext(ArgumentExtractor.java:96) 在 info.archinnov.achilles.bootstrap.AbstractManagerFactoryBuilder.buildConfigContext(AbstractManagerFactoryBuilder.java:60) 在 info.archinnov.achilles.generated.ManagerFactoryBuilder.build(ManagerFactoryBuilder.java:38) 在 com.ds.db.cassandra.AchillesClient.(AchillesClient.java:22) 在 com.ds.message.RabbitMQMsgClient$1.open(RabbitMQMsgClient.java:114) 在 org.apache.flink.api.common.functions.util.FunctionUtils.openFunction(FunctionUtils.java:36)

但是类,io.netty.buffer.PooledByteBufAllocator 属于 netty-buffer-4.0.56.Final.jar 已经是类路径的一部分。

当我尝试从 Intellij IDE 进行本地测试时,一切正常。 但是在部署之后,我在我的 docker 容器中遇到了这个问题。

该服务在我的 docker 容器中启动,如下所示:

java -服务器 -XX:HeapDumpPath=/opt/ds/srv/diagnostics/msgreader-1589749851-2s89z.heapdump -Xmx614m -Xms614m -XX:MaxMetaspaceSize=126M -XX:+HeapDumpOnOutOfMemoryError -XX:+UseG1GC -XX:CICompilerCount=4 -XX:MaxGCPauseMillis=1000 -XX:+DisableExplicitGC -XX:ParallelGCThreads=4 -Dsun.net.inetaddr。 ttl=60 -XX:OnOutOfMemoryError=kill -9 %p -Djava.library.path=/usr/local/lib -Djava.net.preferIPv4Stack=true -Dapp.dir=/opt/ds/sw/apps/msgreader - Dserver.name=msgreader -Dlog.dir=/opt/ds/var/log/msgreader -cp /opt/ds/sw/apps/javacontainer/resources:/opt/ds/sw/apps/msgreader/lib /*:/opt/ds/sw/apps/msgreader/resources:/opt/ds/sw/apps/javacontainer/lib/* com.ds.msg.Server 启动

从上面的 cmd 中,您可以注意到 -cp 参数提到了类路径。此路径包含netty-buffer-4.0.56.Final.jar

我后来发现netty-all-4.0.51.Final.jar也是类路径的一部分,这个jar也包含相同的类文件。我什至尝试使用所有可能的组合移除罐子。但我仍然面临同样的问题。

即使一个 jar 文件有多个版本,我们也应该得到 NoSuchMethodError,谁能帮我理解这个问题。

【问题讨论】:

  • IntelliJ 是如何执行这个服务的——命令应该在“运行”窗口输出的第一行?
  • 我没有在本地启动服务器,我在测试类中实例化了客户端,在同一个包中并运行它
  • Run 窗口顶部应该仍然显示一个命令,其中包含 IntelliJ 使用的类路径。
  • @KonradBotor 它指向 gradle 缓存,其中包含两个 jar 文件
  • 嗯,您可以尝试在类路径中列出所有 jar,例如将此类:mkyong.com/java/how-to-print-out-the-current-project-classpath 添加到您的项目中,然后在 Docker 中运行它而不是 com.ds.msg.Server 类。您还可以发布您的 Dockerfile 和项目结构吗?

标签: java docker gradle cassandra intellij-14


【解决方案1】:

我终于找到了答案,问题是我在我的问题中猜到的。同一个 jar 的多个版本,导致失败。为了找到它,我在我的 gradle 文件中使用了以下内容:

apply plugin: 'project-report'

然后跑了,

gradle htmlDependencyReport

它将为我们提供关于依赖关系树的良好 HTML 报告。我们甚至可以使用下面的 cmd,但是在多模块 gradle 项目中很难跟进

gradle dependencies

在 HTML 报告中,我发现 achilles-core 模块依赖于 netty-buffer-4.0.56.Final.jar,而另一个模块依赖于 netty-all-4.0.51.Final.jar。 因此,当我在 build.gradle 中为 achilles 尝试以下操作时,一切正常:

compile(group:'info.archinnov', name: 'achilles-core', version: '6.0.0'){
    exclude module: 'netty-buffer'
}

由于netty-all-4.0.51.Final.jar 已经有了 achilles 对象映射所需的类,我的项目开始着手部署。

另一个失败的原因,即使从 docker 容器中删除了重复的 jars 文件: (硬)重启 pod,反过来又创建了一个新的 pod,它从 docker repo 中拉取相同的 Dockerimage。

IntelliJ 在本地运行时如何解决 PATH 问题:/

【讨论】:

  • 听起来很有趣,很高兴知道 NoClassDefFoundError,也是由于同一个 jar 的多个版本引起的
  • 在 gradle 中使用 project-report 总是更好,因为一旦您的项目增长,将很难维护依赖关系..
猜你喜欢
  • 2016-06-05
  • 2021-08-05
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
相关资源
最近更新 更多