2
\$\begingroup\$

I have a project that uses a library to save serialized objects in items and loads them again, when needed.
To do the de-/serialization, this library uses Gson.

Due to how Gson works and how the library is set up, I can't add support for custom types easily and thus have to rely heavily on reflection.
I don't like this, but it has to be like this, sadly.

I am asking, whether there is a way to make this code use more Kotlin idioms.
My issue is that because the fields I am accessing are private, the usual reflection using :: doesn't work.

Anyways, here is my code:

/**
 * Registers a custom GSON handler to handle the [Location] class.
 */
private fun registerGsonHandlers() {
 logger.entering(LobbyMain::class, "registerGsonHandlers")
 // Gets private static final Gson gson = new Gson();
 val fGson = NBTReflectionUtil::class.java.getDeclaredField("gson")
 fGson.isAccessible = true
 val modifiersField = Field::class.java.getDeclaredField("modifiers")
 modifiersField.isAccessible = true
 modifiersField.setInt(fGson, fGson.modifiers and Modifier.FINAL.inv())
 // Gets private final List<TypeAdapterFactory> factories;
 val fFactories = Gson::class.java.getDeclaredField("factories")
 fFactories.isAccessible = true
 val factories = fFactories.get(fGson.get(null)) as List<*>
 // Sets private static final Gson gson
 fGson.set(null, GsonBuilder().apply {
 registerTypeAdapter(Location::class.java, LocationTypeAdapter)
 factories.forEach { this::registerTypeAdapterFactory }
 }.create())
 logger.exiting(LobbyMain::class, "registerGsonHandlers")
}

It pulls the Gson object out of the NBTReflectionUtil class, makes it modifiable and gets its list of TypeAdapterFactories.
I then create a new Gson object with all the old TypeAdapters and mine added and set it as the new Gson object for the library.

asked Jul 6, 2017 at 18:04
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I'd group your code to make it more readable. Something like this:

fun getGson(): Field {
 val fGson = NBTReflectionUtil::class.java.getDeclaredField("gson")
 fGson.isAccessible = true
}
fun removeFinalModifier(field: Field) {
 val modifiersField = Field::class.java.getDeclaredField("modifiers")
 modifiersField.isAccessible = true
 modifiersField.setInt(fGson, fGson.modifiers and Modifier.FINAL.inv())
}
// etc
answered Jul 6, 2017 at 18:48
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.