owlike / genson

Genson a fast & modular Java <> Json library
http://owlike.github.io/genson/
218 stars 66 forks source link

Reflection Access for Java 16+ #173

Open nicky9door opened 2 years ago

nicky9door commented 2 years ago

Since java 16, there are stricter limits on reflection access to the jdk internals. Calling setAccessible on non-public fields/methods in the base JDK classes causes an InaccessbileObjectException to be thrown. One work around seems to be using the --add-opens flag to allow other modules to access the internal modules but this doesnt work for codebases that arent using module (i.e. classes are in the 'unnamed' module). Alternatively, these non-public members can be excluded when configuring the genson builder, but depending on which classes are being serialized/deserialized, this list might be large and could conceivably break if the internal classes are changed

I looked at the Jackson library and they implemented a change to mitigate this issue by excluding non public fields/methods for classes in the "java." and "javax." package. See here

The quickest way to implement this would probably be to tweak VisibilityFilter.isVisible to exclude non-public members for these internal classes. That being said, this change would likely break existing behaviour. I can create a PR to do this but I was wondering if anyone else could comment as to whether they are encountering this issue and whether such a change would be worth implementing

EugenCepoi commented 2 years ago

Thanks for bringing this up and offering to fix it! I'm not actively working on Genson anymore but contributions are welcome and I can help with that.

Have you tried using Genson with Java 16? I wonder what exactly would break in the existing tests. I suspect this might not be that common of an issue but I might be wrong. Your proposition of implementing it as a VisibilityFilter sounds great to me.

nicky9door commented 2 years ago

I'm in the process of switching to Java 17 and hit a couple snags due to the following classes:

The class that was using Locale was one of my own, so I used annotations to filter it out,

In this case, the Logger was due to deserializing a third-party class which I have no control over. For now, I have used an exclude to avoid serializing/deserializing logger.

I'll admit that its probably not a very common occurrence. If you are serializing/deserializing classes completely within your control, you are lilkely to encounter the issue. But just in case, I will try to create a PR to handle this issue. At the very least, we can leave it pending until there is a clearer understanding of if this is a common issue