google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.36k stars 4.28k forks source link

Android is upgrading from Java 8 to OpenSDK 17 #2365

Open seventhmoon opened 1 year ago

seventhmoon commented 1 year ago

Follow up on fix Java9 DateFormat changes

1211

Android is moving to newer Java implementations

from https://developer.android.com/about/versions/13/features#core-libraries

Android 13 starts the work of refreshing Android's core libraries to align with the OpenJDK 11 LTS release with both library updates and Java 11 language support for application and platform developers. The core library changes introduced in Android 13 will also be available to Android 12 devices through a Google Play system update to the ART Mainline Module.

And in Android 14, it will update more implementation following OpenJDK 17.

from https://android-developers.googleblog.com/2023/02/first-developer-preview-android14.html

OpenJDK 17 Support - This preview includes access to 300 OpenJDK 17 classes. We are working hard to fully enable Java 17 language features in upcoming developer previews. These include record classes, multi-line strings and pattern matching instanceof. Thanks to Google Play system updates (Project Mainline), over 600M devices are enabled to receive the latest Android Runtime (ART) updates that include these changes. This is part of our commitment to give apps a more consistent, secure environment across devices, and to deliver new features and capabilities to users independent of platform releases.

That may cause issues related to DateFormat as the current implementation in Gson assume Android's implementation will not change.

mihirv0ra commented 1 year ago

Are there other changes that needs to be made to fix this issue other than the DateFormat changes?

Marcono1234 commented 1 year ago

@mihirv0ra, I think the main open questions here are:

If have tested this in Android Studio with an emulator for a device running API level 33 (Android 13) and API level 34. It appears JavaVersion.isJava9OrLater() still returns false because System.getProperty("java.version") returns 0 (as mentioned by the [documentation](https://developer.android.com/reference/java/lang/System?hl=en#getProperties())).

Regarding usages of JavaVersion.isJava9OrLater(): The date format used by Android still seems to be equivalent to the one of Java 8 (at least for DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US)). According to https://developer.android.com/guide/topics/resources/internationalization the used CLDR data for java.text.DateFormat (which is used by Gson) might also not change anymore, but instead the class android.icu.text.DateFormat is updated with the latest CLDR data. And indeed when using android.icu.text.DateFormat it seems to format the date the same way newer Java versions do. And also, Android 13 only includes some of the OpenJDK 11 features, but does apparently not include the Java Platform Module System.

So to me it appears there is no action needed for Gson for now. But please feel free to test this yourself (maybe also on a physical Android device) in case my test setup was incorrect.

seventhmoon commented 1 year ago

the used CLDR data for java.text.DateFormat (which is used by Gson) might also not change anymore

Could it be the impact of Gson is huge so is blocking the change from Android? https://android-review.googlesource.com/c/platform/libcore/+/2519999

Marcono1234 commented 1 year ago

Apparently yes... that is quite unfortunate 😒

In hindsight I assume no one is happy about Gson using a human readable and locale specific formatting of dates by default instead of a well defined format such as ISO-8601. Though I guess this cannot be solved now anymore without breaking backward compatibility.

Edit: To clarify, the above is my personal opinion; I am not a direct member of this project and also was not involved in this project nor in any decisions when Date support was initially added to Gson. Maybe other users see this differently.

seventhmoon commented 1 year ago

Could it be done by re-try? If the 1st parsing with newer patten failed, fallback to the original one?

Marcono1234 commented 1 year ago

Maybe; though at least I am not very familiar with the date handling code of Gson. It appears DateTypeAdapter.deserializeToDate already tries to perform multiple fallback approaches, and #1211 added an additional fallback pattern. There is apparently also some code duplication between DateTypeAdapter and DefaultDateTypeAdapter.

I think the other main problem is that for serialization it uses DateFormat.DEFAULT which could change between Java versions / CLDR versions (as seen in the past). Maybe it would be better to use the formats created by PreJava9DateFormatProvider as default, so that it is unaffected (or at least less affected?) by changes in the Java or Android versions. For a variant which is guaranteed to not change between Java versions, it might even be necessary to duplicate the CLDR logic for the US locale in Gson? For example to account for the hypothetical case that "Tuesday" is not being abbreviated as "Tue" in the future anymore, ..., who knows how locale rules will evolve in the future.

Marcono1234 commented 1 year ago

Hmm, the idea in my previous comment to duplicate CLDR logic is probably neither very realistic nor worth the effort.

Though @seventhmoon, I think you raised some interesting points here. I have created #2472 now to track the idea of switching to ISO 8601 format for Date serialization by default. It is however only an idea for now, and I am not a direct member of the Gson project, so this is not something which is guaranteed to happen. Though at least at the moment, switching the serialization format (but still keeping the fallback approach for deserialization) seems like the most reasonable and permanent solution to this issue to me.