Skip to content

[fix][client] Apply Avro logical type conversions when decoding schema without classloader - #25759

Merged
lhotari merged 1 commit into
apache:masterfrom
lhotari:lh-avro-logical-type-bug
May 13, 2026
Merged

[fix][client] Apply Avro logical type conversions when decoding schema without classloader#25759
lhotari merged 1 commit into
apache:masterfrom
lhotari:lh-avro-logical-type-bug

Conversation

@lhotari

@lhotari lhotari commented May 13, 2026

Copy link
Copy Markdown
Member

Motivation

AvroReader only registered logical-type conversions (UUID, decimal,
date/time, timestamp) when a non-null ClassLoader was supplied, while
AvroWriter always registers them. This asymmetry caused decoding to
fail for any logical-type field when a schema was constructed via
SchemaDefinition.builder().withJsonDef(...), where no pojo class or
classloader is provided.

For example, a UUID field encoded with Schema.AVRO(class) could not
be decoded with Schema.AVRO(SchemaDefinition.builder().withJsonDef(...))
and failed with:

java.lang.IllegalArgumentException: Can not set java.util.UUID field ... to java.lang.String

because the UUIDConversion was never registered on the reader's
ReflectData.

Modifications

  • AvroReader now always builds a fresh ReflectData (using the
    supplied classloader when present, otherwise the default) and calls
    AvroSchema.addLogicalTypeConversions(...) on it, mirroring
    AvroWriter's behavior.
  • Added testDecodeUuidLogicalTypeWithClass and
    testDecodeUuidLogicalTypeWithJsonDef in AvroSchemaTest to cover
    the UUID logical-type round-trip for both schema construction paths.

Verifying this change

  • Make sure that the change passes the CI checks.

This change added tests and can be verified as follows:

  • The new AvroSchemaTest#testDecodeUuidLogicalTypeWithJsonDef
    reproduces the original failure and now passes with the fix.
  • Existing pulsar-client schema tests continue to pass.

Does this pull request potentially affect one of the following parts:

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

…a without classloader

### Motivation

`AvroReader` only registered logical-type conversions (UUID, decimal,
date/time, timestamp) when a non-null `ClassLoader` was supplied, while
`AvroWriter` always registers them. This asymmetry caused decoding to
fail for any logical-type field when a schema was constructed via
`SchemaDefinition.builder().withJsonDef(...)`, where no pojo class or
classloader is provided.

For example, a `UUID` field encoded with `Schema.AVRO(class)` could not
be decoded with `Schema.AVRO(SchemaDefinition.builder().withJsonDef(...))`
and failed with:

```
java.lang.IllegalArgumentException: Can not set java.util.UUID field ... to java.lang.String
```

because the `UUIDConversion` was never registered on the reader's
`ReflectData`.

### Modifications

- `AvroReader` now always builds a fresh `ReflectData` (using the
  supplied classloader when present, otherwise the default) and calls
  `AvroSchema.addLogicalTypeConversions(...)` on it, mirroring
  `AvroWriter`'s behavior.
- Added `testDecodeUuidLogicalTypeWithClass` and
  `testDecodeUuidLogicalTypeWithJsonDef` in `AvroSchemaTest` to cover
  the UUID logical-type round-trip for both schema construction paths.

### Verifying this change

This change added tests and can be verified as follows:

- The new `AvroSchemaTest#testDecodeUuidLogicalTypeWithJsonDef`
  reproduces the original failure and now passes with the fix.
- Existing `pulsar-client` schema tests continue to pass.

### Does this pull request potentially affect one of the following parts:

- [ ] Dependencies (add or upgrade a dependency)
- [ ] The public API
- [ ] The schema
- [ ] The default values of configurations
- [ ] The threading model
- [ ] The binary protocol
- [ ] The REST endpoints
- [ ] The admin CLI options
- [ ] The metrics
- [ ] Anything that affects deployment
@lhotari
lhotari merged commit 30ca23f into apache:master May 13, 2026
44 checks passed
lhotari added a commit that referenced this pull request May 13, 2026
…a without classloader (#25759)

(cherry picked from commit 30ca23f)
lhotari added a commit that referenced this pull request May 13, 2026
…a without classloader (#25759)

(cherry picked from commit 30ca23f)
lhotari added a commit that referenced this pull request May 15, 2026
…a without classloader (#25759)

(cherry picked from commit 30ca23f)
nodece pushed a commit to ascentstream/pulsar that referenced this pull request May 19, 2026
nodece pushed a commit to ascentstream/pulsar that referenced this pull request May 27, 2026
manas-ctds pushed a commit to datastax/pulsar that referenced this pull request Jun 1, 2026
…a without classloader (apache#25759)

(cherry picked from commit 30ca23f)
(cherry picked from commit f4ef184)
priyanshu-ctds pushed a commit to datastax/pulsar that referenced this pull request Jun 9, 2026
…a without classloader (apache#25759)

(cherry picked from commit 30ca23f)
(cherry picked from commit e7c3731)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants