Skip to content

Hazelcast4IndexedSessionRepository not using the CacheErrorHandler #2663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
joaquinjsb opened this issue Nov 28, 2023 · 9 comments
Closed

Hazelcast4IndexedSessionRepository not using the CacheErrorHandler #2663

joaquinjsb opened this issue Nov 28, 2023 · 9 comments
Assignees
Labels

Comments

@joaquinjsb
Copy link

Describe the bug
when using hazel cast and the sessions, when there's an issue, it's not being handled by the CacheErrorHandler

To Reproduce

  1. have a project with spring boot 2.7 and hazel cast 5.3.2
  2. configure the session with hazel cast
  3. have an exception, for example, InvalidClassException, which is being wrapped in an com.hazelcast.nio.serialization.HazelcastSerializationException

Expected behavior
in my case for example, if the session is not valid because of serialization, it should treat it as a new one

Sample
whatever recent project, for example this
https://github.com/hazelcast-guides/spring-session-hazelcast

then maybe have multiple instances and change the serial UUID version to generate the exception.

@joaquinjsb joaquinjsb added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 28, 2023
@joaquinjsb
Copy link
Author

joaquinjsb commented Nov 28, 2023

ERROR o.s.b.w.s.support.ErrorPageFilter - Forwarding to error page from request [/endpoint] due to exception [java.io.InvalidClassException: com.org.example.service.domain; local class incompatible: stream classdesc serialVersionUID = 1915983300780842472, local class serialVe
rsionUID = 438016292982441562]
com.hazelcast.nio.serialization.HazelcastSerializationException: java.io.InvalidClassException:  com.org.example.service.domain; local class incompat
ible: stream classdesc serialVersionUID = 1915983300780842472, local class serialVersionUID = 438016292982441562
        at com.hazelcast.internal.serialization.impl.SerializationUtil.handleException(SerializationUtil.java:111)
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:363)
        at com.hazelcast.internal.serialization.InternalSerializationService.readObject(InternalSerializationService.java:81)
        at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:600)
        at com.hazelcast.map.impl.operation.EntryBackupOperation.readInternal(EntryBackupOperation.java:66)
        at com.hazelcast.spi.impl.operationservice.Operation.readData(Operation.java:798)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.readInternal(DataSerializableSerializer.java:167)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:113)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:52)
        at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:44)
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:357)
        at com.hazelcast.internal.serialization.InternalSerializationService.readObject(InternalSerializationService.java:81)
        at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:600)
        at com.hazelcast.spi.impl.operationservice.impl.operations.Backup.readInternal(Backup.java:297)
        at com.hazelcast.spi.impl.operationservice.Operation.readData(Operation.java:798)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.readInternal(DataSerializableSerializer.java:167)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:113)
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:52)
        at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:44)
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:271)
        at com.hazelcast.spi.impl.NodeEngineImpl.toObject(NodeEngineImpl.java:424)
        at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:487)
        at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:202)
        at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:142)
        at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.loop(OperationThread.java:134)
        at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:115)
        at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:111)
        at ------ submitted from ------.()
        at com.hazelcast.internal.util.ExceptionUtil.cloneExceptionWithFixedAsyncStackTrace(ExceptionUtil.java:348)
        at com.hazelcast.spi.impl.AbstractInvocationFuture.wrapRuntimeException(AbstractInvocationFuture.java:1975)
        at com.hazelcast.spi.impl.AbstractInvocationFuture.wrapOrPeel(AbstractInvocationFuture.java:1956)
        at com.hazelcast.spi.impl.AbstractInvocationFuture$ExceptionalResult.wrapForJoinInternal(AbstractInvocationFuture.java:1438)
        at com.hazelcast.spi.impl.AbstractInvocationFuture.resolveAndThrowForJoinInternal(AbstractInvocationFuture.java:601)
        at com.hazelcast.spi.impl.AbstractInvocationFuture.joinInternal(AbstractInvocationFuture.java:585)
        at com.hazelcast.map.impl.proxy.MapProxyImpl.executeOnKey(MapProxyImpl.java:826)
        at org.springframework.session.hazelcast.Hazelcast4IndexedSessionRepository.save(Hazelcast4IndexedSessionRepository.java:267)

@marcusdacoregio
Copy link
Contributor

Hi, @joaquinjsb.

Based on the stack trace, it seems that the serialization problem comes from a class from your domain, under the com.org.example.service.domain package. Please check if you have a serialVersionUID in that class or, if not, you might have removed/added/changed fields in that class, therefore changing the serial version.

If you still believe there is a bug in Spring Session, please provide a minimal, reproducible sample and we can reopen this issue.

@marcusdacoregio marcusdacoregio self-assigned this Nov 28, 2023
@marcusdacoregio marcusdacoregio added status: invalid and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 28, 2023
@joaquinjsb
Copy link
Author

joaquinjsb commented Nov 28, 2023

the minimal sample is the link to the repo I posted you, to reproduce it i wrote the steps, you just need to start one instance, then change the UID version and start the second node, and this problem is replicable.

the issue as I explained is on the Hazelcast4IndexedSessionRepository.save, it's not using any sort of error management, which I would expect due to the implementation of the CacheErrorHandler.

@marcusdacoregio
Copy link
Contributor

Spring Session Hazelcast does not use any CacheErrorHandler, I do not follow what you mean in this case.

It is expected to have an error between two same classes with different serial versions, you should configure a custom serialization for the object(s) you're having issues with. This way you would address your problem in Hazelcast configuration without extending/duplicating Spring Session's Hazelcast configuration.

@joaquinjsb
Copy link
Author

the issue is not the de-serialization it self, the serialization is fine, the problem is presented when you deploy a different version of the session object, which then, fails because of the different object, at this point, we need to have the option to handle it gracefully, I'm referring to the CacheErrorHandler, because spring recommends to use it to have a single global object to handle cache issues.

this line of code throws the RuntimeException I'm talking about.

@marcusdacoregio
Copy link
Contributor

There is some confusion here. Spring Session is not about a cache implementation, it provides an API and implementations for managing a user’s session information while also making it trivial to support clustered sessions without being tied to an application container-specific solution. There is nothing related to CacheErrorHandler.

Your stacktrace shows a deserialization error from your domain class, which should be handled by you as I mentioned here.

If you still believe there is a bug in Spring Session and its domain classes, please provide a minimal, reproducible sample and we can reopen this issue.

@joaquinjsb
Copy link
Author

There's no confusion at all, I'm referring to the cache error handler as an example of what is done in this case when using a cache provider,
Once again the repository is posted on the main thread link.

When there's an runtime exception when the repository is saving, there's no any sort of error management, in the hazelcast there's no need to customize it because it's using the standard Java Serializable, the issue here is that what you are asking is to use custom serializers that are explicitly tied to Hazelcast.

The issue I'm explaining here is that the code should have a graceful management of the RuntimeException that would deal with a simple in case of "failure during merge/delta update", just save a new one.

@marcusdacoregio
Copy link
Contributor

Please see #529

@joaquinjsb
Copy link
Author

so I'd looks like stalled as of now right?

#1913

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants