Я создал клиент Cassandra, написанный с отображением объектов Achilles на Java (с использованием IntelliJ + Gradle). Мой клиент отлично работает локально в IntelliJ, но выдает исключение при развертывании в контейнере докеров. В настоящее время я застрял с приведенным ниже исключением в моем контейнере докеров.
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, все работает нормально. Но после развертывания я столкнулся с этой проблемой в своем контейнере докеров.
Служба запускается в моем контейнере докеров следующим образом:
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 мы должны получить NoSuchMethodError. Кто-нибудь может помочь мне разобраться в проблеме.
Я не запускаю сервер локально, я создал экземпляр клиента в тестовом классе в том же пакете и запустил его
В верхней части окна Run должна отображаться команда, содержащая путь к классам, используемый IntelliJ.
@KonradBotor указывает на кеш Gradle, в котором есть оба файла jar
Хм, вы можете попробовать перечислить все jar-файлы в пути к классам, например, добавив этот класс: mkyong.com/java/how-to-print-out-the-current-project-classpa th в свой проект, а затем в Docker, запустив его вместо класса com.ds.msg.Server. Также не могли бы вы опубликовать свой Dockerfile и структуру проекта?
хм .. спасибо, попробую .. Я не могу опубликовать файл докеров, так как образы докеров автоматически генерируются через фреймворк
Позвольте нам продолжить обсуждение в чате.




Я наконец нашел ответ, проблема в том, что я угадала в своем вопросе. Несколько версий одной и той же банки вызвали сбой. Чтобы найти его, я использовал в своем файле Gradle следующее:
apply plugin: 'project-report'
И побежал,
gradle htmlDependencyReport
Это даст нам хороший HTML-отчет о дереве зависимостей. Мы даже можем использовать приведенный ниже cmd, но его будет сложно отслеживать в многомодульных проектах Gradle.
gradle dependencies
В отчете HTML я обнаружил, что модуль ахиллесово ядро зависит от netty-buffer-4.0.56.Final.jar, а другой модуль зависит от netty-all-4.0.51.Final.jar.
Поэтому, когда я попробовал следующее для ахилла в build.gradle, все работало нормально:
compile(group:'info.archinnov', name: 'achilles-core', version: '6.0.0'){ exclude module: 'netty-buffer' }
Поскольку в netty-all-4.0.51.Final.jar уже были классы, необходимые для отображения объектов ахилла, мой проект начал работу над развертыванием.
Еще одна причина сбоя, даже после удаления повторяющихся файлов jars из контейнера докеров: (Жестко) При перезапуске модуля, в свою очередь, создается новый модуль, который извлекает тот же образ Dockerimage из репозитория докеров.
IntelliJ каким-то образом решает проблему PATH при локальном запуске: /
Звучит интересно, полезно знать, что NoClassDefFoundError также возникает из-за нескольких версий одной и той же банки
Всегда лучше использовать проект-отчет в gradle, так как по мере роста вашего проекта будет сложно поддерживать зависимости.
И как IntelliJ выполняет эту службу - команда должна быть в первой строке вывода в окне «Выполнить»?