-
Notifications
You must be signed in to change notification settings - Fork 6
JSTEP 1
(Back to JSTEP page)
Tatu Saloranta (@cowtowncoder)
- 2024-04-29: Update based on current status, thinking
- 2022-06-29: major change to Coordinates (com.fasterxml -> tools.jackson!)
- 2021-01-29: small clarifications
- 2019-02-09: minor touchup
- 2019-01-26: first revision
Mostly complete as of Jackson 2.18: implemented as proposed.
The basic proposal now is that for Jackson 3, we will change
- Maven coordinates AND Java package names and SOME (but not all) Java class names
- exception being
jackson-annotations
, for which none of above would be changed
- exception being
- Maven coordinate change (minus annotations) would be changing group id base from
com.fasterxml.jackson
totools.jackson
(that is, fromcom.fasterxml.jackson.core
totools.jackson.core
)- CREDITS: suggestion for
tools.jackson
was by Sergei Egorov - Potentially open question: how about Artifact Id? Do we keep
jackson-core
or change tojackson3-core
?- Some expressed desire for unique artifact ids for usage where jar names must be unique to allow Jackson 2.x / 3.x co-existence
- Note: Jackson 1.x -> 2.x did change names of many artifacts (
jackson-mapper-asl
->jackson-databind
), but not all - Current plan is NOT to change artifact id.
- CREDITS: suggestion for
- Java package name change, similarly, would be
com.fasterxml.jackson
totools.jackson
-
jackson-annotations
would be a special case in that it would CONTINUE USING jackson 2.x Maven artifact and Java package names- this implies that Jackson 2.x could use Jackson 3.x annotation package, and vice versa: this is indeed the intent -- no need for duplication of annotations unlike with Jackson 1.x -> 2.x upgrade
For full details and discussion on why proposal is like this, continue reading.
Jackson follows Semantic Versioning, and as such Major Version change planned from 2.x to 3.0 indicates major, backwards-incompatible changes. Such changes are made in order to improve Jackson in ways that would not otherwise be possible, including (but not limited to) things like:
- Removal of deprecated methods in public API (note: Jackson minor versions allow more aggressive removal of internal methods)
- Changes to required abstract methods (for abstract classes and interfaces)
- Renaming of public API classes
- Changes to default settings, behavior
A particular important reason for this specific upgrade, however, is the desire to make 2 core abstractions fully immutable: ObjectMapper
and JsonFactory
(now renamed as TokenStreamFactory
).
This requires combination of above changes, and can not be done in a way that retains Jackson 2.x source level compatibility.
Jackson has already undergone one major version upgrade: from 1.9 to 2.0. We consider that upgrade largely successful and positive, due to changes taken to avoid class-loading collisions across 1.x and 2.x, which essentially allow 1.x and 2.x implementations to co-exist within same JVM. There are of course downsides -- there is no perfect way to upgrade; and it could be argued that need to do major upgrade is a sign of fundamental problems with upgrade -- main complaint being that upgrade process even for simplest cases is more involved than just upgraded dependency version number.
What was done with 1.9-to-2.0 upgrade can be summarized as:
- Move root Java package from
org.codehaus.jackson
tocom.fasterxml.jackson
, to avoid class collisions - Change Maven group id from
org.codehaus.jackson
tocom.fasterxml.jackson[.core]
- Some Maven artifact ids were also changed (like
jackson-mapper-asl
tojackson-databind
), but that was optional cleanup; change of group id would have sufficed for isolation.
- Some Maven artifact ids were also changed (like
One thing that was done to simplify upgrade was to keep most public API type names unchanged -- specifically ObjectMapper
and JsonFactory
(as well as JsonParser
, JsonGenerator
) -- doing this meant that in many cases all that was needed was to mechanically change import
statements and Maven pom.xml
dependency declarations.
With 3.0 we are planning to do somewhat more aggressive class renaming, but keep some of most exposed names as-is (most specific example being JsonFactory
/ JsonParser
/ JsonGenerator
set).
Although upgrade from Jackson 1 to Jackson 2 seemed to go largely well for most users (when they chose to do that), one somewhat painful and potentially unnecessary part was handling of annotations.
Since annotations are type of metadata, and since changes between 1.9 and 2.0 were minimal, it was possible to create value classes (POJOs with no Jackson dependency exception for annotations) that worked with both Jackson 1.x and 2.x -- but if any annotations were required, both 1.x and 2.x annotations were needed as neither could read "other" annotations (note: it is actually possible to implement Jackson AnnotationIntrospector
that DOES understand both -- and such implementations were written by 3rd party developers).
But it seems that it might have been possible to handle annotation package compatibility different from other packages: we will extend on this in sections below, suggesting another way to tackle version evolution for annotations.
We should follow footsteps of Jackson-1-to-Jackson-2 upgrade in most parts, renaming Maven group-id (but none of artifact ids) as well as Java packages, but to keep many of existing high-level API type names unchanged (in cases where there is no important reasons for actually changing names -- for example, for reducing references to "json" for format-agnostic abstractions).
But one exception is that we should consider keeping jackson-annotations
compatible across major versions.
This would require keeping same Maven group and artifact ids, as well as Java package name.
There are some trade-offs -- essentially, difference in versioning may seem confusing to users -- but there is some value in ability to use only a single set of annotations on (non-Jackson) POJOs, regardless of whether Jackson 2.x or 3.x is actually used for processing.
There is one general naming question to decide first: how to change Maven group id. Plan is to:
- Change Maven group ids "com.fasterxml.jackson" -> "tools.jackson" (and same fur sub-groups)
tools.jackson
domain is registered for this use.
We should consistently use the above translation, with the possible exception of jackson-annotations
(see below).
We should keep existing artifact ids, unless there are particularly important reasons to change artifact-id. Currently none of the components is planned to be renamed.
As with 2.x, I think we should use Maven group id, followed with (part of) artifact id as the root package name (omitting "jackson-" prefix from artifact id).
As indicated earlier, basic approach for all other components may not work as well for jackson-annotations
.
This because:
- Annotations are added as metadata on non-Jackson value types, and these should ideally be compatible across many Jackson versions (historically just across all 1.x or 2.x versions)
- Annotation evolution is slower, and so far they have been strictly backwards compatibility across both major versions -- unlike
jackson-core
, or, in particularjackson-databind
. This means that keeping strict compatibility would likely be possible across (otherwise) major version boundary.
So. I propose we keep existing Maven id and Java package names for jackson-annotations
(NOTE: we must keep both group and artifact ids)
This would allow use of a single set of annotations during migration from 2.x to 3.x for processing; as well as exposing value libraries (by 3rd parties) that similarly work fine with both Jackson 2.x and Jackson 3.x
There are some challenges/downsides too:
- Difference in Maven group id between annotations and other components can be confusing to users.
- If we are to publish more 2.x versions, concurrently with 3.0 (a possibility but not certainty), we will probably need to be bit more careful in ensuring version compatibility (probably need to limit or even prevent changes in 2.x series after 2.19, to make 3.x annotations a strict superset of all 2.x annotations)
These do not seem too significant downsides to prevent taking this approach, but are worth considering.
Another related idea for 3.x annotations is to do something that has been planned for a while -- stop releasing patch versions. With Jackson 2.x, all patch versions are identical, and for example 2.9.0 and 2.9.5 have no differences. The reason we publish separate versions is simply because some users felt that doing this is simpler, and works better with existing tooling (such as Maven or Gradle plugins that verify consistent set of versions).
But with addition of jackson-bom
with Jackson 2.8, there is now a better mechanism for getting compatible version sets; something where only single version is needed for reference.
So: part of versioning change is to start publishing jackson-annotations
versions 3.0
, 3.1
and so on; the only exception being if, for some reason, we absolutely have to make a patch release: if so, patch number will be used, but it does NOT have to match patch version of other components.