Skip to content
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

Add a default registration if missing Class structure when re… #686

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

maxisvest
Copy link

An recommendation for #643 in #684 , give a default registration if missing Class structure when reading

@maxisvest maxisvest changed the title try to give a default registration if missing Class structure when re… Add a default registration if missing Class structure when re… Aug 12, 2019
@magro magro force-pushed the master branch 3 times, most recently from 19bafd9 to 53bf511 Compare March 8, 2020 20:37
@maxisvest maxisvest closed this May 17, 2020
@maxisvest maxisvest reopened this May 17, 2020
@maxisvest maxisvest closed this May 17, 2020
@maxisvest maxisvest reopened this May 17, 2020
@maxisvest
Copy link
Author

@magro , I reopen this PR for trigger CI rebuild and it has been passed, log is here https://travis-ci.org/github/EsotericSoftware/kryo/builds/687970498, and I don't know why this page show that CI build is still failed.

@magro
Copy link
Collaborator

magro commented May 17, 2020

Not sure either. Maybe rebasing on master would help?

I'd also like to have a test for this, this would also trigger a completely fresh build 😁

The test could use 2 kryo instances, where the 1st kryo instance is configured with a classloader that also "knows" a dynamically generated class.
This could be used for inspiration, although it's only working with a modified class: https://github.com/magro/memcached-session-manager/blob/master/kryo-serializer/src/test/java/de/javakaffee/web/msm/serializer/kryo/SerializationChangeTests.java (and here we should use asm instead of javassist).

@theigl
Copy link
Collaborator

theigl commented Jun 15, 2020

@maxisvest: If you want to get this merged, please provide a testcase that demonstrates what you are trying to achieve with your change.

@maxisvest
Copy link
Author

@theigl : Yes,I will write the test case later. But the change I was provide is used to the case of transfer data in two services, and those two services rely one DTO(Data transfer Object) with different version. Which means this test case can't run automaticlly in one service because you should change DTO structure manually to complete the test case.

@maxisvest
Copy link
Author

@theigl : The test case has been added.

@theigl
Copy link
Collaborator

theigl commented Jul 11, 2020

@maxisvest: Thank you! I tried your test-case against the current master and it does not throw any exceptions in my case. Could this somehow depend on the JDK vendor and version used? I'm using OpenJDK 11 and the class is deserialized without any issue after deleting the SubData.

@maxisvest
Copy link
Author

@theigl : I think this is not depended on any special JDK version. Just like deserializition on other class. Or should I add a switch for this feature?

@theigl
Copy link
Collaborator

theigl commented Jul 12, 2020

@maxisvest: We first need a test-case that can reliably replicate the issue. Please merge the current master into your branch and make sure that your test-case really fails. Currently, I cannot reproduce the issue.

On master, my bean looks like this after following all the steps in your test-case:

image

No exception is thrown.

@maxisvest
Copy link
Author

@theigl : Yes, after merge master the issue is disappeared. Because in FieldSerializer will sort cachedFields by field name. It will make message in front of subData and serialize message first. So I simplely rename subData to aSubData. Make sure aSubData serialize first in DataBean. And then run test agian in current master, my issue will be reliably replicated.

@theigl
Copy link
Collaborator

theigl commented Jul 13, 2020

@maxisvest: Thanks. I can now reproduce your issue and I think I understand what's going on: When chunked encoding is enabled and Kryo encounters an unknown class, it skips the whole chunk as described in the JavaDoc:

In either case, if the data is skipped and {@link Kryo#setReferences(boolean) references} are enabled, then any
references in the skipped data are not read and further deserialization receive the wrong references and fail.

Your fix works by forcing Kryo to read the chunk to a generic object. It solves the problem but could theoretically cause incorrect behavior for other users. We could disable it by default but I'm not sure what we would call the configuration option.

@magro: Do you have an opinion on this?

@magro
Copy link
Collaborator

magro commented Jul 17, 2020

I think I don't understand the consequences completely, e.g. in combination with references.
E.g. I couldn't tell what the documentation for the new setting would be 😉 Having that would help me.

So far I have a slight feeling that this change adds more complexity than value, but that's just a feeling.

Another thought:

In my projects I find it quite naturally to do multi step deployments. E.g. if I want to remove a field from a table/db which is used by multiple instances, at first I change the code to no longer use it (deployment 1) and then I remove the column from the table (deployment 2).

Couldn't the same pattern be applied here?
At first add the class so that all parties/services have that class (deployment 1), then use the class in RPCs (deployment 2)?

@maxisvest
Copy link
Author

@magro : Yes, Theoretically upgrade a common class should take multi step as you says. But to our service system may have special situation on depolyment that is sometime services can't deploy at same time. So it cause the differentiation and I try to avoid it.

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

Successfully merging this pull request may close these issues.

3 participants