[BUG] JSONSchema silently fails to resolve forward references in $defs (loses validation rules depending on key order)
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 613
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Description
### Description
`JSONSchema` silently fails to correctly resolve forward references inside the `$defs` (or `definitions`) block when parsing a schema using `JSONSchema.of()`. It does not throw any exceptions, but quietly loses validation information.
According to the JSON Schema specification, the order of keys in a JSON object is not regulated, and validators must support forward references. However, `fastjson2` processes `$defs` sequentially in a single pass. If a schema definition references another schema that appears later in the `$defs` object, the parser cannot find it in the internal catalog yet. Instead of throwing an error or resolving it lazily, it silently falls back to an empty schema (`{}`), causing incorrect validation behavior.
This issue seems directly related to an incomplete fix in **#1766** (where recursive references were partially introduced). While #1766 fixed certain cyclical cases, the strict key ordering in `$defs` still breaks the parser if the referenced schema hasn't been processed yet during the single-pass iteration.
### Steps to Reproduce
Given a JSON Schema where a definition (`attachments`) references a type (`attachment`) defined later in the `$defs` map:
```json
{
"\$schema": "https://json-schema.org",
"type": "object",
"properties": {
"data": { "\(ref": "#/\)defs/attachments" }
},
"\$defs": {
"attachments": {
"type": "array",
"items": { "\(ref": "#/\)defs/attachment" }
},
"attachment": {
"type": "object",
"properties": {
"id": { "type": "string" }
},
"required": ["id"]
}
}
}
```
### Actual Behavior
No exceptions are thrown, but the reference isn't resolved correctly. When `JSONSchema.of` compiles `attachments`, it looks for `#/$defs/attachment` inside `this.defs`. Since the iteration hasn't reached the `attachment` key yet, it is missing from the catalog, resulting in `items` being compiled as an empty schema `{}`.
As a result, the parsed schema for `attachments` incorrectly becomes:
```json
{"type":"array","items":{}}
```
This breaks any strict validation for array items.
### Expected Behavior
The parser should support forward references within `$defs` regardless of the key order. This can be achieved by using a two-pass compilation approach (registering all definitions first, then resolving internal `$ref` links) or utilizing proper lazy evaluation for references.
### Environment
* **Fastjson2 Version:** 2.0.65
* **JDK Version:** 17
Contributor guide
Research direction
Start at the JSONSchema.of() entry point and trace how the $defs or definitions block is compiled and how internal $ref links are looked up. Reproduce the forward-reference example with the definition order shown, then verify that array item validation still requires the attachment id regardless of definition order.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100