Problem parsing "minDiskFree" on Android


(Catfriend1) #1

Hi,

I currently investigate the problem at "Minimum Free Disk Space" setting not working/respected? . My config is this:

<?xml version="1.0" encoding="UTF-8"?><configuration version="28">
    <folder id="android_sdk_built_for_x86_8cvj-photos" label="Camera" path="/storage/emulated/0/DCIM" type="sendonly" rescanIntervalS="3600" fsWatcherEnabled="false" fsWatcherDelayS="10" ignorePerms="true" autoNormalize="true">
        <filesystemType>basic</filesystemType>
        <device id="AWEF5D3-UKS7WRS-76TPRA7-A7KVBZA-AX24ASZ-EKVUOY3-67ITRMM-IIWYFAY" introducedBy=""/>
        <minDiskFree unit="%">5</minDiskFree>
        <versioning type="trashcan">
            <param key="cleanoutDays" val="39"/>
        </versioning>
        <copiers>0</copiers>
        <pullerMaxPendingKiB>0</pullerMaxPendingKiB>
        <hashers>1</hashers>
        <order>random</order>
        <ignoreDelete>false</ignoreDelete>
        <scanProgressIntervalS>0</scanProgressIntervalS>
        <pullerPauseS>0</pullerPauseS>
        <maxConflicts>10</maxConflicts>
        <disableSparseFiles>false</disableSparseFiles>
        <disableTempIndexes>false</disableTempIndexes>
        <paused>false</paused>
        <weakHashThresholdPct>25</weakHashThresholdPct>
        <markerName>.stfolder</markerName>
        <useLargeBlocks>false</useLargeBlocks>
    </folder>

The Android app uses “new Gson().toJson(restConfigResponse)” to parse the config. The class making deserialization is correct, checked twice. The fields “unit” and the text node “value” of minDiskFree aren’t deserialized and I instead get a null object which is wrong. So I dumped the parsed config readable to screen because to see why it doesn’t work.

"minDiskFree":{"unit":"%"}

Comparing this to the /rest/config response Chrome on PC gets, I see a slight mismatch which I suspect causing the above deserialization issue.

  "minDiskFree": {
    "value": 5,
    "unit": "%"
  },

Conclusion: a) The /rest/config endpoint offers the correct config in text form as Chrome on PC can also see it and the app uses the same endpoint to retrieve the config. b) The deserialization of “value: [no matter what I enter for test]” always fails leaving the created JAVA class holding the data with “null” behind. c) The gson() class seems to have its problem with the xml text node holding the value, in example the “5” and cancels the whole part to deserialize. That’s why I also don’t get “String unit”.

Dear Core devs,

could you please make the “minDiskFree” xml node in config and REST json the same way structured as it’s already the case for:

<versioning type="trashcan">
   <param key="cleanoutDays" val="39"/>
</versioning>

The contents deserialize correctly with the gson() module on Android.

If there’s another probably easier solution, I’d appreciate a tip where to look at.

Kind regards Catfriend1


(Audrius Butkevicius) #2

Not sure what the xml format has todo with this, but value is a float (double?), not a string to make sure that you have the right type. Also, perhaps the keyword value is special and needs some special handling in gson.


(Catfriend1) #3

Thanks for the pointer. I found an article confirming problems with reserved keywords like “public” when using gson. I’ve tried different types (float, double, Number, String) and put the @SerializedName annotation - unfortunately without success. I still get null. image


(Catfriend1) #4

I’ve tried to find a solution but no luck yet. Still wondering why deserializing the /rest/config JSON response works for the “Versioning” POJO class and doesn’t work for the “MinDiskFree” class. Looking at: https://github.com/syncthing/syncthing-android/blob/master/app/src/main/java/com/nutomic/syncthingandroid/model/Folder.java

Both are static and I think they have the correct var types. Changing them doesn’t help, still null. Annotating with @SerializedName doesn’t help either. I’ve read a lot on StackOverflow where it was suggested using static classes, okay we have it. I’ve also experimented with 1) taking “Versioning” out completely and 2) using non-static classes. Still no luck for getting the “MinDiskFree” data from the JSON response right. Any further suggestions?


(Audrius Butkevicius) #5

I think serialised name only has meaning when serialising, not deserialising.


(Catfriend1) #6

Should I try another deserializer, e.g. Jackson?


(Audrius Butkevicius) #7

I for some reason remember having issues with the keyword value and gson before, so worth a try. Jackson provides more control.


(Catfriend1) #8

Sorry, I’m missing a feedback on the thread. In the meantime, the issue got solved. It was specific to another code change which lead to the correct deserialized content never getting passed down the function tree. I’ve (internally) added a milestone where I’d like to try the Jackson stuff in the future as this sounds promising to ease things, Thanks.