es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

GSON no puede serializar una excepción con Java 17.

El siguiente código solía funcionar en Java 11:

new Gson().toJson(new Exception())

En JDK 17 obtengo el siguiente error:

Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @147ed70f

Después de leer esta página, creo que podría resolverlo con --add-opens java.base/java.lang=ALL-UNNAMED. ¿Existe una mejor manera sin embargo? ¿Quizás con un de/serializer personalizado?

Tags:  ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que el código está intentando acceder a un campo privado de la superclase Throwable, lo cual ya no está permitido en JDK 17. La solución propuesta de utilizar la bandera --add-opens para agregar java.lang al módulo sin nombre es una posible solución alternativa, pero puede que no sea el enfoque más adecuado.

    Una solución alternativa podría ser definir un serializador/deserializador personalizado que maneje la clase Throwable de una manera diferente. Esto implicaría crear una implementación personalizada de las interfaces JsonSerializer y/o JsonDeserializer y registrarla con el objeto Gson.

    Por ejemplo, para serializar una excepción como un objeto JSON solo con el campo de mensaje, podrías definir un serializador de la siguiente manera:

    import com.google.gson.*;
    import java.lang.reflect.Type;
    
    public class ExceptionSerializer implements JsonSerializer<exception> {
    
      public JsonElement serialize(Exception src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject obj = new JsonObject();
        obj.addProperty("message", src.getMessage());
        return obj;
      }
    
    }
    

    Y luego registrarlo con el objeto Gson de la siguiente manera:

    Gson gson = new GsonBuilder()
        .registerTypeAdapter(Exception.class, new ExceptionSerializer())
        .create();
    

    Con este enfoque, puedes personalizar fácilmente la serialización y deserialización de cualquier clase, sin depender de la reflexión para acceder a campos privados.

Comments are closed.