Skip to content

[Java] Something wrong when deserializing EXT type #2698

@urlyy

Description

@urlyy

Search before asking

  • I had searched in the issues and found no similar issues.

Version

latest

Component(s)

Java

Minimal reproduce step

@Data
static class MyExt {
  int id;

  public MyExt(int id) {
    this.id = id;
  }

  public MyExt() {}
}

private static class MyExtSerializer extends Serializer<MyExt> {

  public MyExtSerializer(Fory fory, Class<MyExt> cls) {
    super(fory, cls);
  }

  @Override
  public void write(MemoryBuffer buffer, MyExt value) {
    xwrite(buffer, value);
  }

  @Override
  public MyExt read(MemoryBuffer buffer) {
    return xread(buffer);
  }

  @Override
  public void xwrite(MemoryBuffer buffer, MyExt value) {
    fory.xwriteRef(buffer, value.id);
  }

  @SuppressWarnings("unchecked")
  @Override
  public MyExt xread(MemoryBuffer buffer) {
    MyExt obj = new MyExt();
    fory.getRefResolver().reference(obj);
    obj.id = (int) fory.xreadRef(buffer);
    return obj;
  }
}

@Test
public void testExt() {
  Fory fory =
      Fory.builder()
          .withLanguage(Language.XLANG)
          .withCompatibleMode(CompatibleMode.COMPATIBLE)
          .withCodegen(false)
          .build();
  fory.register(MyExt.class, 103);
  fory.registerSerializer(MyExt.class, MyExtSerializer.class);
  MyExt myExt = new MyExt(42);
  byte[] serialize = fory.serialize(myExt);
  MyExt newExt = (MyExt) fory.deserialize(serialize);
  Assert.assertEquals(myExt, newExt);
}

What did you expect to see?

pass test

What did you see instead?


org.apache.fory.exception.DeserializationException: Failed to deserialize input

	at org.apache.fory.util.ExceptionUtils.handleReadFailed(ExceptionUtils.java:66)
	at org.apache.fory.Fory.deserialize(Fory.java:889)
	at org.apache.fory.Fory.deserialize(Fory.java:785)
	at org.apache.fory.RustXlangTest.testExt(RustXlangTest.java:739)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:136)
	at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:658)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:219)
	at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
	at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:923)
	at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:192)
	at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.testng.TestRunner.privateRun(TestRunner.java:808)
	at org.testng.TestRunner.run(TestRunner.java:603)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
	at org.testng.SuiteRunner.run(SuiteRunner.java:326)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
	at org.testng.TestNG.runSuites(TestNG.java:1092)
	at org.testng.TestNG.run(TestNG.java:1060)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:65)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:105)
Caused by: java.lang.IllegalStateException: Type id 26387 not registered
	at org.apache.fory.resolver.XtypeResolver.throwUnexpectTypeIdException(XtypeResolver.java:774)
	at org.apache.fory.resolver.XtypeResolver.readClassInfo(XtypeResolver.java:751)
	at org.apache.fory.Fory.xreadNonRef(Fory.java:1086)
	at org.apache.fory.serializer.SerializationBinding$XlangSerializationBinding.readNonRef(SerializationBinding.java:390)
	at org.apache.fory.serializer.AbstractObjectSerializer.readOtherFieldValue(AbstractObjectSerializer.java:140)
	at org.apache.fory.serializer.MetaSharedSerializer.read(MetaSharedSerializer.java:216)
	at org.apache.fory.serializer.MetaSharedSerializer.xread(MetaSharedSerializer.java:261)
	at org.apache.fory.Fory.xreadNonRef(Fory.java:1121)
	at org.apache.fory.Fory.xreadRef(Fory.java:1056)
	at org.apache.fory.Fory.deserialize(Fory.java:883)
	... 29 more

Anything Else?

Reason: It seems that registerSerializer() did not re-add the new xtypeId to the xtypeIdToClassMap. It is necessary to roll back the operations in the previous register() and then cache the typeInfo with the new ext-xtypeId.

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions