Skip to content

Commit f1ed0c7

Browse files
committed
feat: LDContext is java.io.Serializable
1 parent f40c86e commit f1ed0c7

5 files changed

Lines changed: 56 additions & 2 deletions

File tree

lib/shared/common/src/main/java/com/launchdarkly/sdk/AttributeMap.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.launchdarkly.sdk;
22

3+
import java.io.Serializable;
34
import java.util.HashMap;
45
import java.util.Map;
56

6-
final class AttributeMap {
7+
final class AttributeMap implements Serializable {
78
private final AttributeMap parent;
89
private final Map<String, LDValue> map;
910

lib/shared/common/src/main/java/com/launchdarkly/sdk/LDValueBool.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,10 @@ public String toJsonString() {
3838
void write(JsonWriter writer) throws IOException {
3939
writer.value(value);
4040
}
41+
42+
// Preserve singleton identity after Java deserialization, since equals() for booleans
43+
// relies on TRUE and FALSE being singletons.
44+
private Object readResolve() {
45+
return fromBoolean(value);
46+
}
4147
}

lib/shared/common/src/main/java/com/launchdarkly/sdk/LDValueNull.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public String toJsonString() {
2626
void write(JsonWriter writer) throws IOException {
2727
writer.nullValue();
2828
}
29+
30+
// Preserve singleton identity after Java deserialization.
31+
private Object readResolve() {
32+
return INSTANCE;
33+
}
2934
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.launchdarkly.sdk.json;
22

3+
import java.io.Serializable;
4+
35
/**
46
* Marker interface for SDK classes that have a custom JSON serialization.
57
*
68
* @see JsonSerialization
79
* @see LDGson
810
*/
9-
public interface JsonSerializable {
11+
public interface JsonSerializable extends Serializable {
1012
}

lib/shared/common/src/test/java/com/launchdarkly/sdk/LDContextTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
import org.junit.Test;
66

7+
import java.io.ByteArrayInputStream;
8+
import java.io.ByteArrayOutputStream;
9+
import java.io.ObjectInputStream;
10+
import java.io.ObjectOutputStream;
711
import java.util.ArrayList;
812
import java.util.List;
913

@@ -437,4 +441,40 @@ public void contextFromUserErrors() {
437441
assertThat(c2.isValid(), is(false));
438442
assertThat(c2.getError(), equalTo(Errors.CONTEXT_NO_KEY));
439443
}
444+
445+
@Test
446+
public void javaSerializationRoundTripSingleKind() throws Exception {
447+
LDContext c = LDContext.builder(kind1, "my-key")
448+
.name("my-name")
449+
.anonymous(true)
450+
.set("email", "x@example.com")
451+
.set("happy", true)
452+
.set("count", 3)
453+
.set("tags", LDValue.buildArray().add("a").add("b").build())
454+
.set("nested", LDValue.buildObject().put("inner", "v").build())
455+
.privateAttributes("email")
456+
.build();
457+
458+
assertThat(javaSerializeAndDeserialize(c), equalTo(c));
459+
}
460+
461+
@Test
462+
public void javaSerializationRoundTripMultiKind() throws Exception {
463+
LDContext c = LDContext.createMulti(
464+
LDContext.builder(kind1, "key1").set("a", "b").build(),
465+
LDContext.builder(kind2, "key2").set("c", LDValue.buildArray().add(1).add(2).build()).build()
466+
);
467+
468+
assertThat(javaSerializeAndDeserialize(c), equalTo(c));
469+
}
470+
471+
private static LDContext javaSerializeAndDeserialize(LDContext c) throws Exception {
472+
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
473+
try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
474+
out.writeObject(c);
475+
}
476+
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
477+
return (LDContext) in.readObject();
478+
}
479+
}
440480
}

0 commit comments

Comments
 (0)