[DO NOT MERGE] Add opt-in Jackson 3 support via multi-release JAR#2783
[DO NOT MERGE] Add opt-in Jackson 3 support via multi-release JAR#2783cretz wants to merge 1 commit intotemporalio:masterfrom
Conversation
|
What about the SDK's internal uses of jackson like for Nexus? |
Can you clarify which internal uses? If it's JSON in and JSON out from server POV, the user doesn't care what JSON serialization we use internally (e.g. for search attributes), and we should continue to use the dependency that is always present (which is Jackson 2 for now). |
|
So to be clear this PR doesn't let users opt out of including Jackson 2. It just lets them include Jackson 2 and Jackson 3? |
|
It lets users opt-out of using Jackson 2, but not opt-out of the dependency. We have never allowed opting out of the Jackson 2 dependency, and I am worried what it'd take to make it an optional dependency without breaking users today. If there is a good option here of being able to opt-out of the Jackson 2 dependency, I think we can discuss them, but I think leaving the required dependency as we always have should be harmless. |
|
@cretz I think that Temporal SDK should not force users to have Jackson 2 on the classpath/modulepath if Jackson 3 is available. This may be problematic - for example, Hibernate will add support for Jackson 3 in version 7.3 but by default, if both Jackson versions are available, it will choose Jackson 2 (this can be overridden of course, but the point still stands I believe). Having Jackson 2 still available implicitly may have similar consequences in other places as well and they would be difficult to debug if inconsistencies in JSON (de)serialization are found because of that. Of course, having Jackson 3 support while still requiring Jackson 2 internally is better than no support for Jackson 3 at all, so if it would take a lot of effort to refactor this requirement out, then I think this PR could be merged as-is. But I strongly believe that the Jackson 2 requirement should be lifted in the future. |
We already require this today even if you have/use Jackson 3 available. We have extreme backwards compatibility requirements for this repository, so coordinating the removal of a dependency users expect and that we use internally is non-trivial and is a breaking change that has to be planned with at least a deprecation first.
This is definitely the case, and we use Jackson 2 things internally and people have expectations built around its behavior and its implicit presence. We can't go just yanking a transitive dependency people may rely on just because we are adding this PR. But we may be able to have a deprecation schedule towards making Jackson 2 an optional dependency requiring users to explicitly depend on it. |
|
I'm not saying that Temporal should just completely drop Jackson 2 as a dependency. It can still have it as required, but users should be able to exclude it via Maven/Gradle. Temporal SDK should check the available Jackson version dynamically and should still work if Jackson 2 is not available provided that Jackson 3 is available instead. This will not break backward compatibility, but will allow users to be flexible about which Jackson version is on the classpath. But, as I said, if this is a lot of effort, then it's absolutely ok to not do that right now. |
I think this is the case (even if not a lot of effort, definitely would want to be a separate effort from this PR, don't want to combine concerns here). And we may find that if Jackson 2 becomes truly EOL some day, we can be willing to break compat by making Jackson 3 the required dep and asking those w/ custom Jackson 2 code to opt-in to Jackson 2 support. |
What was changed
Jackson3JsonPayloadConverteras a multi-release JAR entry (Java 8 stub insrc/main/java/, real implementation insrc/main/java17/) that uses Jackson 3.xJsonMapperfor JSON serializationJacksonJsonPayloadConverter.setDefaultAsJackson3(boolean, boolean)static method to globally opt in to Jackson 3 delegation, including for the default converter inDefaultDataConverter.STANDARD_PAYLOAD_CONVERTERSjackson2Compat=false) and Jackson 2 compatibility mode (jackson2Compat=trueviaJsonMapper.builderWithJackson2Defaults())ObjectMapperpassed to the constructor are not affected by the global Jackson 3 delegate"json/plain"encoding type and are wire-compatible in both directions[3.0.4,)in the POMjackson3Teststest suite (8 tests, Java 17 launcher) covering direct converter usage, wire compatibility, global delegation viaGlobalDataConverter.get(), and explicit-mapper opt-outUnsupportedOperationException) and Java 17+ without Jackson 3 (NoClassDefFoundError)jackson3TestsCI step to theunit_test_jdk8job@Documentedto the@ExperimentalannotationDO NOT MERGE - we are going to wait on Spring Boot 4 support at the same time to at least get reviewed at #2786
Checklist