changing or upgrading built-in org.json libraries, is possible and a good idea?
Asked Answered
J

1

2

My application depends a lot on the JSON library org.json.*. This package is built-in into Android standard libraries, something I didn't know because I also included it in my source tree.

I need to use a function (JSONArray.remove) that is not supported on the built-in package, while it is in the source distribution jar from org.json (that I include in my project). So what happens is, everything compiles & all, but I get java.lang.NoSuchMethodError: org.json.JSONArray.remove at runtime.

My question is, how can I tell eclipse or Android to use the org.json.* from my source tree instead of its built-in version?

And a sub-question: Is it a good idea at all? May the built-in JSON package have native-level improvements or something like that vs. the official source code distribution?

Jaggery answered 5/12, 2013 at 0:34 Comment(0)
H
2

My question is, how can I tell eclipse or Android to use the org.json.* from my source tree instead of its built-in version?

You can't. You do not control the runtime classpath, and the firmware always wins.

You are welcome to use jarjar or a similar tool to move your copy of the org.json classes into a new package. Or, find a better JSON library -- there's lots of them out there.

Hooked answered 5/12, 2013 at 0:54 Comment(5)
thanks for the concise answer :) Do you think if I rename and use this new package for json parsing the performance will be similar to the stock one? (see the second question)Jaggery
@rupps: I am not aware that the one that is part of the firmware has any performance improvements. org.json is supposed to be canonical, not well-performing. If you want a performant JSON parser, choose Jackson. That being said, I have no idea if org.json itself has changed in any way since ~2007 that would make the current version faster or slower than the version that is in Android.Hooked
Been debugging all night for a strange Proguard error, I finally found what was going on and I remembered this question and your answer. I've found a way to accomplish this as a funny side-effect: If you include ie. org.json.* in your project, and don't obfuscate it, the JSON library in use will be the firmware's. However if you enable obfuscation (specifically class renaming/package flattening) the resulting app will use the version in eclipse project. It makes sense but it has caused me a big headache figuring why the production and the debug version behaved subtlely different!Jaggery
@rupps: Interesting point. It makes sense now that you write it. However, it does assume that the entire library can be obfuscated (i.e., no need for keep directives for anything in the library). That's probably true in many cases, though not all cases. If the library is providing something that winds up being used by reflection (e.g., logging classes configured by parsing some configuration file), then this strategy breaks down, though only so many firmware libraries would have this requirement.Hooked
yes you're right, I wasn't posting it as a universal remedy rather than a curious thing, I figured it out by accident trying to find the reason why my app in production behaved differently than the debug version in some specific routine, it was totally crazy, then I found this was the reason. But now that I think about it, it's not that uncommon to include jars in a project that collide with the firmware implementations and at the same use proguard, so in such a case you will get different behaviours between the debug and the production versions in all kind of random places :)Jaggery

© 2022 - 2024 — McMap. All rights reserved.