-
Notifications
You must be signed in to change notification settings - Fork 263
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
[Java] Class with missing field failed to deserialize on new version #1972
Comments
Hi @orisgarno , thanks for reporting this bug. Could you use We should write class meta in |
Thank you to take a look at this issue @chaokunyang. Wondering though, does it mean that the class meta is already implemented on v0.5.1, but removed on v0.9.0? |
0.5.1 didn't enable meta share mode, so it go to another schema compatible protocol, which write type meta in a KV format. This format is not efficient, and has been replaced by scoped meta share mode in later versions. But we forget to write shared type meta for root class for |
after further read, seems serializeJavaObject API already write class def. which meta are you refering to? maybe if you can help to share some context or pointer it will be much help
thank you |
Hi @chaokunyang. |
Hi @orisgarno which fury version are you using when you try those approaches? |
@chaokunyang the working one was v0.5.1, the failing one is v0.9.0. |
It didn't write class def, the correct code should looks like following: public void serializeJavaObject(MemoryBuffer buffer, Object obj) {
try {
jitContext.lock();
if (depth != 0) {
throwDepthSerializationException();
}
if (config.isMetaShareEnabled()) {
int startOffset = buffer.writerIndex();
buffer.writeInt32(-1); // preserve 4-byte for meta start offsets.
if (!refResolver.writeRefOrNull(buffer, obj)) {
ClassInfo classInfo = classResolver.getOrUpdateClassInfo(obj.getClass());
classResolver.writeClass(buffer, classInfo);
writeData(buffer, classInfo, obj); public <T> T deserializeJavaObject(MemoryBuffer buffer, Class<T> cls) {
try {
jitContext.lock();
if (depth != 0) {
throwDepthDeserializationException();
}
if (shareMeta) {
readClassDefs(buffer);
}
T obj;
int nextReadRefId = refResolver.tryPreserveRefId(buffer);
if (nextReadRefId >= NOT_NULL_VALUE_FLAG) {
ClassInfo classInfo;
if (shareMeta) {
classInfo = classResolver.readClassInfo(buffer);
} else {
classInfo = classResolver.getClassInfo(cls);
}
obj = (T) readDataInternal(buffer, classInfo);
return obj;
} else {
return null;
} And when deserializing, you must register class by id to setup class mapping: static BaseFury s = Fury.builder()
.withRefTracking(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.requireClassRegistration(false)
.serializeEnumByName(true)
.buildThreadSafeFury();
static BaseFury s1 = Fury.builder()
.withRefTracking(true)
.withCompatibleMode(CompatibleMode.COMPATIBLE)
.requireClassRegistration(false)
.serializeEnumByName(true)
.buildThreadSafeFury();
public static class PrivateFliedClassNumberOne {
private boolean privateBoolean = true;
private int privateInt = 10;
private String privateString = "notNull";
private Map<String, String> privateMap = ofHashMap("a", "b");
private List<String> privateList = ofArrayList("l");
private PrivateFieldSubClass privateFieldSubClass = new PrivateFieldSubClass();
}
public static class PrivateFliedClassNumberTwoWithMissingField {
private Map<String, String> privateMap = ofHashMap("a", "b");
private int privateInt = 10;
private PrivateFieldSubClass privateFieldSubClass = new PrivateFieldSubClass();
private List<String> privateList = ofArrayList("l");
private boolean privateBoolean = true;
}
private static class PrivateFieldSubClass{}
@Test
public void test() {
PrivateFliedClassNumberOne privateField = new PrivateFliedClassNumberOne();
s.register(PrivateFliedClassNumberOne.class);
byte[] serialized = s.serializeJavaObject(privateField);
s1.register(PrivateFliedClassNumberTwoWithMissingField.class);
PrivateFliedClassNumberTwoWithMissingField privateField2 = s1.deserializeJavaObject(
serialized,
PrivateFliedClassNumberTwoWithMissingField.class
);
} |
If you want to avoid class registeration, this will need more work, you need to extend |
Thanks for the code and the example @chaokunyang . not so sure for the solution to avoid class registration. seems quite some works. if it doesn't affect the performance, will try to take a look. |
Looking forward to your PR. For registration, if nested field classes are not registered, fury will skip those fields when there is a inconsistency. Currently fury will skip all incompatible fields if theiir declared types are not compatible. There is a PR #1870 which is working on this |
Search before asking
Version
java v0.9.0
Component(s)
Java
Minimal reproduce step
code to repro
What did you expect to see?
Should be able to deserialize successfully
What did you see instead?
exception
Anything Else?
this is the first time i encounter this issue.
i was using fury v0.5.1 and doesnt have this kind of problem. i am also tried to repro this on 0.5.1, but its not happening on that version.
Are you willing to submit a PR?
The text was updated successfully, but these errors were encountered: