Skip to content

gson cannot deserialise to Void #18

Open
@robinfriedli

Description

@robinfriedli

setStats creates a ResponseTransformer that attempts to deserialise the response to java.lang.Void:

    private CompletionStage<Void> setStats(JSONObject jsonBody) {
        HttpUrl url = baseUrl.newBuilder()
                .addPathSegment("bots")
                .addPathSegment(botId)
                .addPathSegment("stats")
                .build();

        return post(url, jsonBody, Void.class);
    }

    private <E> CompletionStage<E> post(HttpUrl url, JSONObject jsonBody, Class<E> aClass) {
        return post(url, jsonBody, new DefaultResponseTransformer<>(aClass, gson));
    }

public class DefaultResponseTransformer<E> implements ResponseTransformer<E> {

    private final Class<E> aClass;
    private final Gson gson;

    public DefaultResponseTransformer(Class<E> aClass, Gson gson) {
        this.aClass = aClass;
        this.gson = gson;
    }

    @Override
    public E transform(Response response) throws IOException {
        String body = response.body().string();
        return gson.fromJson(body, aClass);
    }

}

However, this does not work on newer versions of java because java.base is a sealed module:

com.google.gson.JsonIOException: Failed making constructor 'java.lang.Void#Void()' accessible; either change its visibility or write a custom InstanceCreator or TypeAdapter for its declaring type: Unable to make private java.lang.Void() accessible: module java.base does not "opens java.lang" to unnamed module @45d84a20
	at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:131)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:211)
	at com.google.gson.Gson.fromJson(Gson.java:991)
	at com.google.gson.Gson.fromJson(Gson.java:956)
	at com.google.gson.Gson.fromJson(Gson.java:905)
	at com.google.gson.Gson.fromJson(Gson.java:876)
	at org.discordbots.api.client.io.DefaultResponseTransformer.transform(DefaultResponseTransformer.java:21)
	at org.discordbots.api.client.impl.DiscordBotListAPIImpl$1.onResponse(DiscordBotListAPIImpl.java:234)
	at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

I don't think it makes sense anyway. If you are not interested in the response, why deserialise it? Probably better to not use a ResponseTransformer and complete the future with null when done instead of deserialising to Void.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions