serializer icon indicating copy to clipboard operation
serializer copied to clipboard

Some issues de/serializing certain types. e.g. EnumSet, Exceptions and Records

Open RafaShobr opened this issue 1 year ago • 4 comments

Environment Details

  • Eclipse Serializer Version: 1.0.0
  • JDK version: 17.0.7
  • OS: Windows 10

Describe the bug

Hello! I stumbled across your de/serialization framework, which looks great! As we are just in the middle of transitioning away from hessian, I thought to give it a try. :) We have created a little testsuite to check if serialization works for us and a few things seem to be not working, so I wanted to ask if these are bugs or if I need to configure something or if there is any other way around the issues.

  1. exceptions: org.eclipse.serializer.persistence.exceptions.PersistenceExceptionTypeNotPersistable: Type not persistable: "class java.lang.Exception". Is there a way to enable exceptions?
  2. EnumSet: java.lang.NullPointerException: Cannot load from object array because "this.this$0.universe" is null
  3. BitSet: does not seem to be properly de/serialized (Expected :{135}, Actual :{})
  4. ImmutableList: e.g. List.of(1) -> Expected :[1] Actual :[1, java.lang.Object@69d2e517] some strange object in the list?
  5. ImmutableSet: like above, but with Set.of(1)
  6. de/serializing an object that has transient fields which are initialized like e.g. private transient ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); private transient WriteLock wLock = rwLock.writeLock(); private transient ReadLock rLock = rwLock.readLock(); the fields remain null. -> nullreference in later code
  7. When trying to de/serialize records, I get Could not obtain access to "jdk.internal.misc.Unsafe", please start the VM with --add-exports java.base/jdk.internal.misc=ALL-UNNAMED

Regards, Raphael

RafaShobr avatar Nov 02 '23 13:11 RafaShobr

Hello, first, I must apologize for the late reaction to your post, many thanks for that. So here are some late answers to your questions:

Is there a way to enable exceptions?

There is no simple solution currently. This requires a modification in the sources. The good news is that we are already working on a solution that should be available in the near future.

EnumSet and BitSet:

Both types are currently bugged as they require new custom type handlers as the java implementations of those classes have changed. As we had no requests for that implementing those handlers is no planed yet.

ImmutableList and ImmutableSet:

Similar to EnumSet, for java 17 and above you can register specialized type handler for those classes. Therefore you need to add the persistence-binary-jdk17 package:

<dependency>
    <groupId>org.eclipse.serializer</groupId>
    <artifactId>persistence-binary-jdk17</artifactId>
    <version>1.0.0</version>
</dependency>

And register the required java 17 handlers to the serializer:

final SerializerFoundation<?> foundation = SerializerFoundation.New();
BinaryHandlersJDK17.registerJDK17TypeHandlers(foundation);
final Serializer<byte[]> serializer = Serializer.Bytes(foundation);

de/serializing transient fields:

By default transient fields are ignored as they are not part of the persistent state of an object. But you can use a custom PersistenceFieldEvaluator to change that behavior:

final SerializerFoundation<?> foundation = SerializerFoundation.New();
foundation.setFieldEvaluatorPersistable((entityType, field) -> {
	
	//TODO: return true if a specific field of a class (entityType) should be persisted
	
	//Default is false if field is transient
	return !XReflect.isTransient(field);
});

final Serializer<byte[]> serializer = Serializer.Bytes(foundation);

de/serialize records:

To use records you need to run your VM with --add-exports java.base/jdk.internal.misc=ALL-UNNAMED due to access restrictions introduced with java 15.

hg-ms avatar Dec 04 '23 11:12 hg-ms

Do you have any hunch if the --add-exports java.base/jdk.internal.misc=ALL-UNNAMED workaround can be removed in future releases? It feals bit "fragile" and for my apps (demo apps, working as a developer advocate) I'd like to remove all extra configurations. And in deployment I'd also wish to remove all extra configurations.

For my current project I first modeled my domain with records, an then asked ChatGPT to convert it to pojos as I didn't want to swap out EclipseStore...

mstahv avatar Apr 19 '24 06:04 mstahv

I'm afraid we have to stick to --add-exports because of Record's reflection restrictions. I didn't find any plans of the JDK team to change that in the future.

fh-ms avatar Jul 09 '24 13:07 fh-ms

To expand on the fragility theme, if I take an app (using --add-exports) that works fine with records, and make it a modular java app, run fails with:

java.lang.IllegalAccessException: class org.eclipse.serializer.memory.sun.JdkInternals (in module 
org.eclipse.serializer.base) cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base 
does not export jdk.internal.misc to module org.eclipse.serializer.base

(I can file a report with test code producing this if desired). The set of modular java apps with records is potentially large I should think, and having EclipseStore/Serializer unusable without a rewrite would be unfortunate.

richardrodgers avatar Jul 25 '24 19:07 richardrodgers

closed, discursive

hg-ms avatar Sep 03 '24 07:09 hg-ms