Skip to content

MessageJsonHandler::toString doesn't work with custom type adapters #768

@henryju

Description

@henryju

Hi,

I am trying to use types like java.nio.file.Path directly in my RPC messages. For this, we are using a custom type adapter, and registering it when building the launcher:

var launcher = new Launcher.Builder<MyClient>()
      .setLocalService(myServer)
      .setRemoteInterface(MyClient.class)
      .setInput(in)
      .setOutput(out)
      .configureGson(gsonBuilder -> gsonBuilder
        .registerTypeAdapterFactory(new PathTypeAdapter.Factory())
      )
      //.traceMessages(new PrintWriter(System.out, true))  // This is one way to trigger the issue
      .create();

the problem is with some code in lsp4j that will try to serialize/deserialize messages with a separate instance of gson, that has not been configured with the custom type adapters.
It leads to errors like:

com.google.gson.JsonIOException: Failed making field 'sun.nio.fs.UnixPath#fs' 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:287)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
	at com.google.gson.Gson.getAdapter(Gson.java:546)
	at org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter.write(CollectionTypeAdapter.java:138)
	at org.eclipse.lsp4j.jsonrpc.json.adapters.CollectionTypeAdapter.write(CollectionTypeAdapter.java:40)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:196)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:366)
	at com.google.gson.Gson.toJson(Gson.java:825)
	at com.google.gson.Gson.toJson(Gson.java:795)
	at com.google.gson.Gson.toJson(Gson.java:742)
	at com.google.gson.Gson.toJson(Gson.java:719)
	at org.eclipse.lsp4j.jsonrpc.json.MessageJsonHandler.toString(MessageJsonHandler.java:161)
	at org.eclipse.lsp4j.jsonrpc.TracingMessageConsumer.consumeMessageSending(TracingMessageConsumer.java:125)
	at org.eclipse.lsp4j.jsonrpc.TracingMessageConsumer.consume(TracingMessageConsumer.java:101)

Any use of MessageJsonHandler.toString is affected.

I wonder if there could be a way to either reuse the same configured gson instance everywhere, or maybe allow to also configure the one used for toString?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions