As developers in an EdTech company it is important for us to be updated with the latest tech trends especially if it involves one of the vital libraries our application can’t launch without, the Android Support Library. This is important because it enables us to reach a wide range of user base by supporting a lot of android platforms as possible.
But since Android Support Library is on its end of life, we recently migrated to androidx and updated a lot of dependencies. We survived a huge code change but not without some hiccups. On the UI side of things we need to update material-component libraries from version alpha01 to alpha05 and eventually alpha06 to fix an issue with our login. But this came with a price because on our happy path testing, a side effect appeared. Not on our code base but to a third-party library that we’re using.
We are using a third party sdk on our app for messaging communication between student and a teacher so this feature is critical for our app. For now let’s call it “ChatSDK”. Upgrading the material component can really impact a third party library that uses UI components.
Android ChatSDK crashes when ChatSDKBaseActivity call
applyOverrideConfiguration with an
IllegalStateException(" Override configuration has already been set ")
This is because
getAssets() has already been called
In this case getResources is called before the
applyOverrideConfiguration in the ContextLocaliser class
So after we find out the root cause, we have speculated that maybe the recent library upgrades affects the third-party library’s crash. We’ve tried downgrading the material libraries to make it work but it’s not a good practice since a lot of UI stuff from our code base will be affected just to fix this crash so we investigated further. Good thing there’s a dedicated forum for ChatSDK users and we found out that we’re not alone. Surprisingly, others have been having this issue since 5 months ago. Around 3 months after the reported issue, one of the company representatives informed in a comment that their engineers are working for a fix but there is no ETA and possible damage assessment.
Other users reported that downgrading the material support library fixes it for them, but for us it isn’t an option because appcompat is a dependency for many other (Jetpack) libraries. We are in the middle of a sprint and this feature is critical to our paying users so we have to look for a workaround. Our manager suggested that if we can reverse engineer the aar library and delete the offending line, it might work for us temporarily until ChatSDK releases a fix.
In our team, we practice pair programming so I’m working with another developer to figure out the feasibility of the workaround.
First we need a java decompiler and since we are working on different machines we went on trying decompilers on our own system.
Step 1 - Extract java classes from the package
Step 2 - Modify Java Bytecode
Step 3 - Verify and repackage it again
Step 4 - Import the repackaged aar together with other dependencies
Then on our project we will import it manually together with other dependencies instead of using gradle for this work around.
We tried a couple of decompilers but we can’t modify up to the bytecode level and repackage it again.
We found a library called Recaf which is a modern java bytecode editor
But first we have to copy rename the base library and change the file extension from .aar to jar in order to extract the classes folder before we can import it on the bytecode editor
We find it easier to use because it has a GUI. Just execute the downloaded jar file and a window will open. Drag the classes.jar file and browse the specific class file that you want to edit. Then right click on the class name on the right window and change the class mode to table.
When on the table view, go to the methods tab and remove the target line.
Go back to the decompiler view again and see that the method call is now removed!
Now we can export the classes.jar with the modified target class
Now we can repackage the entire library and include it to our project manually.
Voila! The workaround works like a charm!
However, there is a side effect on this workaround as it now only works on a single language which is English by default. But it’s still better than an app crash though for the meantime until the ChatSDK developers release a fixed version.
Apparently the next day, a new version of the sdk is released with the fix and we can just use it right away. It’s kinda mixed feelings for us because just a day before we are going down to the bytecode level of a library to find a workaround but at least we learn a lot from it and it may come in handy whenever we encounter similar problems in the future so I think it’s still worth it that we tried.
It’s also a good thing because we don’t have to release the workaround into production and just in time before our sprint ends.