Skip to content

[QUESTION]与fastjson1相比,fastjson2的类加载机制发生了变化吗? #3420

@ifreefly

Description

@ifreefly

使用的fastjson1版本:1.2.83
使用的fastjson2版本:2.0.49

同样的代码片段在fastjson1上使用没有问题,但是在切换至fastjson2出现了NoClassDefFoundError
与fastjson1相比,fastjson2在类加载机制上是发生了什么变化吗?

java.lang.NoClassDefFoundError: com/xxx/xxx/xxx/xxx/response/Rpc/InitializeRpcResponse$Initialize$Capabilities
	at com.alibaba.fastjson2.reader.ORG_2_2_Capabilities.createInstance(Unknown Source)
	at com.alibaba.fastjson2.reader.ObjectReaderAdapter.createInstance(ObjectReaderAdapter.java:606)
	at com.alibaba.fastjson2.reader.ObjectReaderAdapter.createInstance(ObjectReaderAdapter.java:635)
	at com.alibaba.fastjson2.JSONObject.to(JSONObject.java:1245)
	at com.alibaba.fastjson2.JSONObject.toJavaObject(JSONObject.java:1255)
	at com.xxx.xxx.xxx.xxx.response.Rpc.InitializeRpcResponse.getInitialize(InitializeRpcResponse.java:26)
	at com.xxx.xxx.xxx.xxx.response.Rpc.InitializeRpcResponse.<init>(InitializeRpcResponse.java:20)
	at com.xxx.xxx.xxx.xxx.LspService.handleResponses(LspService.java:748)
	at com.xxx.xxx.xxx.xxx.JsonRpcUtils.decode(JsonRpcUtils.java:111)
	at com.xxx.xxx.xxx.xxx.LspService.handleLspData(LspService.java:1364)
	at com.xxx.xxx.xxx.xxx.LspService$3.onTextAvailable(LspService.java:1125)
	at com.intellij.execution.process.ProcessHandler$2.onTextAvailable(ProcessHandler.java:289)
	at com.intellij.execution.process.ProcessHandler.notifyTextAvailable(ProcessHandler.java:220)
	at com.intellij.execution.process.BaseOSProcessHandler$SimpleOutputReader.onTextAvailable(BaseOSProcessHandler.java:133)
	at com.intellij.util.io.BaseOutputReader.processInput(BaseOutputReader.java:213)
	at com.intellij.util.io.BaseOutputReader.readAvailableBlocking(BaseOutputReader.java:151)
	at com.intellij.util.io.BaseDataReader.readAvailable(BaseDataReader.java:72)
	at com.intellij.util.io.BaseDataReader.doRun(BaseDataReader.java:153)
	at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:218)
	at com.intellij.util.io.BaseDataReader.lambda$start$0(BaseDataReader.java:48)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.ClassNotFoundException: com.xxx.xxx.xxx.xxx.xxx.xxx.InitializeRpcResponse$Initialize$Capabilities
	at java.base/java.lang.ClassLoader.findClass(ClassLoader.java:723)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:592)
	at com.alibaba.fastjson2.util.DynamicClassLoader.loadClass(DynamicClassLoader.java:190)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
	... 29 more

为了解决这个问题,我们现在在使用json序列化/反序列化的时候是这么写的

ClassLoader oldClassLoader = Thread.currentThread().getContextClassloader();
try {
    Thread.currentThread().setContextClassLoader(User.class.getClassLoader());
    User user = Json.to(User.class, jsonStr);
} finally {
    Thread.currentThread().setContextClassLoader(oldClassLoader);
}

但这么实现很不优雅,也很繁琐,请问是否有什么办法不需要去手动设置classloader?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions