Areas where Jackson is Used:
1. Direct usage of Jackson by Portal code
2. Indirect dependency through other packages
Modules with direct dependency on Jackson package:
Portal-SDK:
- epsdk-fw
- epsdk-analytics
- epsdk-app-common
- epsdk-app-os
- epsdk-core
- epsdk-domain
- epsdk-music
- epsdk-workflow
- epsdk-aaf
Portal:
- Portal-BE-Common:
- Portal-BE-OS:
- Portal-widget-ms:
Packages used that have dependency on Jackson:
Portal-SDK:
- org.elasticsearch:elasticsearch:jar – Not using this package anywhere in the code and can be removed, as confirmed by Sunder.
- org.onap.portal.sdk:epsdk-music:jar
Portal:
- com.orbitz.consul:consul-client:jar
- org.elasticsearch:elasticsearch:jar - Not using this package anywhere in the code and can be removed, as confirmed by Sunder
Code Analysis:
- Portal-SDK: Approximately 60+ files that inculde fatserxml jackson excluding test files.
- Portal: Approximately 60+ files that inculde fatserxml jackson excluding test files
Using Gson In our Code:
Gson Maven Dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
POC- Replacing Jackson with Gson in our code:
- Gson FromJson method as replacement for Jackson readValue method-Replaced Jackson methods with Gson methods in saveRoleFunction() method of RoleFunctionListController class as below,
Replaced this,
public void saveRoleFunction() {
String data = roleFunc;
RoleFunction availableRoleFunction = mapper.readValue(data, RoleFunction.class);
System.out.println("mapper.readVlaue:"+availableRoleFunction);
}
With this,
public void saveRoleFunction() {
String data = roleFunc;
RoleFunction roleFunctonAvailable = gson.fromJson(data, RoleFunction.class);
System.out.println("gson:fromJson:"+roleFunctonAvailable);
}
Output for both methods, gson.fromJson() and mapper.readValue, is same.
- Gson toJson method as replacement for Jackson writeValueAsString method-Replaced Jackson methods with Gson methods in buildJsonResponse() method of JsonMessage class as below,
Replaced this,
public static String buildJsonResponse(boolean success, String msg) {
String json = null;
json = new ObjectMapper().writeValueAsString(response);
System.out.println("mapper.WriteValueAsString:"+json);
return json;
}
With this,
public static String buildJsonResponse(boolean success, String msg) {
String jsonFromGson = null;
jsonFromGson = new Gson().toJson(response);
System.out.println("Gson().toJson:"+jsonFromGson);
return jsonFromGson;
}
Output for both methods, gson.fromJson() and mapper.readValue, is same
Jackson Methods used in our code and their equivalents in Gson:
Below are few of the methods and their usages in Gson that can be used as replacements for Jackson,
Jackson Method | Jackson Class | Usage | GSON Equivalent Method | GSON Equivalent Class | Usage |
---|---|---|---|---|---|
readValue | jackson.databind.ObjectMapper | <ObjectType> obj = mapper.readValue(JsonString, ClassType); | fromJson | com.google.gson.Gson; | <ObjectType> obj = gson.fromJson(data, RoleFunction.class); |
writeValueAsString | jackson.databind.ObjectMapper | String json = new ObjectMapper().writeValueAsString(Object); | toJson | com.google.gson.Gson; | String resultJson = new Gson().toJson(Object); |
configure | jackson.databind.ObjectMapper | objectMapper.configure(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) objectMapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) | Use GsonBuilder to construct a Gson instance when you need to set configuration options other than the default | com.google.gson.GsonBuilder | Gson gson = new GsonBuilder() .serializeNulls() .setDateFormat(DateFormat.LONG) .create(); |
readTree | jackson.databind.ObjectMapper | JsonNode root = mapper.readTree(request.getReader()); | parse | com.google.gson.JsonParser | JsonElement rootNode = parser.parse(jsonString); |
NA | jackson.databind.JsonNode; | Base class for all JSON nodes, which form the basis of JSON | NA | import com.google.gson.JsonElement; | class representing an element of Json. It could either be a JsonObject, a JsonArray, a JsonPrimitive or a JsonNull |
NA | jackson.core.type.TypeReference | TypeReference<List<Type>> typeRef = new TypeReference<List<Type>>() {}; List<Type> listObj = mapper.readValue(requestBody, typeRef); | NA | import com.google.gson.reflect.TypeToken; | listObj = gson.fromJson(jsonString, new TypeToken<Hashtable<String, Type>>() {}.getType()); |
NA | import com.fasterxml.jackson.databind.type.TypeFactory; | NA | |||
NA | jackson.annotation.JsonIgnoreProperties; | JsonIgnoreProperties(ignoreUnknown = true) | NA | com.google.gson.annotations.Expose | GSON @Expose annotation using GsonBuilder.excludeFieldsWithoutExposeAnnotation(). |
NA | jackson.annotation.JsonRootName; | JsonRootName(value="abc") public class ClassName {} | NA | javax.xml.bind.annotation.XmlElement | XmlRootElement public class ClassName {} |
References:
https://www.baeldung.com/jackson-vs-gson
http://websystique.com/java/json/gson-json-annotations-example/
https://www.tutorialspoint.com/gson/gson_tree_model.htm
https://google.github.io/gson/apidocs/index.html?com/google/gson/class-use/JsonElement.html
https://www.baeldung.com/gson-deserialization-guide
http://websystique.com/java/json/gson-tree-model-example/