it-swarm.com.ru

Android M + Retrofit + JSON: невозможно сделать конструктор полей доступным

В настоящее время я проверяю мое приложение для поддержки М. Я получаю эту ошибку, когда я делаю вызовы API с модернизацией. Кажется, это ошибка JSON, которую я получаю. Кто-нибудь еще сталкивался с этим еще? Вот мой вспомогательный класс JSON.

public class JsonHelper {

    private static final String JSON_PARSE_ERROR = "Unable to parse JSON: ";
    private static Gson sGson;
    private static Gson sExposeGson;

    static {
        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapterFactory(new EnumTypeAdapterFactory());
        builder.registerTypeAdapter(BlogCategoryDto.class, new BlogCategorySerializer());
        ...

        sGson = builder.create();

        builder.excludeFieldsWithoutExposeAnnotation();
        sExposeGson = builder.create();
    }

    public static Gson getGson() {
        return sGson;
    }

    public static Gson getsExposeGsonGson() {
        return sExposeGson;
    }

    public static String toJson(@NonNull Object object) {
        return sGson.toJson(object);
    }

    public static String toJson(@NonNull Object object, @NonNull Type type) {
        return sGson.toJson(object, type);
    }

    public static String toExposeJson(@NonNull Object object) {
        return sExposeGson.toJson(object);
    }

    public static String toExposeJson(@NonNull Object object, @NonNull Type type) {
        return sExposeGson.toJson(object, type);
    }

    public static <T> T fromJson(@NonNull String content, @NonNull Class<T> clazz)
            throws IllegalStateException {
        try {
            return sGson.fromJson(content, clazz);
        } catch (JsonSyntaxException e) {
            throw new IllegalStateException(JSON_PARSE_ERROR + content, e);
        }
    }

    public static <T> T fromJson(@NonNull String content, @NonNull Type type)
            throws IllegalStateException {
        try {
            return sGson.fromJson(content, type);
        } catch (JsonSyntaxException e) {
            throw new IllegalStateException(JSON_PARSE_ERROR + content, e);
        }
    }
}

Это ошибка, которая выбрасывается

D/Retrofit﹕Java.lang.SecurityException: Can't make field constructor accessible
        at Java.lang.reflect.Constructor.setAccessible(Constructor.Java:334)
        at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.Java:97)
        at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.Java:79)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.Java:82)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.Java:52)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.Java:122)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.Java:46)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.Java:92)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.Java:91)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.Java:142)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.Java:83)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.Java:122)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.Java:46)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.Java:92)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.Java:91)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.Java:142)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.Java:83)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.internal.bind.CollectionTypeAdapterFactory.create(CollectionTypeAdapterFactory.Java:52)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldAdapter(ReflectiveTypeAdapterFactory.Java:122)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.access$100(ReflectiveTypeAdapterFactory.Java:46)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.Java:92)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.Java:91)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.Java:142)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.Java:83)
        at com.google.gson.Gson.getAdapter(Gson.Java:359)
        at com.google.gson.Gson.fromJson(Gson.Java:809)
        at com.google.gson.Gson.fromJson(Gson.Java:775)
        at retrofit.converter.GsonConverter.fromBody(GsonConverter.Java:63)
        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.Java:367)
        at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.Java:220)
        at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.Java:278)
        at retrofit.CallbackRunnable.run(CallbackRunnable.Java:42)
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1113)
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:588)
        at retrofit.Platform$Android$2$1.run(Platform.Java:142)
        at Java.lang.Thread.run(Thread.Java:818)
18
Eoin

Как отмечалось в комментариях, в проекте Gson уже открыта проблема.

https://github.com/google/gson/issues/648

Поэтому неплохо подождать, пока они обновят свою библиотеку. В то же время я смог быстро исправить это, добавив строку кода.

static {
    GsonBuilder builder = new GsonBuilder();

    ...

    builder.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC);**
    builder.excludeFieldsWithoutExposeAnnotation();
    sExposeGson = builder.create();
}
25
Eoin

Это сработало для меня. Надеюсь, это может кому-то помочь.

GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC);
Gson gson = builder.create();
4
Muneef M

Лучший способ!

  GsonBuilder builder = new GsonBuilder().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC);
  Gson gson = builder.create();
  Retrofit retrofit = new Retrofit.Builder().baseUrl(URL)
      .addConverterFactory(GsonConverterFactory.create(gson))
      .build();
1
Pierry

Существует проблема с использованием Retrofit2 в Android M, как упоминалось в здесь

одним из решений является настройка GsonConverterFactory следующим образом:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(URLWebService)
    .addConverterFactory(GsonConverterFactory.create(
                           new GsonBuilder()
                           .excludeFieldsWithoutExposeAnnotation()
                           .create()
                        ))
    .client(okHttpClient)
    .build(); 
0
faruk