feat: Replace Jackson with Gson for json (de) serialization#789
feat: Replace Jackson with Gson for json (de) serialization#789ehsavoie wants to merge 3 commits intoa2aproject:0.3.x-compatfrom
Conversation
Replace Jackson ObjectMapper with Gson throughout the codebase to eliminate
Jackson dependency and provide custom serialization control.
Key Changes:
- Created JsonUtil.java with Gson-based OBJECT_MAPPER singleton
- Implemented 9 custom TypeAdapters for complex type handling:
* OffsetDateTimeTypeAdapter - ISO-8601 datetime serialization
* JSONRPCErrorTypeAdapter - Polymorphic error deserialization (12 error types)
* ThrowableTypeAdapter - Avoids Java 17+ reflection restrictions
* TaskStateTypeAdapter - Wire format enum serialization
* RoleTypeAdapter - Message.Role enum handling
* PartKindTypeAdapter - Part.Kind enum handling
* PartTypeAdapter - Polymorphic Part deserialization (Text/File/Data)
* StreamingEventKindTypeAdapter - Event type deserialization
* FileContentTypeAdapter - FileWithBytes/FileWithUri discrimination
- Added TaskSerializationTest with 21 comprehensive tests covering:
* Round-trip serialization for all Task components
* Direct JSON deserialization tests
* All Part types and FileContent variants
- Removed Jackson-specific deserializers and annotations
- Updated all usages across 142 files (client, server, extras, tests)
- Removed Jackson dependencies from spec/pom.xml
Technical Details:
- Thread-safe singleton OBJECT_MAPPER with all adapters registered
- Handles polymorphic types via two-pass parsing strategy
- Maintains wire format compatibility with existing JSON-RPC protocol
- Preserves null-safety with NullAway/JSpecify conventions
Breaking Changes: None - wire format remains compatible
Signed-off-by: Emmanuel Hugonnet <ehugonne@redhat.com>
a2aproject#581) We no longer use Jackson
Signed-off-by: Emmanuel Hugonnet <ehugonne@redhat.com>
There was a problem hiding this comment.
Code Review
This pull request migrates the project from Jackson to Gson for JSON processing. It includes the addition of a new JsonUtil utility class, updates to various pom.xml files to replace Jackson dependencies with Gson, and updates to the codebase to use the new utility. The reviewer correctly identified that several Quarkus modules were left without a configured JSON provider after removing the Jackson dependencies, which would cause runtime issues.
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-resteasy-jackson</artifactId> | ||
| <artifactId>quarkus-resteasy</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-resteasy-jackson to quarkus-resteasy. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for RESTEasy. To ensure JSON serialization and deserialization work correctly with Gson in this Quarkus module, you should replace this with quarkus-resteasy-gson.
This same concern applies to other modules where quarkus-resteasy-jackson or quarkus-rest-client-jackson were replaced with their base artifact without specifying a Gson alternative, for example in:
extras/push-notification-config-store-database-jpa/pom.xmlextras/task-store-database-jpa/pom.xmlreference/common/pom.xmlreference/jsonrpc/pom.xmlreference/rest/pom.xmltck/pom.xml
Please ensure all Quarkus modules that handle JSON are correctly configured with a Gson provider.
| <artifactId>quarkus-resteasy</artifactId> | |
| <artifactId>quarkus-resteasy-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-client-jackson</artifactId> | ||
| <artifactId>quarkus-rest-client</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-client-jackson to quarkus-rest-client. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for the REST client. To ensure JSON serialization and deserialization work correctly with Gson in the tests for this module, you should replace this with quarkus-rest-client-gson.
| <artifactId>quarkus-rest-client</artifactId> | |
| <artifactId>quarkus-rest-client-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-client-jackson</artifactId> | ||
| <artifactId>quarkus-rest-client</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-client-jackson to quarkus-rest-client. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for the REST client. To ensure JSON serialization and deserialization work correctly with Gson in the tests for this module, you should replace this with quarkus-rest-client-gson.
| <artifactId>quarkus-rest-client</artifactId> | |
| <artifactId>quarkus-rest-client-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-client-jackson</artifactId> | ||
| <artifactId>quarkus-rest-client</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-client-jackson to quarkus-rest-client. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for the REST client. To ensure JSON serialization and deserialization work correctly with Gson in the tests for this module, you should replace this with quarkus-rest-client-gson.
| <artifactId>quarkus-rest-client</artifactId> | |
| <artifactId>quarkus-rest-client-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-client-jackson</artifactId> | ||
| <artifactId>quarkus-rest-client</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-client-jackson to quarkus-rest-client. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for the REST client. To ensure JSON serialization and deserialization work correctly with Gson in the tests for this module, you should replace this with quarkus-rest-client-gson.
| <artifactId>quarkus-rest-client</artifactId> | |
| <artifactId>quarkus-rest-client-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-client-jackson</artifactId> | ||
| <artifactId>quarkus-rest-client</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-client-jackson to quarkus-rest-client. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for the REST client. To ensure JSON serialization and deserialization work correctly with Gson in the tests for this module, you should replace this with quarkus-rest-client-gson.
| <artifactId>quarkus-rest-client</artifactId> | |
| <artifactId>quarkus-rest-client-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
| <dependency> | ||
| <groupId>io.quarkus</groupId> | ||
| <artifactId>quarkus-rest-jackson</artifactId> | ||
| <artifactId>quarkus-rest</artifactId> |
There was a problem hiding this comment.
The dependency has been changed from quarkus-rest-jackson to quarkus-rest. This correctly removes the explicit Jackson integration, but it does not configure a JSON provider for RESTEasy. To ensure JSON serialization and deserialization work correctly with Gson in this module, you should replace this with quarkus-rest-gson.
| <artifactId>quarkus-rest</artifactId> | |
| <artifactId>quarkus-rest-gson</artifactId> |
There was a problem hiding this comment.
This doesn't exist
|
@ehsavoie is the cloud deployment example expected? |
Replacing Jackson with Gson for json (de)serialization
Fixes #<issue_number_goes_here> 🦕