Fastjson: 1.2.37版本开始出现:default constructor not found 异常

Created on 7 Nov 2017  ·  45Comments  ·  Source: alibaba/fastjson

1.2.40版本,kotlin代码如下:

class User() {
    constructor(userId: Long, loginName: String) : this() {
        this.userId = userId
        this.loginName = loginName
    }

    var userId: Long = Long.MIN_VALUE
        private set
    var loginName: String = ""
        private set
}


fun main(args: Array<String>) {
    val json = "{\"loginName\":\"san\",\"userId\":1}"
    JSON.parseObject(json, User::class.java)
}

异常:

Exception in thread "main" com.alibaba.fastjson.JSONException: default constructor not found. class com.juxia.mpcrm.application.model.User
    at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:450)
    at com.alibaba.fastjson.util.JavaBeanInfo.build(JavaBeanInfo.java:211)
    at com.alibaba.fastjson.parser.ParserConfig.createJavaBeanDeserializer(ParserConfig.java:611)
    at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:528)
    at com.alibaba.fastjson.parser.ParserConfig.getDeserializer(ParserConfig.java:341)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:637)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:365)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:269)
    at com.alibaba.fastjson.JSON.parseObject(JSON.java:488)
    at com.juxia.mpcrm.application.model.SessionUserKt.main(SessionUser.kt:23)

已经提供无参默认构造函数为什么还说找不到?

bug

Most helpful comment

楼上各位,
请在depencies里边加上 compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
就不会出现此错误了.

All 45 comments

通过测试,发现1.2.37这个版本开始出现了这个问题,1.2.37以下版本没有问题。

这难道不是个bug吗?怎么没人关注回应?

抱歉,已经关注到了,但这两天比较忙,会尽快跟进的

@wenshao 我也出了同样的问题,求解决。我是为了解决反序列时服务器返回的Json中有字段为Null造成的数据模型对应字段空指针的错误,才想升级的。结果升级后就出现了这个问题。顺便问一下,碰到反序列化服务器数据返回某个字段为Null时,如何避免kotlin中空检查报错的问题啊?

谢谢反馈,问题已经重现并解决,预计月底前会发布新版本

@wenshao 问题在1.2.41中依然存在, 就我提供的用例都没跑过

https://github.com/alibaba/fastjson/releases/tag/1.2.42
新版已发布,请验证问题是否已经修复。

@wenshao 经测试,版本 1.2.37+在解析 kotlin 类时,还是报 default constructor not found Exception

kotlin 版本 kotlin-stdlib-jre8:1.1.61kotlin-stdlib-jre8:1.1.50kotlin-stdlib-jre8:1.1.4 都是如此

@wenshao 用原来的代码测试 1.2.44 版本,问题依旧 @.@

android 1.1.67 还是会报错 = =

17年到现在18年1月31号,还没修复。。。

能提供重现问题的testcase么?上面的testcase已经跑过的,可能还是有场景没有解决

https://github.com/alibaba/fastjson/wiki/Use-Fastjson-in-Kotlin 直接用你们的case都跑不通,1.2.44和1.2.45两个版本都跑不通

@zhuyonghao 这些例子都是有回归测试的,都是跑过的。能否提供你跑不通的更详细环境信息?

使用最新版本1.2.46
用例一 data class JsonVo(@JSONField(name = "id")val id: String = "", @JSONField(name = "name")val name: String = "")
用例二 data class JsonVo(val id: String = "", @JSONField(name = "name")val name: String = "")

fun main(args: Array) {
val jsonStr = "[{"id":"1", "name":"1"}, {"id":"2", "name":"2"}]"
val jsonList = JSON.parseArray(jsonStr, JsonVo::class.java)
}
使用用例二则报错 default constructor not found ,用例一则正常,区别是用例二部分有JSONField

1.2.35版本则都正常,麻烦看下!

@wenshao

楼上各位,
请在depencies里边加上 compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
就不会出现此错误了.

@exhui 你加上kotlin-reflect试试看

带上默认参数没问题,在1.1.65版本上;但同时再加上有参的构造方法后,又会出现这个问题了(找不到默认的构造函数);

@faith-hb 能提供重现问题的case么?

版本切换到1.2.35 同时增加 compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 反射的依赖. 我就可以了. 用最新的1.2.46 还是不可以的.

不增加 compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 反射的依赖,1.2.35版本可以,1.2.4版本不行。

好像把as的instant run功能关掉就好了

这个再第一次安装的时候不会出现问题,但是我把安装包传到腾讯Bugly上,旧版本更新新版本的时候会出现这个问题,而单独安装不会出现这个问题

I faced the same issue and raised a bug. I hope someone can help.
https://github.com/alibaba/fastjson/issues/1804

我最终选择了 GSON .
经过上次的调整后,发现部分情况下还是无法使用.
经过几天的测试,发现 FastJson 针对此问题一直以来都没有准备修复. 挣扎了几天之后,最终更坏为 GSON, 完美解决所有问题.

解决办法:
1.使用static类
2.创建一个interface IFastJson,将此类的内部类实现implements IFastJson
3.在proguard.txt中配置
-keep class * implements com.xxxx.IFastJson

1.2.49 fastJson 和 1.1.70 android 版本,普通 kotlin data class 还是会报 ‘default constructor not found.’ 需要依赖 kotlin-reflect 才能解决。

@wenshao 我在android上用了1.2.49,只要是release版,已经@Keep了数据类,但仍然会提示default constructor not found,我也加了kotlin-reflect库,一点用没有。但debug版就没问题

已经找到原因了,是proguard使kotlin-reflect失效了,在proguard.pro中加上如下就没问题了:

-keepattributes *Annotation*
-keep class kotlin.** { *; }
-keep class org.jetbrains.** { *; }

reflect 包 1w+ 方法数,为了解决一个 crash ,compile 那么多方法不值得吧..

对移动端来说代价是不可忽视的,希望后续可以采用别的方式实现对Adnroid版本的优化

我最终选择了 GSON .
经过上次的调整后,发现部分情况下还是无法使用.
经过几天的测试,发现 FastJson 针对此问题一直以来都没有准备修复. 挣扎了几天之后,最终更坏为 GSON, 完美解决所有问题.

我也打算用GSON,但是用着发现另一个问题,我封装的带泛型的类,GSON解决不了,泛型会丢失

在使用jdk的反序列化时,会出现 JSONException:default constructor not found. 异常,case如下:

package com.alibaba.json;

import com.alibaba.fastjson.JSONObject;
import org.junit.Test;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class TestSerializer {

@Test
public void testSerilzier(){
    List<String> list = Arrays.asList("123","23444");
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("list", list);
    byte[] serialize = serialize(jsonObject);
    Serializable serializable = deserialize(serialize);
    Serializable seri = deserialize(serialize);
    System.out.println(serializable);    // 返回 null,  原因反序列化异常  default constructor not found.
    System.out.println(seri);    // 再次反序列化 正常返回  

}
public static byte[] serialize(Serializable o) {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        byte[] bytes = null;

        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(o);
            oos.flush();
            bytes = bos.toByteArray();
        } catch (Exception var13) {
        } finally {
            try {
                oos.close();
                bos.close();
            } catch (Exception var12) {
            }

        }
        return bytes;
}


public static Serializable deserialize(byte[] bytes) {
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        Object o = null;

        try {
            bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            o = ois.readObject();
        } catch (Exception var13) {
            System.out.println(var13);
        } finally {
            try {
                ois.close();
                bis.close();
            } catch (Exception var12) {
            }

        }

        return (Serializable)o;
}

}

在使用jdk的反序列化时,会出现 JSONException:default constructor not found. 异常,case如下:

package com.alibaba.json;

import com.alibaba.fastjson.JSONObject;
import org.junit.Test;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class TestSerializer {

@Test
public void testSerilzier(){
    List<String> list = Arrays.asList("123","23444");
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("list", list);
    byte[] serialize = serialize(jsonObject);
    Serializable serializable = deserialize(serialize);
    Serializable seri = deserialize(serialize);
    System.out.println(serializable);    // 返回 null,  原因反序列化异常  default constructor not found.
    System.out.println(seri);    // 再次反序列化 正常返回  

}
public static byte[] serialize(Serializable o) {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        byte[] bytes = null;

        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(o);
            oos.flush();
            bytes = bos.toByteArray();
        } catch (Exception var13) {
        } finally {
            try {
                oos.close();
                bos.close();
            } catch (Exception var12) {
            }

        }
        return bytes;
}


public static Serializable deserialize(byte[] bytes) {
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        Object o = null;

        try {
            bis = new ByteArrayInputStream(bytes);
            ois = new ObjectInputStream(bis);
            o = ois.readObject();
        } catch (Exception var13) {
            System.out.println(var13);
        } finally {
            try {
                ois.close();
                bis.close();
            } catch (Exception var12) {
            }

        }

        return (Serializable)o;
}

}

确实如此,项目在使用Memcache + fastjson(1.2.54) 在 JsonObject 进行jdk反序列化时,必现这个问题

应该是在1.2.49 版本 新增了JSONObject 类的 序列化 方法 readObject导致的

我添加上无参的构造函数就不会 版本:1.1.67.android

有些第三方的jar包里面的类,怎么解决?

------------------ 原始邮件 ------------------
发件人: "weizhizhu"<[email protected]>;
发送时间: 2019年11月20日(星期三) 晚上6:39
收件人: "alibaba/fastjson"<[email protected]>;
抄送: "玩转生活!"<[email protected]>;"Comment"<[email protected]>;
主题: Re: [alibaba/fastjson] 1.2.37版本开始出现:default constructor not found 异常 (#1569)

我添加上无参的构造函数就不会 版本:1.1.67.android


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.

kotlin版本:1.3.61
fastjson版本:1.2.49和1.1.7.android

Bean:

data class Article(
    var id: Long,
    var title: String,
    var content: String,
    var categoryId: Long,
    var createDateTime: String
)

仍然报出这个异常。加了kotlin的反射库之后,报错:java.lang.exception:""

这个异常我记得我在17年刚转kotlin的时候就遇到了,没想到2年过去了,这bug还没解决,还给关闭了,难道是不管了?

还是用moshi算了。。

bug还没有解决

bug还没解决kotlin必现

哎。这都几年了还是这个bug。。。我就是进来看看。

Was this page helpful?
0 / 5 - 0 ratings