Jackson Generic Type + Java Type Erasure


The problem
We are save configuration elements to Dynamodb: the key is the configuration name, the value is the JSON string.
Recently I am trying to refactor the code to make the service code much shorter and easier to read. But I made one mistake - related with Java Type erasure.

The following code tries to read configuration: its value is a Map. I want to create one generic method that can read different Map.
  @Nonnull
  private <T> Map<String, T> getMapConfig(final String configName) {
      final ConfigElement c = configDao.getConfigByName(configName);

      Map<String, T> resultMap = null;
      if (c != null) {
          String json = c.getValue();
          resultMap = objectMapper.readValue(json, new TypeReference<Map<String, T>>() {});
      }
      if (resultMap == null) {
          resultMap = new HashMap<>();
      }
      return resultMap;
  }

  private <T> T convertMapValue(final String json) {
      return objectMapper.readValue(json, new TypeReference<T>(){});
  }
But this doesn't work: because of type erasure, T is just a type variable, at runtime, Java can't get the real value of the type.

The Solution
We have to specify class type like below:
  @Nonnull
  private <T> Map<String, T> getMapConfig(final String configName, final Class<T> classType) {
      final ConfigElement c = configDao.getConfigByName(configName);

      Map<String, T> resultMap = null;
      if (c != null) {
          String json = c.getValue();
          final MapType mapType = TypeFactory.defaultInstance().constructMapType(Map.class, String.class, classType);            
          resultMap = objectMapper.readValue(json, mapType);
      }
      if (resultMap == null) {
          resultMap = new HashMap<>();
      }
      return resultMap;
  }
  private <T> T convertMapValue(final String json,final Class<T> valueType) {
      return objectMapper.readValue(json, valueType);
  }
One related stuff I found is that in eclipse you can change Eclipse's Warning settings so that if Eclipse will show warnings if some parameter are not used: Change -> Window/Preferences /Java/Compiler/ErrorsWarnings -> Unnecessary Code > Value of parameter is not used to warning.

Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure
Jackson Date Serialize + Deserialize
Apache Commons TypeLiteral
Google Guice TypeLiteral
Effects of Type Erasure and Bridge Methods

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)