Skip to content

Fix #2969: stop overriding Apicurio's avroDatumProvider default - #2993

Merged
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2969
Sep 1, 2026
Merged

Fix #2969: stop overriding Apicurio's avroDatumProvider default#2993
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-2969

Conversation

@oscerd

@oscerd oscerd commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #2969.

Five Kamelets defaulted avroDatumProvider to io.apicurio.registry.serde.avro.ReflectAvroDatumProvider. Apicurio's own default is DefaultAvroDatumProvider, so the catalog was silently flipping a library default rather than restating it.

Confirmed from the shipped bytecode rather than from documentation — AvroKafkaSerdeConfig is the class that holds the constant:

AvroKafkaSerdeConfig: class io/apicurio/registry/serde/avro/DefaultAvroDatumProvider

Why it matters

On the read path, the reflect provider lets the schema resolved from the registry drive reflection-based class resolution during deserialization. Narrowing the five:

Kamelet reads Avro? disclaimed by name?
kafka-batch-apicurio-registry-source yes no
kafka-batch-apicurio-registry-not-secured-source yes yes (-not-secured-)
kafka-not-secured-apicurio-registry-source yes yes (-not-secured-)
kafka-apicurio-registry-not-secured-sink writes yes
kafka-not-secured-apicurio-registry-sink writes yes

kafka-batch-apicurio-registry-source is the only one that both reads Avro and is not already disclaimed by a -not-secured- name. The sinks write Avro, where reflection over the route's own outbound objects is a much weaker concern.

I changed all five anyway — the inconsistency is not worth preserving, and restating the library default is the same fix everywhere.

What changed

       avroDatumProvider:
         title: Avro Datum Provider
-        description: How to read data with Avro
+        description: How to read data with Avro. Defaults to Apicurio's own DefaultAvroDatumProvider,
+          which handles GenericRecord and generated SpecificRecord classes. Set
+          io.apicurio.registry.serde.avro.ReflectAvroDatumProvider to map Avro onto arbitrary POJOs
+          by reflection instead.
         type: string
-        default: "io.apicurio.registry.serde.avro.ReflectAvroDatumProvider"
+        default: "io.apicurio.registry.serde.avro.DefaultAvroDatumProvider"

The reflect provider stays fully available — it moves from an invisible default to an informed opt-in, with the description saying what each one actually does.

Compatibility — please read before merging

This changes deserialization behaviour for existing users. Anyone relying on the implicit reflect provider to map Avro onto plain POJOs will find that stops working until they set avroDatumProvider explicitly:

  • DefaultAvroDatumProviderGenericRecord and generated SpecificRecord classes
  • ReflectAvroDatumProvider → arbitrary POJOs via reflection

It is a one-line opt-in to restore, but it is not a silent no-op, so it wants a release-note mention. Per the contributor guidelines a default change like this is committer territory rather than something to wave through — flagging it rather than burying it.

An alternative shape, if reviewers prefer the catalog to assert nothing at all: drop default: entirely and switch the template placeholder to {{?avroDatumProvider}}, so Apicurio's default applies and the catalog automatically tracks it if upstream ever changes. I went with the explicit default because it stays visible in tooling, but I am happy to switch.

Verification

script/validator reports no errors, script/generator produces no doc changes, and mvn clean install passes from the repository root. No ReflectAvroDatumProvider default remains in the catalog.

The issue also asked to confirm the effective Avro version resolved via mvn:io.quarkus:quarkus-apicurio-registry-avro:3.24.2 — I have not done that here; it is independent of this change and better handled on its own.


Claude Code on behalf of Andrea Cosentino

Five Kamelets defaulted avroDatumProvider to
io.apicurio.registry.serde.avro.ReflectAvroDatumProvider. Apicurio's own
default is DefaultAvroDatumProvider -- confirmed from the bytecode of
apicurio-registry-serdes-avro-serde, where AvroKafkaSerdeConfig is the
class holding the constant. So the catalog was silently flipping a library
default rather than restating it.

That matters most on the read path: with the reflect provider, the schema
resolved from the registry drives reflection-based class resolution during
deserialization. Of the five, kafka-batch-apicurio-registry-source is the
only one that both reads Avro and is not already disclaimed by a
-not-secured- name.

All five now restate Apicurio's default, and the property description says
what each provider does so the reflect provider stays available as an
informed opt-in rather than an invisible default.

This changes deserialization behaviour for anyone who relied on the
implicit reflect provider to map Avro onto plain POJOs -- see the PR for
the compatibility note.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@oscerd
oscerd merged commit e1022b2 into apache:main Sep 1, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apicurio Kamelets override Apicurio's avroDatumProvider default with the reflect provider

1 participant