Skip to content

Updates Kafka client from 2.8.1 to 3.3.1#130

Merged
andsel merged 9 commits into
logstash-plugins:mainfrom
andsel:fix/update_kafka_version_3.3.1
Dec 16, 2022
Merged

Updates Kafka client from 2.8.1 to 3.3.1#130
andsel merged 9 commits into
logstash-plugins:mainfrom
andsel:fix/update_kafka_version_3.3.1

Conversation

@andsel

@andsel andsel commented Nov 10, 2022

Copy link
Copy Markdown
Contributor

Release notes

Update kafka client to 3.3.1, requires Logstash >= 8.3.0. Deprecated default value for setting client_dns_lookup, when used it's forced to use_all_dns_ips

What does this PR do?

Updated the Kafka client library used from 2.8.1 to 3.3.1 and Schema Registry from 6.2.2 to 7.3.0.

This PR updates the client library and, due to the removal of zookeeper flag in launching integration Kafka instance, update also the bash scripts used in integration testing.
The update of the Schema Registry forces the dependency on Logstash 8.3 because it's the first that ships Jackson 2.13.3 which is strictly required during the instantiation of the client.

Why is it important/What is the impact to the user?

Updating the client requires a library (Jackson) that's available from Logstash 8.3.0 so this is a requirement starting from this version of the plugin.
The new Kafka client dropped the default value for configuration client_dns_lookup. Starting from Kafka 2.6.0 it had been deprecated and was removed in Kafka 3.0.
The default value for plugin setting client_dns_lookup switched from default to use_all_dns_ips which if a user doesn't customize i,t doesn't create any problem.
If a user explicitly set client_dns_lookup to default and updates the plugin to this version then the value is forced to use_all_dns_ips.
Simple explanation why default is not a good choice, see here.

Checklist

  • My code follows the style guidelines of this project
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • [ ] I have made corresponding change to the default configuration files (and/or docker env variables)
  • [ ] I have added tests that prove my fix is effective or that my feature works

Author's Checklist

  • Run it locally, with Kafka and Logstash.

How to test this PR locally

  • Download Kafka and unpack locally
curl "https://archive.apache.org/dist/kafka/3.3.1/kafka_2.12-3.3.1.tgz" -o kafka_2.12-3.3.1.tgz
  • start Kafka and Zookeeper after cd-ing into the uncompressed folder
bin/zookeeper-server-start.sh -daemon config/zookeeper.properties
bin/kafka-server-start.sh -daemon config/server.properties --override advertised.host.name=127.0.0.1
  • create the partition logstash_integration_topic_plain to be later used into the Logstash pipeline
bin/kafka-topics.sh --create --partitions 3 --replication-factor 1 --topic logstash_topic --bootstrap-server localhost:9092
  • install this plugin into Logstash, for example in case of local checkout, edit into Gemfile
gem "logstash-integration-kafka", :path => "/path/to/logstash-integration-kafka"
bin/logstash-plugin install --no-verify
  • run Logstash pipeline
input {
  kafka {
    topics => ["logstash_topic"]
    decorate_events => true
  }
}

output {
  stdout { codec => rubydebug {metadata => true } }
}
  • Launch CLI Kafka producer client and start typing some lines
bin/kafka-console-producer.sh --topic logstash_topic --broker-list localhost:9092

The events has to be received and logged by Logstash.

Shutdown and cleanup:

bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic 'logstash_.*'
bin/kafka-server-stop.sh
bin/zookeeper-server-stop.sh

Related issues

Use cases

As a Kafka user I want to be able to use a Logstash plugin aligned to the latest major version of Kafka.

Screenshots

Logs

Kafka 3.3.1 correspond to Confluent Platform 7.3.0.
This commit
- updates the jar dependencies to match version 3.3.1 and all relates scripts where the version is used.
- with Kafka 3 the zookeper param was removed from kafka-topics.sh CLI tool, being replaced with bootstrap-server.
- In Kafka 3 the "default" value was removed from the possibile values of "client.dns.lookup" setting, so plugin's input and output corresponding "client_dns_lookup" was consequently aligned.
@andsel

andsel commented Nov 21, 2022

Copy link
Copy Markdown
Contributor Author

The CI error that's happening on 7.x branch is:

Java::OrgApacheKafkaCommon::KafkaException:
  Failed to construct kafka producer
# org.apache.kafka.clients.producer.KafkaProducer.<init>(org/apache/kafka/clients/producer/KafkaProducer.java:468)
# org.apache.kafka.clients.producer.KafkaProducer.<init>(org/apache/kafka/clients/producer/KafkaProducer.java:291)
# org.apache.kafka.clients.producer.KafkaProducer.<init>(org/apache/kafka/clients/producer/KafkaProducer.java:318)
# org.apache.kafka.clients.producer.KafkaProducer.<init>(org/apache/kafka/clients/producer/KafkaProducer.java:303)
# jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
# jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(jdk/internal/reflect/NativeConstructorAccessorImpl.java:62)
# jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(jdk/internal/reflect/DelegatingConstructorAccessorImpl.java:45)
# java.lang.reflect.Constructor.newInstance(java/lang/reflect/Constructor.java:490)
# usr.share.plugins.plugin.spec.integration.inputs.kafka_spec.write_some_data_to(/usr/share/plugins/plugin/spec/integration/inputs/kafka_spec.rb:404)
# usr.share.plugins.plugin.spec.integration.inputs.kafka_spec./usr/share/plugins/plugin/spec/integration/inputs/kafka_spec.rb(/usr/share/plugins/plugin/spec/integration/inputs/kafka_spec.rb:411)
# java.lang.invoke.MethodHandle.invokeWithArguments(java/lang/invoke/MethodHandle.java:710)
# ------------------
# --- Caused by: ---
# Java::JavaLang::ClassNotFoundException:
#   com.fasterxml.jackson.databind.json.JsonMapper
#   java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)

happens also with 8.x up to 8.2.3

With LS 8.3.0 jrjackson switched from 0.4.14 to 0.4.15 and this makes the jackson JSON library to switch from 2.9.10 to 2.13.3.

Now, the class that can't be found com.fasterxml.jackson.databind.json.JsonMapper is present in Jackson library only starting from 2.10 .

Kafka Client switched jackson-databind

@andsel

andsel commented Nov 23, 2022

Copy link
Copy Markdown
Contributor Author
The full exception is
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/json/JsonMapper
	at io.confluent.kafka.schemaregistry.utils.JacksonMapper.<clinit>(JacksonMapper.java:27)
	at io.confluent.kafka.schemaregistry.client.rest.RestService.<clinit>(RestService.java:156)
	at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.<init>(CachedSchemaRegistryClient.java:158)
	at io.confluent.kafka.schemaregistry.client.SchemaRegistryClientFactory.newClient(SchemaRegistryClientFactory.java:36)
	at io.confluent.kafka.serializers.AbstractKafkaSchemaSerDe.configureClientProperties(AbstractKafkaSchemaSerDe.java:72)
	at io.confluent.kafka.serializers.AbstractKafkaAvroSerializer.configure(AbstractKafkaAvroSerializer.java:66)
	at io.confluent.kafka.serializers.KafkaAvroSerializer.configure(KafkaAvroSerializer.java:50)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:396)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:291)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:318)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:303)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at org.jruby.dist/org.jruby.javasupport.JavaConstructor.newInstanceDirect(JavaConstructor.java:279)
	at org.jruby.dist/org.jruby.java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:86)
	at org.jruby.dist/org.jruby.java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:175)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.java.proxies.ConcreteJavaProxy$InitializeMethod.call(ConcreteJavaProxy.java:56)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.RubyClass.newInstance(RubyClass.java:894)
	at org.jruby.dist/org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrNBlock.call(JavaMethod.java:349)
	at org.jruby.dist/org.jruby.java.proxies.ConcreteJavaProxy$NewMethod.call(ConcreteJavaProxy.java:158)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:192)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:125)
	at org.jruby.dist/org.jruby.runtime.Block.yieldNonArray(Block.java:174)
	at org.jruby.dist/org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1764)
	at org.jruby.dist/org.jruby.RubyBasicObject.instance_exec(RubyBasicObject.java:2680)
	at org.jruby.dist/org.jruby.RubyBasicObject$INVOKER$i$0$3$instance_exec.call(RubyBasicObject$INVOKER$i$0$3$instance_exec.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:204)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:338)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:89)
	at org.jruby.dist/org.jruby.runtime.Block.yieldSpecific(Block.java:139)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:503)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:76)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:89)
	at org.jruby.dist/org.jruby.runtime.Block.yieldSpecific(Block.java:139)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:503)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:76)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:89)
	at org.jruby.dist/org.jruby.runtime.Block.yieldSpecific(Block.java:139)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:503)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:76)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:89)
	at org.jruby.dist/org.jruby.runtime.Block.yieldSpecific(Block.java:139)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:503)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:76)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:79)
	at org.jruby.dist/org.jruby.runtime.Block.call(Block.java:129)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:299)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:278)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:266)
	at org.jruby.dist/org.jruby.RubyProc$INVOKER$i$0$0$call.call(RubyProc$INVOKER$i$0$0$call.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:121)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:108)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:192)
	at org.jruby.dist/org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:90)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:354)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:143)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:345)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:192)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:125)
	at org.jruby.dist/org.jruby.runtime.Block.yieldNonArray(Block.java:174)
	at org.jruby.dist/org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1764)
	at org.jruby.dist/org.jruby.RubyBasicObject.instance_exec(RubyBasicObject.java:2680)
	at org.jruby.dist/org.jruby.RubyBasicObject$INVOKER$i$0$3$instance_exec.call(RubyBasicObject$INVOKER$i$0$3$instance_exec.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:182)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:338)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:191)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:178)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:203)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:325)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:79)
	at org.jruby.dist/org.jruby.runtime.Block.call(Block.java:129)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:299)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:278)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:266)
	at org.jruby.dist/org.jruby.RubyProc$INVOKER$i$0$0$call.call(RubyProc$INVOKER$i$0$0$call.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:84)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:121)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:108)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:192)
	at org.jruby.dist/org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:90)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:354)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:143)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:345)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:192)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:125)
	at org.jruby.dist/org.jruby.runtime.Block.yieldNonArray(Block.java:174)
	at org.jruby.dist/org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1764)
	at org.jruby.dist/org.jruby.RubyBasicObject.instance_exec(RubyBasicObject.java:2680)
	at org.jruby.dist/org.jruby.RubyBasicObject$INVOKER$i$0$3$instance_exec.call(RubyBasicObject$INVOKER$i$0$3$instance_exec.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:338)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:191)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:178)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:396)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:205)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:325)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.call(IRBlockBody.java:79)
	at org.jruby.dist/org.jruby.runtime.Block.call(Block.java:129)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:299)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:278)
	at org.jruby.dist/org.jruby.RubyProc.call(RubyProc.java:266)
	at org.jruby.dist/org.jruby.RubyProc$INVOKER$i$0$0$call.call(RubyProc$INVOKER$i$0$0$call.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:121)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:108)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:192)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:354)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:143)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:345)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:191)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:337)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:73)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:73)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:73)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:191)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:178)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:396)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:205)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:325)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:185)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
	at org.jruby.dist/org.jruby.runtime.Block.yield(Block.java:170)
	at org.jruby.dist/org.jruby.RubyArray.collect(RubyArray.java:2566)
	at org.jruby.dist/org.jruby.RubyArray.map19(RubyArray.java:2580)
	at org.jruby.dist/org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroBlock.call(JavaMethod.java:555)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:185)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
	at org.jruby.dist/org.jruby.runtime.Block.yield(Block.java:170)
	at org.jruby.dist/org.jruby.RubyArray.collect(RubyArray.java:2566)
	at org.jruby.dist/org.jruby.RubyArray.map19(RubyArray.java:2580)
	at org.jruby.dist/org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroBlock.call(JavaMethod.java:555)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:89)
	at org.jruby.dist/org.jruby.runtime.Block.yieldSpecific(Block.java:139)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:503)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:76)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:73)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:93)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:537)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:116)
	at org.jruby.dist/org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:143)
	at org.jruby.dist/org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:185)
	at org.jruby.dist/org.jruby.runtime.BlockBody.yield(BlockBody.java:116)
	at org.jruby.dist/org.jruby.runtime.Block.yield(Block.java:170)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.yield(IRRuntimeHelpers.java:499)
	at org.jruby.dist/org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:85)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:178)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:104)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:386)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:184)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:191)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:337)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:156)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:143)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:92)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:191)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:178)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:396)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:205)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:325)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:86)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:73)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:332)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:86)
	at org.jruby.dist/org.jruby.ir.instructions.CallBase.interpret(CallBase.java:540)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:361)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:80)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:121)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:108)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:192)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:354)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:143)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:345)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:96)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:81)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:30)
	at org.jruby.dist/org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
	at org.jruby.dist/org.jruby.Ruby.runInterpreter(Ruby.java:870)
	at org.jruby.dist/org.jruby.Ruby.loadFile(Ruby.java:2961)
	at org.jruby.dist/org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:234)
	at org.jruby.dist/org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
	at org.jruby.dist/org.jruby.runtime.load.LoadService.load(LoadService.java:343)
	at org.jruby.dist/org.jruby.RubyKernel.loadCommon(RubyKernel.java:1043)
	at org.jruby.dist/org.jruby.RubyKernel.load(RubyKernel.java:1013)
	at org.jruby.dist/org.jruby.RubyKernel$INVOKER$s$load.call(RubyKernel$INVOKER$s$load.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:417)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:375)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:174)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:316)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:72)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.INTERPRET_EVAL(Interpreter.java:106)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.evalCommon(Interpreter.java:158)
	at org.jruby.dist/org.jruby.ir.interpreter.Interpreter.evalWithBinding(Interpreter.java:182)
	at org.jruby.dist/org.jruby.RubyKernel.evalCommon(RubyKernel.java:1090)
	at org.jruby.dist/org.jruby.RubyKernel.eval(RubyKernel.java:1052)
	at org.jruby.dist/org.jruby.RubyKernel$INVOKER$s$0$3$eval.call(RubyKernel$INVOKER$s$0$3$eval.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:220)
	at org.jruby.dist/org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:216)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:418)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:236)
	at usr.share.rvm.gems.jruby_minus_9_dot_2_dot_9_dot_0.bin.jruby_executable_hooks.invokeOther18:eval(/usr/share/rvm/gems/jruby-9.2.9.0/bin/jruby_executable_hooks:22)
	at usr.share.rvm.gems.jruby_minus_9_dot_2_dot_9_dot_0.bin.jruby_executable_hooks.RUBY$script(/usr/share/rvm/gems/jruby-9.2.9.0/bin/jruby_executable_hooks:22)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:710)
	at org.jruby.dist/org.jruby.ir.Compiler$1.load(Compiler.java:89)
	at org.jruby.dist/org.jruby.Ruby.runScript(Ruby.java:857)
	at org.jruby.dist/org.jruby.Ruby.runNormally(Ruby.java:780)
	at org.jruby.dist/org.jruby.Ruby.runNormally(Ruby.java:798)
	at org.jruby.dist/org.jruby.Ruby.runFromMain(Ruby.java:610)
	at org.jruby.dist/org.jruby.Main.doRunFromMain(Main.java:412)
	at org.jruby.dist/org.jruby.Main.internalRun(Main.java:304)
	at org.jruby.dist/org.jruby.Main.run(Main.java:234)
	at org.jruby.dist/org.jruby.Main.main(Main.java:206)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.json.JsonMapper
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

Which is summarized as:

Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/json/JsonMapper
	at io.confluent.kafka.schemaregistry.utils.JacksonMapper.<clinit>(JacksonMapper.java:27)
	at io.confluent.kafka.schemaregistry.client.rest.RestService.<clinit>(RestService.java:156)
	at io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient.<init>(CachedSchemaRegistryClient.java:158)
	at io.confluent.kafka.schemaregistry.client.SchemaRegistryClientFactory.newClient(SchemaRegistryClientFactory.java:36)
	at io.confluent.kafka.serializers.AbstractKafkaSchemaSerDe.configureClientProperties(AbstractKafkaSchemaSerDe.java:72)
	at io.confluent.kafka.serializers.AbstractKafkaAvroSerializer.configure(AbstractKafkaAvroSerializer.java:66)
	at io.confluent.kafka.serializers.KafkaAvroSerializer.configure(KafkaAvroSerializer.java:50)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:396)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:291)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:318)
	at org.apache.kafka.clients.producer.KafkaProducer.<init>(KafkaProducer.java:303)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at org.jruby.dist/org.jruby.javasupport.JavaConstructor.newInstanceDirect(JavaConstructor.java:279)
	<JRuby intepreter part> 
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.json.JsonMapper
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)

So it comes from io.confluent:kafka-schema-registry-client org.apache.kafka:kafka-clients

@andsel

andsel commented Nov 24, 2022

Copy link
Copy Markdown
Contributor Author

Looking better at the problem, it originates from the fact that io.confluent.kafka.schemaregistry.client.rest.RestService which uses a singleton of io.confluent.kafka.schemaregistry.utils.JacksonMapper fails because the JacksonMapper class has a dependency on com.fasterxml.jackson.databind.json.JsonMapper.

The io.confluent:kafka-schema-registry-client:6.2.2 used in previous version of the plugin had a dependency on jackson-databind:2.12.5 which in theory should have presented the class not found problem of JsonMapper; but it didn't happen because the io.confluent.kafka.schemaregistry.utils.JacksonMapper switched implementation:

  • in io.confluent:kafka-schema-registry-client:6.2.2 the class didn't import com.fasterxml.jackson.databind.json.JsonMapper (code ref).
  • starting from io.confluent:kafka-schema-registry-client:7.0.4 the implementation changed and import such class (code ref).

Comment thread docs/input-kafka.asciidoc Outdated
Co-authored-by: Karen Metts <35154725+karenzone@users.noreply.github.com>

@karenzone karenzone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for using/setting the attributes, @andsel! Please update the kafka client doc version attributes, too.

Comment thread docs/input-kafka.asciidoc Outdated
Comment thread docs/output-kafka.asciidoc Outdated
andsel and others added 2 commits November 29, 2022 18:27
Co-authored-by: Karen Metts <35154725+karenzone@users.noreply.github.com>
@andsel
andsel force-pushed the fix/update_kafka_version_3.3.1 branch from 7e6e55c to 10b3ac5 Compare December 12, 2022 09:56
@andsel andsel added the enhancement New feature or request label Dec 12, 2022
…ed jruby's bundler from Logstash's artifacts
Comment thread .ci/run.sh
Comment thread build.gradle Outdated
Comment thread CHANGELOG.md Outdated
Comment thread lib/logstash/inputs/kafka.rb Outdated
# connection. If the value is `resolve_canonical_bootstrap_servers_only` each entry will be
# resolved and expanded into a list of canonical names.
config :client_dns_lookup, :validate => ["default", "use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "default"
config :client_dns_lookup, :validate => ["use_all_dns_ips", "resolve_canonical_bootstrap_servers_only"], :default => "use_all_dns_ips"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did default previously map to in Kafka?

By not allowing the setting of default, this is potentially a breaking change (even though it is somewhat unlikely that a user will explicitly set default, it's a valid setting). If we choose to remove the explicit default value we need to flag it in change logs and release notes, and figure out how we choose to bundle this with future logstashes. We would also need to update the docs for the input and output

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you on the breaking change. Given the explanation in previous comment do you think that maybe is better if we implicitly remap default to use_all_dns_ips?. So that if one user has explicitly set default we switch implicitly to use_all_dns_ips. In worst case we let them to connect to another node while the previous setting would have resulted in connection error.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is reasonable - we should add a note in the docs and the release notes to explicitly state the change, and they are changing the value of default to be the kafka default setting, rather than the explicit default value that Kafka previously used.

@andsel andsel Dec 14, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applied with commit b2568f0, so no anymore breaking change if the user uses default but just log a warn message.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@robbavey I've removed the breaking change on the removal of default value by admitting it, deprecating and forcing to use_all_dns_ips.
The PR is read for another review, please 🙏

@andsel
andsel requested a review from robbavey December 13, 2022 16:26
@andsel
andsel force-pushed the fix/update_kafka_version_3.3.1 branch from 4ce293c to b2568f0 Compare December 14, 2022 10:17

@robbavey robbavey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine, but there is an incomplete looking unit test

Comment thread spec/unit/inputs/kafka_spec.rb Outdated
expect { subject.register }.to_not raise_error
end

context "x" do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test looks unfinished - can you fix this up before committing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed with 6448983

@andsel
andsel requested a review from robbavey December 16, 2022 10:45

@robbavey robbavey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@andsel
andsel merged commit a388a3f into logstash-plugins:main Dec 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update Kafka client and Confluent schema registry client

4 participants