Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

kotlin在多线程下反序列化会报错 #1488

Closed
sd4324530 opened this issue Sep 21, 2017 · 10 comments
Closed

kotlin在多线程下反序列化会报错 #1488

sd4324530 opened this issue Sep 21, 2017 · 10 comments
Labels
Milestone

Comments

@sd4324530
Copy link

kotlin 1.1.4-3
jdk 1.8-112
fastjson 1.2.38
场景是开多线程,反序列化同一个data class,使用的方法是JSON.parseObject(String, Class)
线程数在1-3的时候正常,从4个线程开始,出现报错:
com.alibaba.fastjson.JSONException: default constructor not found. class com.haiziwang.platform.krediskt.common.pojo.info.Server
at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:409)
at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:175)
at com.alibaba.fastjson.parser.ParserConfig.createJavaBeanDeserializer(ParserConfig.java:602)
at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:519)
at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:341)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:623)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:348)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:252)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:471)

跟了下代码,发现应该是TypeUtils.getKoltinConstructorParameters(Class)这个方法的问题
刚进入这个方法,TypeUtils类中kotlin_kclass_constructor属性就不为空,但是kotlin_kclass_getConstructors为空,导致在TypeUtils.java的2091行报错空指针,导致这个方法返回null,然后出现上述问题

@sd4324530
Copy link
Author

附上我报错的data class,就是封装了redis命令:info Server的返回内容

data class Server(
        @JSONField(name = "redis_version")
        var redisVersion: String? = null,

        @JSONField(name = "redis_git_sha1")
        var redisGitSha1: String? = null,

        @JSONField(name = "redis_git_dirty")
        var redisGitDirty: String? = null,

        @JSONField(name = "redis_build_id")
        var redisBuildId: String? = null,

        @JSONField(name = "redis_mode")
        var redisMode: String? = null,

        var os: String? = null,

        @JSONField(name = "arch_bits")
        var archBits: String? = null,

        @JSONField(name = "multiplexingApi")
        var multiplexing_api: String? = null,

        @JSONField(name = "gcc_version")
        var gccVersion: String? = null,

        @JSONField(name = "process_id")
        var processId: Int? = null,

        @JSONField(name = "run_id")
        var runId: String? = null,

        @JSONField(name = "tcp_port")
        var tcpPort: Int? = null,

        @JSONField(name = "uptime_in_seconds")
        var uptimeInSeconds: Int? = null,

        @JSONField(name = "uptime_in_days")
        var uptimeInDays: Int? = null,

        var hz: String? = null,

        @JSONField(name = "lru_clock")
        var lruClock: String? = null,

        @JSONField(name = "config_file")
        var configFile: String? = null
)

@sd4324530
Copy link
Author

TypeUtils.getKoltinConstructorParameters(Class)这个方法貌似确实不是线程安全的,主要是方法里使用到的几个静态变量的初始化问题

@wenshao wenshao added the bug label Sep 21, 2017
@wenshao wenshao added this to the 1.2.39 milestone Sep 21, 2017
@wenshao
Copy link
Member

wenshao commented Sep 24, 2017

不应该哈,报错应该是别的原因导致的

@sd4324530
Copy link
Author

sd4324530 commented Sep 25, 2017

我的整个代码只调整了线程数,其他都没有动,当线程数变大后,开始出现这个异常的,也通过断点跟踪了代码,确实是TypeUtils类中kotlin_kclass_constructor属性就不为空,但是kotlin_kclass_getConstructors为空,导致在TypeUtils.java的2091行报错空指针

TypeUtils.getKoltinConstructorParameters(Class)这个方法所初始化的那几个静态变量,只是各自是volatile的,但是整个方法并不是线程安全啊,我觉得原因可能是出在这

@sd4324530
Copy link
Author

sd4324530 commented Sep 27, 2017

我写了个测试例子,线程数小的时候(<3),出现的概率很小,基本可以正常执行,但是线程数调大(>10),基本是必现,@wenshao 你可以用这个试试看

const val THREAD_NUMBER = 10

fun main(args: Array<String>) {
    val threadPool = Executors.newScheduledThreadPool(THREAD_NUMBER)
    for (i in 1..THREAD_NUMBER) {
        println("start....")
        threadPool.scheduleAtFixedRate({
            val map = mapOf("id" to 1, "name" to "test1")
            try {
                println(JSON.parseObject(JSON.toJSONString(map), User::class.javaObjectType))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }, 1, 1, TimeUnit.SECONDS)
    }
}

data class User(val id: Int, val name: String)

wenshao added a commit that referenced this issue Oct 1, 2017
@wenshao
Copy link
Member

wenshao commented Oct 1, 2017

我写了测试,问题没有重现

@sd4324530
Copy link
Author

你这个例子是java写的哇,我这个问题是使用kotlin调用时出现的,我上面发的那段代码,问题是必现的呀

@wenshao
Copy link
Member

wenshao commented Oct 1, 2017

https://github.com/alibaba/fastjson/releases/tag/1.2.39
帮忙用新版本验证一下,如果还不行,可以直接微信找我 wenshaojin

@wenshao
Copy link
Member

wenshao commented Oct 10, 2017

问题重现并修复,非常感谢反馈问题

@wenshao
Copy link
Member

wenshao commented Nov 4, 2017

https://github.com/alibaba/fastjson/releases/tag/1.2.40
问题已经修复,请用新版本

@wenshao wenshao closed this as completed Nov 4, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants