gpt4 book ai didi

java - 在 groovy 中反序列化 java 对象时遇到问题

转载 作者:行者123 更新时间:2023-12-02 05:11:24 25 4
gpt4 key购买 nike

我正在 Groovy/Grails 中开发一个应用程序,它应该处理来自旧数据库的一些数据。已处理表之一中的一列具有 BLOB 类型,并且它存储使用 writeObject() 方法在 Java 中序列化的对象。我可以读取域对象的实例,但是当我尝试使用以下代码反序列化该字段时:

    def stream = new ObjectInputStream(new ByteArrayInputStream(instance.body))
TargetRequest request = (TargetRequest)stream.readObject()
stream.close()

它在第二行(readObject)上吹动

ERROR errors.GrailsExceptionResolver - ClassNotFoundException occurred when processing request

TargetRequest 是我的旧版 Java 对象的 Groovy 副本,但该消息要求原始(旧版)类。我将相应的 JAR 文件作为运行时依赖项添加到我的项目中,但仍然找不到它。这是堆栈跟踪:

    Line | Method
->> 366 | run in java.net.URLClassLoader$1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 355 | run in ''
| 354 | findClass . . . . in java.net.URLClassLoader
| 425 | loadClass in java.lang.ClassLoader
| 358 | loadClass . . . . in ''
| 270 | forName in java.lang.Class
| 625 | resolveClass . . . in java.io.ObjectInputStream
| 1612 | readNonProxyDesc in ''
| 1517 | readClassDesc . . in ''
| 1771 | readOrdinaryObject in ''
| 1350 | readObject0 . . . in ''
| 370 | readObject in ''
| 33 | $tt__doFormat . . in com.abc.def.xyz.DataFormattingService
| 24 | $tt__formatData in ''
| 12 | index . . . . . . in com.abc.def.xyz.DataFormattingServiceController
| 198 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . . . . . in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 744 | run in java.lang.Thread

该堆栈跟踪中的第 33 行指向上述代码行。调查问题时,我在 readObject 调用之前在代码中添加了以下行

TargetRequest targetRequest = Class.forName('com.ijk.mln.domain.TargetRequest').newInstance()

类已成功加载,对象已实例化。为什么它无法在下一行加载完全相同的类,这超出了我的范围。我不知道该怎么做。只是没有更多的想法。

如果有人能帮助我解决这个问题,我将非常感激。

最佳答案

尝试一下:

new ByteArrayInputStream(instance.body).withObjectInputStream(getClass().classLoader) { is ->
TargetRequest targetRequest = (TargetRequest)is.readObject()
}

这样类加载器就会知道序列化的类类型。

<小时/>

根据我对用户评论的理解添加其他信息:

Grails 使用自定义类加载器。子类加载器可以找到父类加载器中加载的类,但反之则不行。因此,一旦我们提供了一个类加载器,它就会使用提供的类加载器而不是默认的。

例如在应用程序中使用以下代码片段:

def cl = getClass().classLoader
log.debug "Child ClassLoader ==> ${cl}"

while(cl.parent){
log.debug "==> ${cl.parent}"
cl = cl.parent
}

将产生如下类似的输出:

Child ClassLoader ==> java.net.URLClassLoader@162ffbfc
==> org.grails.launcher.rootloader.RootLoader@12f483b4
==> sun.misc.Launcher$AppClassLoader@6fafc4c2
==> sun.misc.Launcher$ExtClassLoader@7c9ed5d6

关于java - 在 groovy 中反序列化 java 对象时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27306176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com