Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonMappingException in release build with ProGuard #2290

Closed
johnjohndoe opened this issue Mar 31, 2019 · 1 comment
Closed

JsonMappingException in release build with ProGuard #2290

johnjohndoe opened this issue Mar 31, 2019 · 1 comment

Comments

@johnjohndoe
Copy link
Contributor

johnjohndoe commented Mar 31, 2019

I am stuck with a JsonMappingException which occurs when I compile a RELEASE with ProGuard obfuscation enabled and run this Android app. It does not occur when I compile and run a DEBUG build.

I was able to narrow the issue down to this commit where I introduce getFileName() in the ChildZone interface being reflected on the concrete LowEmissionZone class.

Due to the exception in ContentProvider.getContent:128 the list of circuits in ContentProvider.getCircuits():92 becomes and empty array.

The current ProGuard setting can be found here.

Here is the stacktrace which I deobfuscated from the RELEASE build.

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input 
  at [Source: android.content.res.AssetManager$AssetInputStream@78c8e0; line: 1, column: 0]
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(Unknown Source)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(Unknown Source)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(Unknown Source)
                                                   readValue
    at de.avpptr.umweltzone.utils.ContentProvider.enforceContentUpdate(Unknown Source)
                                                  getFaqs
                                                  getAdministrativeZoneByName
                                                  getContent
                                                  getContent
                                                  getResourceId
                                                  getFilePath
                                                  lambda$getAdministrativeZoneByName$0
    at de.avpptr.umweltzone.utils.ContentProvider.enforceContentUpdate(Unknown Source)
                                                  getFaqs
                                                  getAdministrativeZoneByName
                                                  getContent
                                                  getContent
                                                  getResourceId
                                                  getFilePath
                                                  lambda$getAdministrativeZoneByName$0
    at de.avpptr.umweltzone.utils.ContentProvider.getAdministrativeZones(Unknown Source)
                                                  getCircuits
                                                  getRawResourceId
    at de.avpptr.umweltzone.map.dataconverters.ChildZonesExtensions.toCircuitViewModels(Unknown Source)
                                                                    toCircuitViewModels
                                                                    toCircuitViewModels
                                                                    toCircuitViewModel
                                                                    toLatLngList
    at de.avpptr.umweltzone.map.dataconverters.ChildZonesExtensions.toCircuitViewModels(Unknown Source)
                                                                    toCircuitViewModels
                                                                    toCircuitViewModels
                                                                    toCircuitViewModel
                                                                    toLatLngList
    at de.avpptr.umweltzone.map.MapFragment.drawPolygonOverlay(Unknown Source)
    at de.avpptr.umweltzone.map.MapFragment.getLayoutResource(Unknown Source)
                                            onAttach
                                            onCreate
                                            onCreateView
                                            zoomToBounds
                                            zoomToLocation
                                            showGooglePlayServicesErrorDialog
                                            onMapReady
                                            onRequestPermissionsResult
                                            setMyLocationActivationViewVisibility
                                            lambda$onCreate$2
                                            access$100
                                            access$400
                                            access$500
    at de.avpptr.umweltzone.map.MapFragment$1.onDrawPolygonOverlay(Unknown Source)
                                              onZoomToBounds
                                              onZoomToLocation
    at de.avpptr.umweltzone.map.MapReadyDelegate.evaluate(Unknown Source)
                                                 storeLastAdministrativeZone
    at de.avpptr.umweltzone.map.MapFragment.getLayoutResource(Unknown Source)
                                            onAttach
                                            onCreate
                                            onCreateView
                                            zoomToBounds
                                            zoomToLocation
                                            showGooglePlayServicesErrorDialog
                                            onMapReady
                                            onRequestPermissionsResult
                                            setMyLocationActivationViewVisibility
                                            lambda$onCreate$2
                                            access$100
                                            access$400
                                            access$500
    at com.google.android.gms.maps.MapView$zza$1.zza(Unknown Source)
    at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
    at android.os.Binder.transact(Binder.java:499)
    at fv.b(:com.google.android.gms.dynamite_mapsdynamite@15090050@15.0.90 (040406-231259764):14)
    at com.google.android.gms.maps.internal.bd.a(:com.google.android.gms.dynamite_mapsdynamite@15090050@15.0.90 (040406-231259764):4)
    at com.google.maps.api.android.lib6.impl.bk.run(:com.google.android.gms.dynamite_mapsdynamite@15090050@15.0.90 (040406-231259764):4)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6119)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Environment

  • Jackson: com.fasterxml.jackson.core:jackson-databind:2.8.10, Cannot update at the moment.
  • Test device: Nexus 9, Android 7.1.1 (API level 25, Nougat)
  • ProGuard: net.sf.proguard:proguard-gradle:6.0.3
  • **Android Gradle plugin: 3.3.2

Related

@johnjohndoe
Copy link
Contributor Author

johnjohndoe commented Mar 31, 2019

Explaining the problem

The actual source problem of this issue is not Jackson. The code and resource shrinker in the Android build removes resources not directly referenced in code. This is the case for files in my project located in the raw directory. I made a change in above mentioned commit which moved the file name reference from the Java code into a JSON configuration file.
As a result some of the binary files in the raw directory where shrinked down as one could see in the console output of the RELEASE build:

> Task :Umweltzone:transformClassesAndDexWithShrinkResForRelease
Removed unused resources: Binary resource data reduced from 1549KB to 1100KB: Removed 28

Also the error message in the stacktrace kind of tells about it .. column: 0:

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input 
  at [Source: android.content.res.AssetManager$AssetInputStream@78c8e0; line: 1, column: 0]

Another valuable tool to get insights is the APK analyzer of Android Studio which revealed that the shrinked down files were still present in the raw folder of the RELEASE APK. However, they were empty.

One solution

To prevent the shrinking Google recommends to explicitly tell the build task to keep the files. Therefore, I have to put a keep.xml file into the raw folder as explained in the documentation.

Related


All the above findings have been discovered by @cketti. Big thanks for your help! 👍

johnjohndoe added a commit to Umweltzone/Umweltzone that referenced this issue Mar 31, 2019
+ Zones files in raw/lez_* are no longer directly referenced in code since
  this commit. Therefore, the code shrinker needs to explicitly be
  instructed to skip these files in a RELEASE build.
  See: FasterXML/jackson-databind#2290
  Thanks to @cketti for helping to resolve this challenge.
johnjohndoe added a commit to Umweltzone/Umweltzone that referenced this issue Apr 1, 2019
+ Zones files in raw/lez_* are no longer directly referenced in code since
  this commit. Therefore, the code shrinker needs to explicitly be
  instructed to skip these files in a RELEASE build.
  See: FasterXML/jackson-databind#2290
  Thanks to @cketti for helping to resolve this challenge.
johnjohndoe added a commit to Umweltzone/Umweltzone that referenced this issue Apr 1, 2019
+ Zones files in raw/lez_* are no longer directly referenced in code since
  this commit. Therefore, the code shrinker needs to explicitly be
  instructed to skip these files in a RELEASE build.
  See: FasterXML/jackson-databind#2290
  Thanks to @cketti for helping to resolve this challenge.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant