我创建了一个 Cassandra 客户端,用 java 中的 Achilles 对象映射编写(使用 IntelliJ + Gradle)。我的客户端在 IntelliJ 中本地运行良好,但在部署到 docker 容器中时抛出异常。我目前在我的 docker 容器中遇到以下异常。
java.lang.NoClassDefFoundError: Could not initialize class io.netty.buffer.PooledByteBufAllocator at com.datastax.driver.core.NettyOptions.afterBootstrapInitialized(NettyOptions.java:144) at com.datastax.driver.core.Connection$Factory.newBootstrap(Connection.java:903) at com.datastax.driver.core.Connection$Factory.access$100(Connection.java:751) at com.datastax.driver.core.Connection.initAsync(Connection.java:139) at com.datastax.driver.core.Connection$Factory.open(Connection.java:807) at com.datastax.driver.core.ControlConnection.tryConnect(ControlConnection.java:252) at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:201) at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79) at com.datastax.driver.core.Cluster$Manager.negotiateProtocolVersionAndConnect(Cluster.java:1631) at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1549) at com.datastax.driver.core.Cluster.init(Cluster.java:160) at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:342) at com.datastax.driver.core.Cluster.connectAsync(Cluster.java:317) at com.datastax.driver.core.Cluster.connect(Cluster.java:259) at java.util.Optional.orElseGet(Optional.java:267) at info.archinnov.achilles.configuration.ArgumentExtractor.initSession(ArgumentExtractor.java:186) at info.archinnov.achilles.configuration.ArgumentExtractor.initConfigContext(ArgumentExtractor.java:96) at info.archinnov.achilles.bootstrap.AbstractManagerFactoryBuilder.buildConfigContext(AbstractManagerFactoryBuilder.java:60) at info.archinnov.achilles.generated.ManagerFactoryBuilder.build(ManagerFactoryBuilder.java:38) at com.ds.db.cassandra.AchillesClient.(AchillesClient.java:22) at com.ds.message.RabbitMQMsgClient$1.open(RabbitMQMsgClient.java:114) at 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 -server -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 start
从上面的 cmd 中,您可以注意到 -cp 参数提到了类路径。而这个路径包含netty-buffer-4.0.56.Final.jar
。
我后来发现netty-all-4.0.51.Final.jar
也是类路径的一部分,这个jar也包含相同的类文件。我什至尝试使用所有可能的组合移除 jar 。但我仍然面临同样的问题。
即使一个 jar 文件有多个版本,我们也应该得到 NoSuchMethodError,谁能帮我理解这个问题。
最佳答案
我终于找到了答案,问题是我在我的问题中猜到的。同一个 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 问题:/
关于java - io.netty.buffer.PooledByteBufAllocator 的 NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51022663/