Skip to content

Commit 9ac3502

Browse files
authored
Migrate to Jackson 3.
This commit migrates the SCIM SDK from Jackson 2 APIs to Jackson 3.1.3. The Jackson 3 release made many backwards-incompatible API changes, so it is no longer feasible to support Jackson 2 further. For this reason, the versions have been updated to 6.0.0-SNAPSHOT. This commit includes other related changes. Some are meant for better alignment with Jackson 3 defaults, and others take advantage of the major version bump. More information is available in the CHANGELOG, but these include: * Updated the default values of the IGNORE_UNKNOWN_FIELDS and USE_GMT_CALENDARS properties. * Removed the PATCH class and MapperFactory methods that were deprecated in 5.1.0. * Removed "throws ScimException" declarations from methods which no longer throw them, allowing clients to avoid unnecessary try/catches. Many important updates have been made to the SCIM SDK after the 5.0.0 release was shipped (e.g., bulk requests), so these updates should not be locked behind a Jackson 3 upgrade. For this reason, this commit was not included with the changes that shipped in 5.1.0. Instead, this commit will be shipped as part of a focused 6.0.0 release. Reviewer: dougbulkley Reviewer: vyhhuang JiraIssue: DS-51372
1 parent 23fb41d commit 9ac3502

119 files changed

Lines changed: 1140 additions & 1653 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ A clear and concise description of what you expected to happen.
1919
**Additional context**
2020
Add any other context about the problem here. For example:
2121
- Java version: [e.g., Java 25]
22-
- SCIM 2 SDK version: [e.g., 5.0.0, master branch]
22+
- SCIM 2 SDK version: [e.g., 6.0.0, master branch]

CHANGELOG.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,71 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## 6.0.0 - 2026-May-11
6+
The UnboundID SCIM SDK has been updated to use version 3 of the Jackson library (this release ships
7+
with v3.1.3). This change aligns the SCIM SDK with HTTP libraries such as Spring Framework 7/Spring
8+
Boot 4, which are moving away from Jackson 2.x. Jackson 2.x can no longer be supported since Jackson
9+
3 contains many backwards-incompatible API changes, design changes, and updated default values. The
10+
most notable updates for applications that use the UnboundID SCIM SDK have been highlighted below:
11+
* `DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES` has been set to `false` by default in
12+
Jackson 3. This marks a major shift: whenever a JSON representing a resource contains extra
13+
fields, the unknown fields are now ignored instead of causing exceptions. This behavior is aligned
14+
with modern API handling, and provides better resilience for applications interacting with
15+
external APIs that may add new fields over time. The SCIM SDK has been updated to use this new
16+
setting and will no longer throw exceptions when extra unknown fields are present in JSON objects.
17+
18+
* Jackson exception objects are no longer checked exceptions. In Jackson 2.x, exceptions were based
19+
on `java.io.IOException`, but in Jackson 3.x, they are based on `java.lang.RuntimeException`. The
20+
SCIM SDK still highlights places where a `JacksonException` is thrown, but it is no longer
21+
mandatory to surround these in a try/catch block. These blocks are likely still useful in cases
22+
when a descriptive error message should be returned.
23+
24+
* Jackson ObjectMappers are now read-only, and their configuration cannot be modified after they
25+
have been built with `JsonMapper.Builder.build()`. To avoid managing object mappers for SCIM uses,
26+
always use `JsonUtils.createJsonMapper()` instead of `new ObjectMapper()` when possible. If you
27+
need to customize the SCIM SDK's object mapper, see `MapperFactory.java`. Note that the previous
28+
`JsonUtils.createObjectMapper()` is equivalent to the new `createJsonMapper()` method.
29+
30+
* Many Jackson classes have been moved or renamed. `TextNode` objects are now `StringNode`, and
31+
`JsonProcessingException` objects from Jackson 2.x no longer exist (these can be replaced with
32+
`JacksonException`). SCIM SDK classes removed or renamed in this release are listed below.
33+
34+
35+
The default values of two configurable SCIM SDK properties have been updated in this release:
36+
* `BaseScimResource.IGNORE_UNKNOWN_FIELDS` is now `true` by default so that unknown JSON fields on
37+
BaseScimResources are ignored instead of throwing exceptions. This change is intended to align
38+
with Jackson 3's new default setting for `FAIL_ON_UNKNOWN_PROPERTIES` (referenced above).
39+
* `DateTimeUtils.USE_GMT_CALENDARS` is now `false` so that Calendars use the `UTC` timezone when
40+
they are initialized from a JSON timestamp. This is intended to provide better default values,
41+
since it is common to use UTC instead of "GMT+00:00", which complicated equals() checks in tests.
42+
* To restore the previous behavior of these properties (not recommended), update the value(s) of the
43+
"com.unboundid.scim2.common.BaseScimResource.ignoreUnknownFields" and/or
44+
"com.unboundid.scim2.common.utils.DateTimeUtils.useGMTCalendars" system properties, or add one of
45+
the following lines of code to your project:
46+
```
47+
BaseScimResource.IGNORE_UNKNOWN_FIELDS = false;
48+
DateTimeUtils.USE_GMT_CALENDARS = true;
49+
```
50+
51+
 
52+
53+
Removed the `com.unboundid.scim2.server.PATCH` annotation class from scim2-sdk-server, which was
54+
deprecated in 5.1.0. Applications should use the `jakarta.ws.rs.PATCH` annotation instead.
55+
56+
Removed several fields in the `MapperFactory` class that were deprecated in 5.1.0. Customizations
57+
should be appended to the `JsonMapper.Builder` object as described by the class-level Javadoc.
58+
59+
Renamed `JsonProcessingExceptionMapper.java` to `JacksonExceptionMapper.java` to reflect the new
60+
naming convention in Jackson.
61+
62+
Removed `throws ScimException` from several methods which no longer threw them. Note that the SCIM
63+
SDK still defines this and its subclasses as a checked exception, so this was not changed like
64+
Jackson exceptions were. ScimExceptions generally indicate failure cases that should be explicitly
65+
handled, such as invalid client requests.
66+
67+
DateDeserializer's implementation is now based on CalendarDeserializer. The most notable change is
68+
that DateDeserializer now supports UNIX timestamp values.
69+
570
## v5.1.0 - 2026-May-11
671
Added support for bulk operations, requests, and responses as defined by the SCIM standard. To get
772
started with implementing bulk request support for client or server applications, see the

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,19 @@ with SCIM 2.0 clients or servers:
4444
that thoroughly explains SCIM concepts and semantics, such as
4545
[service provider configuration](https://javadoc.io/doc/com.unboundid.product.scim2/scim2-parent/latest/com/unboundid/scim2/common/types/ServiceProviderConfigResource.html)
4646
and [bulk requests](https://javadoc.io/doc/com.unboundid.product.scim2/scim2-parent/latest/com/unboundid/scim2/common/bulk/BulkRequest.html).
47+
* The core `scim2-sdk-common` module only contains a dependency on Jackson, so this library won't
48+
contribute to a complex dependency tree in your project.
4749
* As with other Java libraries, this SDK can be used in projects written in other JVM languages such
4850
as Kotlin and Scala.
4951
* Full support for interacting with Ping Identity SCIM services such as the
5052
[PingOne SCIM API](https://developer.pingidentity.com/pingone-api/platform/scim.html).
5153

5254
## Supported Versions
5355
As of version 4.0.0, the UnboundID SCIM SDK requires Java SE 17 or greater.
54-
This library also depends on the Jackson 2.x libraries for JSON serialization and deserialization.
56+
57+
As of version 6.0.0, [Jackson 3](https://github.com/FasterXML/jackson) is leveraged for high
58+
performance JSON processing and for broad compatibility with other HTTP libraries. For Jackson 2
59+
support, use the latest release before 6.0.0.
5560

5661
## Structure
5762
This library is separated into multiple modules to target specific use cases, and consists of the
@@ -72,9 +77,9 @@ More information on each section:
7277
* `scim2-sdk-client`: This component helps create SCIM 2 client applications using
7378
[JAX-RS](https://projects.eclipse.org/projects/ee4j.rest). For more information, see the
7479
[wiki](https://github.com/pingidentity/scim2/wiki/JAX-RS-Client-examples).
75-
* `scim2-sdk-server`: This component helps create SCIM 2 services using JAX-RS. If you are not using
76-
JAX-RS and are using another solution (e.g., Spring), the `scim2-sdk-common` component is
77-
generally a better choice and may be used directly.
80+
* `scim2-sdk-server`: This component helps create SCIM 2 services using JAX-RS. If you are using a
81+
different solution (e.g., [Spring](https://spring.io/projects/spring-framework)),
82+
the `scim2-sdk-common` component is generally a better choice and may be used directly.
7883
* `scim2-ubid-extensions`: Provides model classes specific to Ping Identity based constructs and
7984
SCIM extensions. This component is subject to API changes and should be considered experimental.
8085
* `scim2-parent`: The parent module for all of the other components.
@@ -203,7 +208,7 @@ Note that Ping Identity does not accept third-party code contributions.
203208
## License
204209
As of the 5.0.0 release, the UnboundID SCIM SDK is available under the terms of the following
205210
licenses:
206-
* The [Apache License, version 2.0](LICENSE.md) (recommended).
211+
* The [Apache License, version 2.0](LICENSE.md) (recommended)
207212
* The GNU General Public License version 2 ([GPLv2](resource/LICENSE-GPLv2.txt))
208213
* The GNU Lesser General Public License version 2.1 ([LGPLv2.1](resource/LICENSE-LGPLv2.1.txt))
209214
* The legacy [UnboundID Free Use License](resource/LICENSE-UnboundID-SCIM2.txt)

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
8585
<compileSource>17</compileSource>
8686
<main.basedir>${project.basedir}</main.basedir>
87-
<jackson.version>2.21.3</jackson.version>
87+
<jackson.version>3.1.3</jackson.version>
8888
<jackson-annotations.version>2.21</jackson-annotations.version>
8989
<jakarta-rs.version>4.0.0</jakarta-rs.version>
9090
<jersey.version>4.0.2</jersey.version>
@@ -380,7 +380,7 @@
380380
<version>${project.version}</version>
381381
</dependency>
382382
<dependency>
383-
<groupId>com.fasterxml.jackson.core</groupId>
383+
<groupId>tools.jackson.core</groupId>
384384
<artifactId>jackson-core</artifactId>
385385
<version>${jackson.version}</version>
386386
</dependency>
@@ -390,17 +390,17 @@
390390
<version>${jackson-annotations.version}</version>
391391
</dependency>
392392
<dependency>
393-
<groupId>com.fasterxml.jackson.core</groupId>
393+
<groupId>tools.jackson.core</groupId>
394394
<artifactId>jackson-databind</artifactId>
395395
<version>${jackson.version}</version>
396396
</dependency>
397397
<dependency>
398-
<groupId>com.fasterxml.jackson.jakarta.rs</groupId>
398+
<groupId>tools.jackson.jakarta.rs</groupId>
399399
<artifactId>jackson-jakarta-rs-base</artifactId>
400400
<version>${jackson.version}</version>
401401
</dependency>
402402
<dependency>
403-
<groupId>com.fasterxml.jackson.jakarta.rs</groupId>
403+
<groupId>tools.jackson.jakarta.rs</groupId>
404404
<artifactId>jackson-jakarta-rs-json-provider</artifactId>
405405
<version>${jackson.version}</version>
406406
</dependency>

scim2-sdk-client/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,15 @@
197197
<artifactId>scim2-sdk-common</artifactId>
198198
</dependency>
199199
<dependency>
200-
<groupId>com.fasterxml.jackson.core</groupId>
200+
<groupId>tools.jackson.core</groupId>
201201
<artifactId>jackson-core</artifactId>
202202
</dependency>
203203
<dependency>
204-
<groupId>com.fasterxml.jackson.core</groupId>
204+
<groupId>tools.jackson.core</groupId>
205205
<artifactId>jackson-databind</artifactId>
206206
</dependency>
207207
<dependency>
208-
<groupId>com.fasterxml.jackson.jakarta.rs</groupId>
208+
<groupId>tools.jackson.jakarta.rs</groupId>
209209
<artifactId>jackson-jakarta-rs-json-provider</artifactId>
210210
</dependency>
211211
<dependency>

scim2-sdk-client/src/main/java/com/unboundid/scim2/client/ScimService.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
package com.unboundid.scim2.client;
3434

35-
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider;
3635
import com.unboundid.scim2.client.requests.BulkRequestBuilder;
3736
import com.unboundid.scim2.client.requests.CreateRequestBuilder;
3837
import com.unboundid.scim2.client.requests.DeleteRequestBuilder;
@@ -52,6 +51,7 @@
5251
import com.unboundid.scim2.common.types.SchemaResource;
5352
import com.unboundid.scim2.common.types.ServiceProviderConfigResource;
5453
import com.unboundid.scim2.common.utils.JsonUtils;
54+
import tools.jackson.jakarta.rs.json.JacksonJsonProvider;
5555

5656
import jakarta.ws.rs.client.WebTarget;
5757
import jakarta.ws.rs.core.MediaType;
@@ -99,9 +99,8 @@ public class ScimService implements ScimInterface
9999
*/
100100
public ScimService(@NotNull final WebTarget baseTarget)
101101
{
102-
this.baseTarget = baseTarget.register(
103-
new JacksonJsonProvider(JsonUtils.createObjectMapper(),
104-
JacksonJsonProvider.BASIC_ANNOTATIONS));
102+
var mapper = JsonUtils.createJsonMapper();
103+
this.baseTarget = baseTarget.register(new JacksonJsonProvider(mapper));
105104
}
106105

107106
/**
@@ -535,12 +534,10 @@ public <T extends ScimResource> ModifyRequestBuilder.Generic<T> modifyRequest(
535534
* @param id The resource identifier.
536535
* @return The request builder that may be used to specify additional request
537536
* parameters and to invoke the request.
538-
* @throws ScimException if an error occurs.
539537
*/
540538
@NotNull
541539
public DeleteRequestBuilder deleteRequest(@NotNull final String endpoint,
542540
@NotNull final String id)
543-
throws ScimException
544541
{
545542
return new DeleteRequestBuilder(baseTarget.path(endpoint).path(id));
546543
}
@@ -551,11 +548,9 @@ public DeleteRequestBuilder deleteRequest(@NotNull final String endpoint,
551548
* @param url The URL of the resource to delete.
552549
* @return The request builder that may be used to specify additional request
553550
* parameters and to invoke the request.
554-
* @throws ScimException if an error occurs.
555551
*/
556552
@NotNull
557553
public DeleteRequestBuilder deleteRequest(@NotNull final URI url)
558-
throws ScimException
559554
{
560555
return new DeleteRequestBuilder(resolveWebTarget(url));
561556
}
@@ -567,12 +562,10 @@ public DeleteRequestBuilder deleteRequest(@NotNull final URI url)
567562
* @param <T> The Java type of the resource.
568563
* @return The request builder that may be used to specify additional request
569564
* parameters and to invoke the request.
570-
* @throws ScimException if an error occurs.
571565
*/
572566
@NotNull
573567
public <T extends ScimResource> DeleteRequestBuilder deleteRequest(
574568
@NotNull final T resource)
575-
throws ScimException
576569
{
577570
return deleteRequest(checkAndGetLocation(resource));
578571
}

scim2-sdk-client/src/main/java/com/unboundid/scim2/client/SearchResultHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232

3333
package com.unboundid.scim2.client;
3434

35-
import com.fasterxml.jackson.databind.node.ObjectNode;
3635
import com.unboundid.scim2.common.annotations.NotNull;
3736
import com.unboundid.scim2.common.annotations.Nullable;
37+
import tools.jackson.databind.node.ObjectNode;
3838

3939
/**
4040
* An interface for handling the search result response. Methods will be called

scim2-sdk-client/src/main/java/com/unboundid/scim2/client/requests/BulkRequestBuilder.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import jakarta.ws.rs.client.Entity;
4444
import jakarta.ws.rs.client.WebTarget;
4545
import jakarta.ws.rs.core.Response;
46-
4746
import java.util.ArrayList;
4847
import java.util.Arrays;
4948
import java.util.List;

scim2-sdk-client/src/main/java/com/unboundid/scim2/client/requests/ListResponseBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232

3333
package com.unboundid.scim2.client.requests;
3434

35-
import com.fasterxml.jackson.databind.node.ObjectNode;
3635
import com.unboundid.scim2.client.SearchResultHandler;
3736
import com.unboundid.scim2.common.annotations.NotNull;
3837
import com.unboundid.scim2.common.annotations.Nullable;
3938
import com.unboundid.scim2.common.messages.ListResponse;
39+
import tools.jackson.databind.node.ObjectNode;
4040

4141
import java.util.LinkedList;
4242
import java.util.List;

scim2-sdk-client/src/main/java/com/unboundid/scim2/client/requests/ModifyRequestBuilder.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
package com.unboundid.scim2.client.requests;
3434

35-
import com.fasterxml.jackson.databind.JsonNode;
3635
import com.unboundid.scim2.common.Path;
3736
import com.unboundid.scim2.common.ScimResource;
3837
import com.unboundid.scim2.common.annotations.NotNull;
@@ -41,6 +40,7 @@
4140
import com.unboundid.scim2.common.messages.PatchOperation;
4241
import com.unboundid.scim2.common.messages.PatchRequest;
4342
import com.unboundid.scim2.common.utils.JsonUtils;
43+
import tools.jackson.databind.JsonNode;
4444

4545
import jakarta.ws.rs.HttpMethod;
4646
import jakarta.ws.rs.ProcessingException;
@@ -49,7 +49,6 @@
4949
import jakarta.ws.rs.client.WebTarget;
5050
import jakarta.ws.rs.core.HttpHeaders;
5151
import jakarta.ws.rs.core.Response;
52-
5352
import java.util.Collection;
5453
import java.util.LinkedList;
5554
import java.util.List;
@@ -433,11 +432,11 @@ public T removeValues(@NotNull final String path)
433432
* @param path The path to the attribute whose value to remove.
434433
*
435434
* @return This patch operation request.
436-
* @throws ScimException If the path is invalid.
435+
* @throws IllegalArgumentException If the path is invalid.
437436
*/
438437
@NotNull
439438
public T removeValues(@NotNull final Path path)
440-
throws ScimException
439+
throws IllegalArgumentException
441440
{
442441
return addOperation(PatchOperation.remove(path));
443442
}

0 commit comments

Comments
 (0)