diff --git a/core-api/src/main/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializer.java b/core-api/src/main/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializer.java index a914f3e90..58ad50d81 100644 --- a/core-api/src/main/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializer.java +++ b/core-api/src/main/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializer.java @@ -22,6 +22,8 @@ import com.optimizely.ab.config.parser.MissingJsonParserException; import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.concurrent.Callable; /** * Factory for generating {@link Serializer} instances, based on the json library available on the classpath. @@ -48,22 +50,27 @@ public static Serializer getInstance() { private static @Nonnull Serializer create() { Serializer serializer; - - if (isPresent("com.fasterxml.jackson.databind.ObjectMapper")) { - serializer = new JacksonSerializer(); - } else if (isPresent("com.google.gson.Gson")) { - serializer = new GsonSerializer(); - } else if (isPresent("org.json.simple.JSONObject")) { - serializer = new JsonSimpleSerializer(); - } else if (isPresent("org.json.JSONObject")) { - serializer = new JsonSerializer(); - } else { - throw new MissingJsonParserException("unable to locate a JSON parser. " - + "Please see for more information"); + if ((serializer = tryCreate("com.fasterxml.jackson.databind.ObjectMapper", JacksonSerializer::new)) != null || + (serializer = tryCreate("com.google.gson.Gson", GsonSerializer::new)) != null || + (serializer = tryCreate("org.json.simple.JSONObject", JsonSimpleSerializer::new)) != null || + (serializer = tryCreate("org.json.JSONObject", JsonSerializer::new)) != null) { + logger.debug("using json serializer: {}", serializer.getClass().getSimpleName()); + return serializer; } + throw new MissingJsonParserException("unable to locate a JSON parser. " + + "Please see for more information"); + } - logger.debug("using json serializer: {}", serializer.getClass().getSimpleName()); - return serializer; + private static @Nullable Serializer tryCreate(String className, Callable factory) { + if (!isPresent(className)) { + return null; + } + try { + return factory.call(); + } catch (Throwable t) { + logger.warn("{} found on classpath but serializer init failed, trying next option.", className, t); + return null; + } } private static boolean isPresent(@Nonnull String className) { diff --git a/core-api/src/test/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializerTest.java b/core-api/src/test/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializerTest.java new file mode 100644 index 000000000..2dfed617c --- /dev/null +++ b/core-api/src/test/java/com/optimizely/ab/event/internal/serializer/DefaultJsonSerializerTest.java @@ -0,0 +1,45 @@ +/** + * + * Copyright 2026, Optimizely and contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.optimizely.ab.event.internal.serializer; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class DefaultJsonSerializerTest { + + @Test + public void getInstanceReturnsNonNull() { + Serializer serializer = DefaultJsonSerializer.getInstance(); + assertNotNull("getInstance() should return a non-null serializer", serializer); + } + + @Test + public void getInstanceReturnsSameInstance() { + Serializer first = DefaultJsonSerializer.getInstance(); + Serializer second = DefaultJsonSerializer.getInstance(); + assertSame("getInstance() should return the same singleton instance", first, second); + } + + @Test + public void instanceCanSerialize() { + Serializer serializer = DefaultJsonSerializer.getInstance(); + String result = serializer.serialize(java.util.Collections.singletonMap("test_key", "test_value")); + assertNotNull("Serializer should produce non-null output", result); + assertTrue("Serialized output should contain the key", result.contains("test_key")); + assertTrue("Serialized output should contain the value", result.contains("test_value")); + } +}