Open ffarinha-msft opened 2 years ago
Seems to me like this is at least tangentially related to #424, if we could customize the Gson instance ourselves, we could potentially add this type adapter to it. I'm guessing with my workaround you could also make that work right now, sadly with the limitations I mentioned.
When using the feature that some functions triggers implement, of allowing to received data as POJO (like Event Grid trigger ) we found that we cannot deserialize the JSON payload to the type java.time.Instant and if you try you will get the below error:
InaccessibleObjectException: Unable to make field private final long java.time.Instant.seconds accessible: module java.base does not "opens java.time" to unnamed module @41b0ae4c Stack: com.google.gson.JsonIOException: Failed making field 'java.time.Instant#seconds' accessible; either change its visibility or write a custom TypeAdapter for its declaring type at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:22) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:158) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101) at com.google.gson.Gson.getAdapter(Gson.java:501) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:116) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:165) at
This is because Function Java Worker uses GSON library to deserialize the JSON input and this library has historically not been able to deserialize the data to the type java.time.Instant, the Function Java Worker Runtime also inherited this limitation.
Relevant articles: • https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#pojos • GSON Serialization/Deserialization of Java 8 Date API · Issue #1059 · google/gson (github.com)
The java.time.Instant has been released quite a while ago and it should replace the usage of java.util.Date.
Repro steps
To repro this, you simply need to create a hello word Event Grid triggered function and follow this doc. The only change needed is when creating the POJO schema instead of having the eventTime as a date object changing to by of type Instant (java.time.Instant )
NOTE: The repro was performed using Java 17 (but it should be the same for others given the issue is tied to GSON)
Proposed behavior
Based on the GitHub discussion it look to be possible to use a Type Adapter that would allow to use GSON to deserialize to java.time.instant. This could be added by default to function java worker to facilitate the use of POJO with the "new" java.time.instant (assuming this will not break anything on the java worker)
https://github.com/google/gson/issues/1059
https://gist.github.com/mike10004/faa0ca340a9ebf67ed71abe49f997ce9
Known workarounds
Deserialize the JSON payload manually, meaning not using POJO functionality and receiving the JSON data as string to then implement our own code to Deserialize to java.time.Instant (for example Jackson library seems to work fine). But this adds a bit more complexity and somewhat destroys the use of the built in POJO functionality.