Search code examples
androidjsongsonosmdroid

osmdroid Polygon class to String


I want to make a Json string with Gson and Polygon class in osmdroid library but i get security exception this is my code :

Polygon polygon = new Polygon();
Gson gson = new Gsom();
Type type = new TypeToken<Polygon>(){}.getType();
String jsonString = gson.toJson(polygon, type);

but i get this error message:

java.lang.SecurityException: Can't make method constructor accessible
    at java.lang.reflect.Constructor.setAccessible(Constructor.java:336)
    at com.google.gson.internal.reflect.PreJava9ReflectionAccessor.makeAccessible(PreJava9ReflectionAccessor.java:31)
    at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:103)
    at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
    at com.google.gson.Gson.getAdapter(Gson.java:458)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)...

how can i fix it?


Solution

  • The error suggests, that there is some class without default constructor (constructor without parameters) included in the hierarchy of Polygon. Such constructor is required by Gson.

    The Polygon class is an osmdroid specific and nontrivial abstraction encapsulating points forming the shape and holes in the shape, information about its look (paint), and behavior.It contains instances of some other nontrivial classes (e.g. LinearRing). The class is not intended to be used as data object and (de)serialized to/from JSON or any other similar format. Some of the contained members are hard to serialize, because they are strongly platform specific (Paint).

    It would be cleaner to use a separate class containing just the information you want to store in the JSON (Do you need just array of points? Do you need any styling information included? etc..). This class should be part of your code base and therefore easily serializable via Gson. Depending on your use-case, you can create your Polygons from this class or the other way around. This approach allows you to model just the complexity you need (e.g. Do you need polygons with holes?).

    If you really want to go with this "shortcut" and serialize Polygon directly, you can create a custom type adapter for Polygon and register it with your Gson instance. A proper implementation of the adapter would be quite complex and out of scope of this response. However, for simple cases you should be able to easily write an adapter that would cover your needs.

    A few tips: follow the source code of the class. #getPoints()) will give you array of points for polygon's outline, #getHoles() will give you array of holes.