İpucu

Gson Throwable Serileştirme Sınıfı Sorunu

Java 11 ve sonrası için, Gson ile bir nesneyi JSON'a çevirirken eğer içerisinde Exception objesi var ise aşağıdaki gibi bir hata oluşmaktadır :
Exception in thread "main" com.google.gson.JsonIOException: Failed making field 'java.lang.Throwable#detailMessage' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
	at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.google.gson.Gson.getAdapter(Gson.java:556)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:160)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:294)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.google.gson.Gson.getAdapter(Gson.java:556)
	at com.google.gson.Gson.toJson(Gson.java:834)
	at com.google.gson.Gson.toJson(Gson.java:812)
	at com.google.gson.Gson.toJson(Gson.java:759)
	at com.google.gson.Gson.toJson(Gson.java:736)
	at com.fibiler.test.ThrowableAdapterFactory.main(ThrowableAdapterFactory.java:75)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @31dc339b
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:35)
	... 12 more
Bunu çözmek için aşağıdaki gibi bir adapter sınıfı eklenebilir :
import java.io.IOException;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class ThrowableAdapterFactory implements TypeAdapterFactory {
	private ThrowableAdapterFactory() {
	}
	public static final ThrowableAdapterFactory INSTANCE = new ThrowableAdapterFactory();
	@Override
	public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
		// Only handles Throwable and subclasses; let other factories handle any other
		// type
		if (!Throwable.class.isAssignableFrom(type.getRawType())) {
			return null;
		}
		@SuppressWarnings("unchecked")
		TypeAdapter<T> adapter = (TypeAdapter<T>) new TypeAdapter<Throwable>() {
			@Override
			public Throwable read(JsonReader in) throws IOException {
				throw new UnsupportedOperationException();
			}
			@Override
			public void write(JsonWriter out, Throwable value) throws IOException {
				if (value == null) {
					out.nullValue();
					return;
				}
				out.beginObject();
				// Include exception type name to give more context; for example
				// NullPointerException might
				// not have a message
				out.name("type");
				out.value(value.getClass().getSimpleName());
				out.name("message");
				out.value(value.getMessage());
				Throwable cause = value.getCause();
				if (cause != null) {
					out.name("cause");
					write(out, cause);
				}
				Throwable[] suppressedArray = value.getSuppressed();
				if (suppressedArray.length > 0) {
					out.name("suppressed");
					out.beginArray();
					for (Throwable suppressed : suppressedArray) {
						write(out, suppressed);
					}
					out.endArray();
				}
				out.endObject();
			}
		};
		return adapter;
	}
}
bu sınıfı aşağıdaki gibi kullanabiliriz :
    public static void main(String[] args) {    	    	  
        System.out.println(new Gson().toJson(new ExBean()));
    }
    static class ExBean {
        Throwable throwable = new Exception("Test exception");
    }
Bu şekilde test edildiğinde hata alınmayacaktır.
    public static void main(String[] args) {    
    	
    	Gson gson=new GsonBuilder()
        		.registerTypeAdapterFactory(ThrowableAdapterFactory.INSTANCE).create();
    	
        System.out.println(gson.toJson(new ExBean()));
    }
    static class ExBean {
        Throwable throwable = new Exception("Test exception");
    }
Çıktı :
{"throwable":{"type":"Exception","message":"Test exception"}}

Kaynak : github.com/google/gson/issues/2352
zafer.teker , 07.03.2025

Bu Sayfayı Paylaş:

Fibiler Üyelerinin Yorumları


Tüm üyeler içeriklere yorum ekleyerek katkıda bulunabilir : Yorum Gir



Bu Sayfayı Paylaş:

İletişim Bilgileri

Takip Et

Her Hakkı Saklıdır. Bu sitede yayınlanan tüm bilgi ve fikirlerin kullanımından fibiler.com sorumlu değildir. Bu sitede üretilmiş , derlenmiş içerikleri, fibiler.com'u kaynak göstermek koşuluyla kendi sitenizde kullanılabilirsiniz. Ancak telif hakkı olan içeriklerin hakları sahiplerine aittir