Skip to content

Commit 649f171

Browse files
authored
No longer serialize static fields; use toString as fallback (#2309)
1 parent ba49577 commit 649f171

File tree

9 files changed

+342
-7
lines changed

9 files changed

+342
-7
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Ensure potential callback exceptions are caught #2123 ([#2291](https://github.com/getsentry/sentry-java/pull/2291))
88
- Remove verbose FrameMetricsAggregator failure logging ([#2293](https://github.com/getsentry/sentry-java/pull/2293))
99
- Ignore broken regex for tracePropagationTarget ([#2288](https://github.com/getsentry/sentry-java/pull/2288))
10+
- No longer serialize static fields; use toString as fallback ([#2309](https://github.com/getsentry/sentry-java/pull/2309))
1011
- Fix `SentryFileWriter`/`SentryFileOutputStream` append overwrites file contents ([#2304](https://github.com/getsentry/sentry-java/pull/2304))
1112
- Respect incoming parent sampled decision when continuing a trace ([#2311](https://github.com/getsentry/sentry-java/pull/2311))
1213

sentry/api/sentry.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3304,6 +3304,12 @@ public final class io/sentry/util/HttpUtils {
33043304
public static fun containsSensitiveHeader (Ljava/lang/String;)Z
33053305
}
33063306

3307+
public final class io/sentry/util/JsonSerializationUtils {
3308+
public fun <init> ()V
3309+
public static fun atomicIntegerArrayToList (Ljava/util/concurrent/atomic/AtomicIntegerArray;)Ljava/util/List;
3310+
public static fun calendarToMap (Ljava/util/Calendar;)Ljava/util/Map;
3311+
}
3312+
33073313
public final class io/sentry/util/LogUtils {
33083314
public fun <init> ()V
33093315
public static fun logNotInstanceOf (Ljava/lang/Class;Ljava/lang/Object;Lio/sentry/ILogger;)V

sentry/src/main/java/io/sentry/JsonObjectSerializer.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
package io.sentry;
22

3+
import static io.sentry.util.JsonSerializationUtils.atomicIntegerArrayToList;
4+
import static io.sentry.util.JsonSerializationUtils.calendarToMap;
5+
36
import java.io.IOException;
7+
import java.net.InetAddress;
8+
import java.net.URI;
49
import java.util.Arrays;
10+
import java.util.Calendar;
511
import java.util.Collection;
12+
import java.util.Currency;
613
import java.util.Date;
14+
import java.util.Locale;
715
import java.util.Map;
816
import java.util.TimeZone;
17+
import java.util.UUID;
18+
import java.util.concurrent.atomic.AtomicBoolean;
19+
import java.util.concurrent.atomic.AtomicIntegerArray;
920
import org.jetbrains.annotations.ApiStatus;
1021
import org.jetbrains.annotations.NotNull;
1122
import org.jetbrains.annotations.Nullable;
@@ -46,6 +57,22 @@ public void serialize(
4657
serializeCollection(writer, logger, Arrays.asList((Object[]) object));
4758
} else if (object instanceof Map) {
4859
serializeMap(writer, logger, (Map<?, ?>) object);
60+
} else if (object instanceof Locale) {
61+
writer.value(object.toString());
62+
} else if (object instanceof AtomicIntegerArray) {
63+
serializeCollection(writer, logger, atomicIntegerArrayToList((AtomicIntegerArray) object));
64+
} else if (object instanceof AtomicBoolean) {
65+
writer.value(((AtomicBoolean) object).get());
66+
} else if (object instanceof URI) {
67+
writer.value(object.toString());
68+
} else if (object instanceof InetAddress) {
69+
writer.value(object.toString());
70+
} else if (object instanceof UUID) {
71+
writer.value(object.toString());
72+
} else if (object instanceof Currency) {
73+
writer.value(object.toString());
74+
} else if (object instanceof Calendar) {
75+
serializeMap(writer, logger, calendarToMap((Calendar) object));
4976
} else if (object.getClass().isEnum()) {
5077
writer.value(object.toString());
5178
} else {

sentry/src/main/java/io/sentry/JsonReflectionObjectSerializer.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
package io.sentry;
22

3+
import static io.sentry.util.JsonSerializationUtils.atomicIntegerArrayToList;
4+
import static io.sentry.util.JsonSerializationUtils.calendarToMap;
5+
36
import java.lang.reflect.Field;
47
import java.lang.reflect.Modifier;
8+
import java.net.InetAddress;
9+
import java.net.URI;
510
import java.util.ArrayList;
11+
import java.util.Calendar;
612
import java.util.Collection;
13+
import java.util.Currency;
714
import java.util.HashMap;
815
import java.util.HashSet;
916
import java.util.List;
17+
import java.util.Locale;
1018
import java.util.Map;
1119
import java.util.Set;
20+
import java.util.UUID;
21+
import java.util.concurrent.atomic.AtomicBoolean;
22+
import java.util.concurrent.atomic.AtomicIntegerArray;
1223
import org.jetbrains.annotations.ApiStatus;
1324
import org.jetbrains.annotations.NotNull;
1425
import org.jetbrains.annotations.Nullable;
@@ -39,6 +50,22 @@ public final class JsonReflectionObjectSerializer {
3950
return object;
4051
} else if (object instanceof String) {
4152
return object;
53+
} else if (object instanceof Locale) {
54+
return object.toString();
55+
} else if (object instanceof AtomicIntegerArray) {
56+
return atomicIntegerArrayToList((AtomicIntegerArray) object);
57+
} else if (object instanceof AtomicBoolean) {
58+
return ((AtomicBoolean) object).get();
59+
} else if (object instanceof URI) {
60+
return object.toString();
61+
} else if (object instanceof InetAddress) {
62+
return object.toString();
63+
} else if (object instanceof UUID) {
64+
return object.toString();
65+
} else if (object instanceof Currency) {
66+
return object.toString();
67+
} else if (object instanceof Calendar) {
68+
return calendarToMap((Calendar) object);
4269
} else if (object.getClass().isEnum()) {
4370
return object.toString();
4471
} else {
@@ -63,7 +90,12 @@ public final class JsonReflectionObjectSerializer {
6390
} else if (object instanceof Map) {
6491
serializedObject = map((Map<?, ?>) object, logger);
6592
} else {
66-
serializedObject = serializeObject(object, logger);
93+
@NotNull Map<String, Object> objectAsMap = serializeObject(object, logger);
94+
if (objectAsMap.isEmpty()) {
95+
serializedObject = object.toString();
96+
} else {
97+
serializedObject = objectAsMap;
98+
}
6799
}
68100
} catch (Exception exception) {
69101
logger.log(SentryLevel.INFO, "Not serializing object due to throwing sub-path.", exception);
@@ -84,6 +116,9 @@ public final class JsonReflectionObjectSerializer {
84116
if (Modifier.isTransient(field.getModifiers())) {
85117
continue;
86118
}
119+
if (Modifier.isStatic(field.getModifiers())) {
120+
continue;
121+
}
87122
String fieldName = field.getName();
88123
try {
89124
field.setAccessible(true);
@@ -94,6 +129,7 @@ public final class JsonReflectionObjectSerializer {
94129
logger.log(SentryLevel.INFO, "Cannot access field " + fieldName + ".");
95130
}
96131
}
132+
97133
return map;
98134
}
99135

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.sentry.util;
2+
3+
import java.util.ArrayList;
4+
import java.util.Calendar;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.concurrent.atomic.AtomicIntegerArray;
9+
import org.jetbrains.annotations.ApiStatus;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
@ApiStatus.Internal
13+
public final class JsonSerializationUtils {
14+
15+
public static @NotNull Map<String, Object> calendarToMap(final @NotNull Calendar calendar) {
16+
final @NotNull Map<String, Object> map = new HashMap<>();
17+
18+
map.put("year", calendar.get(Calendar.YEAR));
19+
map.put("month", calendar.get(Calendar.MONTH));
20+
map.put("dayOfMonth", calendar.get(Calendar.DAY_OF_MONTH));
21+
map.put("hourOfDay", calendar.get(Calendar.HOUR_OF_DAY));
22+
map.put("minute", calendar.get(Calendar.MINUTE));
23+
map.put("second", calendar.get(Calendar.SECOND));
24+
25+
return map;
26+
}
27+
28+
public static @NotNull List<Object> atomicIntegerArrayToList(
29+
final @NotNull AtomicIntegerArray array) {
30+
final int numberOfItems = array.length();
31+
final @NotNull List<Object> list = new ArrayList<>(numberOfItems);
32+
for (int i = 0; i < numberOfItems; i++) {
33+
list.add(array.get(i));
34+
}
35+
return list;
36+
}
37+
}

sentry/src/test/java/io/sentry/JsonObjectSerializerTest.kt

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
package io.sentry
22

3+
import com.nhaarman.mockitokotlin2.inOrder
34
import com.nhaarman.mockitokotlin2.mock
5+
import com.nhaarman.mockitokotlin2.times
46
import com.nhaarman.mockitokotlin2.verify
57
import org.junit.Test
8+
import java.net.URI
9+
import java.util.Calendar
10+
import java.util.Currency
11+
import java.util.Locale
612
import java.util.TimeZone
13+
import java.util.UUID
14+
import java.util.concurrent.atomic.AtomicBoolean
15+
import java.util.concurrent.atomic.AtomicIntegerArray
716

817
internal class JsonObjectSerializerTest {
918

@@ -114,9 +123,9 @@ internal class JsonObjectSerializerTest {
114123

115124
@Test
116125
fun `serialize unknown object without data`() {
117-
fixture.getSUT().serialize(fixture.writer, fixture.logger, object {})
118-
verify(fixture.writer).beginObject()
119-
verify(fixture.writer).endObject()
126+
val value = object {}
127+
fixture.getSUT().serialize(fixture.writer, fixture.logger, value)
128+
verify(fixture.writer).value(value.toString())
120129
}
121130

122131
@Test
@@ -166,10 +175,107 @@ internal class JsonObjectSerializerTest {
166175
verify(fixture.writer).endObject()
167176
}
168177

178+
@Test
179+
fun `serialize locale`() {
180+
val inOrder = inOrder(fixture.writer)
181+
fixture.getSUT().serialize(fixture.writer, fixture.logger, Locale.US)
182+
183+
inOrder.verify(fixture.writer).value("en_US")
184+
}
185+
186+
@Test
187+
fun `serialize locale in map`() {
188+
val map = mapOf<String, Locale>("one" to Locale.US)
189+
val inOrder = inOrder(fixture.writer)
190+
fixture.getSUT().serialize(fixture.writer, fixture.logger, map)
191+
inOrder.verify(fixture.writer).beginObject()
192+
inOrder.verify(fixture.writer).name("one")
193+
inOrder.verify(fixture.writer).value("en_US")
194+
inOrder.verify(fixture.writer).endObject()
195+
}
196+
197+
@Test
198+
fun `serialize locale in list`() {
199+
val list = listOf<Locale>(Locale.US, Locale.GERMAN)
200+
val inOrder = inOrder(fixture.writer)
201+
fixture.getSUT().serialize(fixture.writer, fixture.logger, list)
202+
inOrder.verify(fixture.writer).beginArray()
203+
inOrder.verify(fixture.writer).value("en_US")
204+
inOrder.verify(fixture.writer).value("de")
205+
inOrder.verify(fixture.writer).endArray()
206+
}
207+
208+
@Test
209+
fun `serialize locale in object`() {
210+
val obj = ClassWithLocaleProperty(Locale.US)
211+
val inOrder = inOrder(fixture.writer)
212+
fixture.getSUT().serialize(fixture.writer, fixture.logger, obj)
213+
inOrder.verify(fixture.writer).beginObject()
214+
inOrder.verify(fixture.writer).name("localeProperty")
215+
inOrder.verify(fixture.writer).value("en_US")
216+
inOrder.verify(fixture.writer).endObject()
217+
}
218+
219+
@Test
220+
fun `serializing AtomicIntegerArray`() {
221+
fixture.getSUT().serialize(fixture.writer, fixture.logger, AtomicIntegerArray(arrayOf(1, 2, 3).toIntArray()))
222+
verify(fixture.writer).beginArray()
223+
verify(fixture.writer).value(1 as Number)
224+
verify(fixture.writer).value(2 as Number)
225+
verify(fixture.writer).value(3 as Number)
226+
verify(fixture.writer).endArray()
227+
}
228+
229+
@Test
230+
fun `serializing AtomicBoolean`() {
231+
fixture.getSUT().serialize(fixture.writer, fixture.logger, AtomicBoolean(true))
232+
verify(fixture.writer).value(true)
233+
}
234+
235+
@Test
236+
fun `serializing URI`() {
237+
fixture.getSUT().serialize(fixture.writer, fixture.logger, URI("http://localhost:8081/api/product?id=99"))
238+
verify(fixture.writer).value("http://localhost:8081/api/product?id=99")
239+
}
240+
241+
@Test
242+
fun `serializing UUID`() {
243+
fixture.getSUT().serialize(fixture.writer, fixture.logger, UUID.fromString("828900a5-15dc-413f-8c17-6ef04d74e074"))
244+
verify(fixture.writer).value("828900a5-15dc-413f-8c17-6ef04d74e074")
245+
}
246+
247+
@Test
248+
fun `serializing Currency`() {
249+
fixture.getSUT().serialize(fixture.writer, fixture.logger, Currency.getInstance("USD"))
250+
verify(fixture.writer).value("USD")
251+
}
252+
253+
@Test
254+
fun `serializing Calendar`() {
255+
val calendar = Calendar.getInstance()
256+
calendar.set(2022, 0, 1, 11, 59, 58)
257+
fixture.getSUT().serialize(fixture.writer, fixture.logger, calendar)
258+
verify(fixture.writer).beginObject()
259+
verify(fixture.writer).name("year")
260+
verify(fixture.writer).value(2022 as java.lang.Integer)
261+
verify(fixture.writer).name("month")
262+
verify(fixture.writer).value(0 as java.lang.Integer)
263+
verify(fixture.writer).name("dayOfMonth")
264+
verify(fixture.writer).value(1 as java.lang.Integer)
265+
verify(fixture.writer).name("hourOfDay")
266+
verify(fixture.writer).value(11 as java.lang.Integer)
267+
verify(fixture.writer).name("minute")
268+
verify(fixture.writer).value(59 as java.lang.Integer)
269+
verify(fixture.writer).name("second")
270+
verify(fixture.writer).value(58 as java.lang.Integer)
271+
verify(fixture.writer).endObject()
272+
}
273+
169274
class UnknownClassWithData(
170275
private val integer: Int,
171276
private val string: String
172277
)
173278
}
174279

175280
data class ClassWithEnumProperty(val enumProperty: DataCategory)
281+
data class ClassWithLocaleProperty(val localeProperty: Locale)

0 commit comments

Comments
 (0)