Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## Release Notes

### 0.12.8 (pending release)

This patch release:
*
* Updates Jackson usage (in `jjwt-jackson`) to use immutable classes instead of using `ObjectMapper` directly.

### 0.12.7

This patch release:
Expand Down Expand Up @@ -445,6 +451,7 @@ provided the JJWT team.
This patch release:

* Adds additional handling for rare JSON parsing exceptions and wraps them in a `JwtException` to allow the application to handle these conditions as JWT concerns.
* Upgrades the `jjwt-jackson` module's Jackson dependency to `2.12.4`.
* Upgrades the `jjwt-jackson` module's Jackson dependency to `2.12.6.1`.
* Upgrades the `jjwt-orgjson` module's org.json:json dependency to `20220320`.
* Upgrades the `jjwt-gson` module's gson dependency to `2.9.0`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.jsonwebtoken.io.AbstractDeserializer;
Expand All @@ -37,7 +39,7 @@ public class JacksonDeserializer<T> extends AbstractDeserializer<T> {

private final Class<T> returnType;

private final ObjectMapper objectMapper;
private final ObjectReader objectReader;

/**
* Constructor using JJWT's default {@link ObjectMapper} singleton for deserialization.
Expand Down Expand Up @@ -116,24 +118,27 @@ public JacksonDeserializer(ObjectMapper objectMapper) {
* @since 0.12.4
*/
public JacksonDeserializer(ObjectMapper objectMapper, Map<String, Class<?>> claimTypeMap) {
this(objectMapper);
Assert.notNull(claimTypeMap, "Claim type map cannot be null.");
// register a new Deserializer on the ObjectMapper instance:
SimpleModule module = new SimpleModule();
module.addDeserializer(Object.class, new MappedTypeDeserializer(Collections.unmodifiableMap(claimTypeMap)));
objectMapper.registerModule(module);
this(objectMapper.registerModule(mappedTypeModule(claimTypeMap)));
}

private JacksonDeserializer(ObjectMapper objectMapper, Class<T> returnType) {
Assert.notNull(objectMapper, "ObjectMapper cannot be null.");
Assert.notNull(returnType, "Return type cannot be null.");
this.objectMapper = objectMapper;
this.objectReader = objectMapper.reader();
this.returnType = returnType;
}

@Override
protected T doDeserialize(Reader reader) throws Exception {
return objectMapper.readValue(reader, returnType);
return objectReader.readValue(reader, returnType);
}

private static Module mappedTypeModule(Map<String, Class<?>> claimTypeMap) {
Assert.notNull(claimTypeMap, "Claim type map cannot be null.");
SimpleModule module = new SimpleModule();
module.addDeserializer(Object.class, new MappedTypeDeserializer(Collections.unmodifiableMap(claimTypeMap)));
return module;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static ObjectMapper newObjectMapper() {
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // https://github.com/jwtk/jjwt/issues/893
}

protected final ObjectMapper objectMapper;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just quickly rebased this, but I want to take another look when I have a few more minutes.

This is a breaking change, the point of this change though is to avoid mutation of the ObjectMapper, but this will require tweaking the change log (mentioning the breaking change, and NOT making this change in a patch release)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok, so gotta wait until 1.0 I suppose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you even specified that milestone! Sorry for the noise 🤦

private final ObjectWriter objectWriter;

/**
* Constructor using JJWT's default {@link ObjectMapper} singleton for serialization.
Expand All @@ -80,13 +80,15 @@ public JacksonSerializer() {
*/
public JacksonSerializer(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "ObjectMapper cannot be null.");
this.objectMapper = objectMapper.registerModule(MODULE);
this.objectWriter = objectMapper
.registerModule(MODULE)
.writer();
}

@Override
protected void doSerialize(T t, OutputStream out) throws Exception {
Assert.notNull(out, "OutputStream cannot be null.");
ObjectWriter writer = this.objectMapper.writer().without(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
ObjectWriter writer = this.objectWriter.without(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
writer.writeValue(out, t);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ class JacksonDeserializerTest {

@Test
void testDefaultConstructor() {
assertSame JacksonSerializer.DEFAULT_OBJECT_MAPPER, deserializer.objectMapper
assertSame JacksonSerializer.DEFAULT_OBJECT_MAPPER.getDeserializationConfig(), deserializer.objectReader.config
}

@Test
void testObjectMapperConstructor() {
def customOM = new ObjectMapper()
deserializer = new JacksonDeserializer<>(customOM)
assertSame customOM, deserializer.objectMapper
assertSame customOM.getDeserializationConfig(), deserializer.objectReader.config
}

@Test(expected = IllegalArgumentException)
Expand Down Expand Up @@ -152,7 +152,7 @@ class JacksonDeserializerTest {
*/
@Test
void testIgnoreUnknownPropertiesWhenDeserializeWithCustomObject() {

long currentTime = System.currentTimeMillis()

String json = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.jsonwebtoken.jackson.io

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.ObjectWriter
import io.jsonwebtoken.io.Serializer
import io.jsonwebtoken.lang.Strings
import org.junit.Before
Expand Down Expand Up @@ -47,14 +48,14 @@ class JacksonSerializerTest {

@Test
void testDefaultConstructor() {
assertSame JacksonSerializer.DEFAULT_OBJECT_MAPPER, ser.objectMapper
assertSame JacksonSerializer.DEFAULT_OBJECT_MAPPER.getSerializationConfig(), ser.objectWriter.config
}

@Test
void testObjectMapperConstructor() {
ObjectMapper customOM = new ObjectMapper()
ser = new JacksonSerializer(customOM)
assertSame customOM, ser.objectMapper
assertSame customOM.getSerializationConfig(), ser.objectWriter.config
}

@Test(expected = IllegalArgumentException)
Expand All @@ -65,8 +66,10 @@ class JacksonSerializerTest {
@Test
void testObjectMapperConstructorAutoRegistersModule() {
ObjectMapper om = createMock(ObjectMapper)
ObjectWriter writer = createMock(ObjectWriter)
expect(om.registerModule(same(JacksonSerializer.MODULE))).andReturn(om)
replay om
expect(om.writer()).andReturn(writer)
replay om, writer
//noinspection GroovyResultOfObjectAllocationIgnored
new JacksonSerializer<>(om)
verify om
Expand Down