alibaba / alibaba/fastjson2

[BUG] 对于List型的属性,无法使用JSONField指明别名,反序列化时会报错

Open
#1,342 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
4.4k
Forks
613
Avg merge
1d 22h
Merged PRs (30d)
6

Description

### 问题描述

给定一个带有List型属性的 `data class` ,给字段定义别名,欲进行反序列化,报错 `com.alibaba.fastjson2.JSONException: invoke constructor error`

### 环境信息

- OS信息:macOS Ventura 13.3.1
- JDK信息:azul-17.0.6
- 版本信息:fastjson2-kotlin:2.0.27

### 重现步骤

```kotlin
import com.alibaba.fastjson2.JSONReader
import com.alibaba.fastjson2.annotation.JSONField
import com.alibaba.fastjson2.parseObject
import com.alibaba.fastjson2.toJSONString

data class A(
val id: Long,
@field:JSONField(name = "reference_ids")
val referenceIds: List,
@field:JSONField(name = "other_ids")
val otherIds: List
)

fun main() {
println(A(1, listOf(1, 2), listOf(2, 3)).toJSONString())
val string = """
{
"id": 1,
"reference_ids": [
1,
2
],
"other_ids": [
2,
3
]
}
""".trimIndent()
println(string.parseObject(JSONReader.Feature.SupportSmartMatch).toJSONString())
}
```

### 期待的正确结果

```bash
{"id":1,"other_ids":[2,3],"reference_ids":[1,2]}
{"id":1,"other_ids":[2,3],"reference_ids":[1,2]}
```

### 相关日志输出

```bash
{"id":1,"other_ids":[2,3],"reference_ids":[1,2]}
Exception in thread "main" com.alibaba.fastjson2.JSONException: invoke constructor error, public A(long,java.util.List,java.util.List)
at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:193)
at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:16)
at com.alibaba.fastjson2.reader.ObjectReaderNoneDefaultConstructor.readObject(ObjectReaderNoneDefaultConstructor.java:306)
at com.alibaba.fastjson2.JSON.parseObject(JSON.java:853)
at TtKt.main(tt.kt:33)
at TtKt.main(tt.kt)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at com.alibaba.fastjson2.reader.ConstructorFunction.apply(ConstructorFunction.java:191)
... 5 more
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method A., parameter referenceIds
at A.(tt.kt)
... 11 more
```

#### 附加信息

注释掉 `JSONField` 注解一切正常

```kotlin
import com.alibaba.fastjson2.JSONReader
import com.alibaba.fastjson2.annotation.JSONField
import com.alibaba.fastjson2.parseObject
import com.alibaba.fastjson2.toJSONString

data class A(
val id: Long,
// @field:JSONField(name = "reference_ids")
val referenceIds: List,
// @field:JSONField(name = "other_ids")
val otherIds: List
)

fun main() {
println(A(1, listOf(1, 2), listOf(2, 3)).toJSONString())
val string = """
{
"id": 1,
"reference_ids": [
1,
2
],
"other_ids": [
2,
3
]
}
""".trimIndent()
println(string.parseObject
(JSONReader.Feature.SupportSmartMatch).toJSONString())
}
```

```bash
{"id":1,"otherIds":[2,3],"referenceIds":[1,2]}
{"id":1,"otherIds":[2,3],"referenceIds":[1,2]}
```

Contributor guide

Open the contributing guide

Research direction

Start with the Kotlin data class reproduction and trace deserialization through ObjectReaderNoneDefaultConstructor.java and ConstructorFunction.java. Verify why the JSONField aliases leave referenceIds null for List properties, then add a regression test that confirms the shown JSON deserializes and serializes to the expected output.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.