-
Notifications
You must be signed in to change notification settings - Fork 331
OneOf vs AnyOf validators - java.lang.OutOfMemoryError: Java heap space #1162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It is the I think it's a viable solution given that my edit: clarification |
It appears that |
Recursive schema is always a problem as we are loading the schema in memory for validation. Is there a way to imporve the schema design? |
Hi @stevehu , Yes I understand the complexity of this, and we might have hit a very reasonable limit. Just mentioned here in case this was something that may have slipped during loading the refs. Feel free to close this issue if this was something totally expected. As a gut feeling, given a recursive schema, I think there's room for a different data structure for keeping it in memory, but I don't know if it is worthy it since you will be just pushing the limit further. Thanks |
This is poor schema design. You will get poor performance regardless of whether there is enough memory as
Your {
"allOf": [
{
"if": {
"properties": {
"$type": { "const": "is" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-is" }
},
{
"if": {
"properties": {
"$type": { "const": "contains" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-contains" }
},
{
"if": {
"properties": {
"$type": { "const": "and" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-and" }
},
{
"if": {
"properties": {
"$type": { "const": "or" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-or" }
},
{
"if": {
"properties": {
"$type": { "const": "true" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-true" }
},
{
"if": {
"properties": {
"$type": { "const": "one-of" }
},
"required": ["$type"]
},
"then": { "$ref": "#/$defs/rule-oneOf" }
},
{
"properties": {
"$type": { "enum": ["is","contains","and","or","true","one-of"] }
},
"required": ["$type"]
}
]
} Example {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "http://echa.europa.eu/dynamic_forms/schemas/config/definitions",
"type": "object",
"properties": {
"outcomeRules": {
"type": "array",
"title": "Rules calculating the outcome",
"items": {
"$ref": "#/$defs/factRule"
}
}
},
"required": [
"outcomeRules"
],
"$defs": {
"factRule": {
"type": "object",
"properties": {
"fact": {
"type": "string",
"minLength": 1
},
"description": {
"type": "string",
"minLength": 1
},
"condition": {
"$ref": "#/$defs/ruleCondition"
}
},
"required": [
"fact",
"condition"
]
},
"ruleCondition": {
"allOf": [
{
"if": {
"properties": {
"$type": {
"const": "is"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-is"
}
},
{
"if": {
"properties": {
"$type": {
"const": "contains"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-contains"
}
},
{
"if": {
"properties": {
"$type": {
"const": "and"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-and"
}
},
{
"if": {
"properties": {
"$type": {
"const": "or"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-or"
}
},
{
"if": {
"properties": {
"$type": {
"const": "true"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-true"
}
},
{
"if": {
"properties": {
"$type": {
"const": "one-of"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-oneOf"
}
},
{
"properties": {
"$type": {
"enum": [
"is",
"contains",
"and",
"or",
"true",
"one-of"
]
}
},
"required": [
"$type"
]
}
]
},
"rule-contains": {
"type": "object",
"properties": {
"$type": {
"const": "contains"
},
"field": {
"type": "string",
"minLength": 1
},
"value": {
"oneOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "boolean"
},
{
"type": "integer"
}
]
},
"not": {
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"$type",
"field",
"value"
]
},
"rule-is": {
"type": "object",
"properties": {
"$type": {
"const": "is"
},
"field": {
"type": "string",
"minLength": 1
},
"not": {
"type": "boolean"
},
"value": {
"oneOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "boolean"
},
{
"type": "integer"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"required": [
"$type",
"field"
]
},
"rule-and": {
"type": "object",
"properties": {
"$type": {
"const": "and"
},
"not": {
"type": "boolean"
},
"members": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"allOf": [
{
"if": {
"properties": {
"$type": {
"const": "is"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-is"
}
},
{
"if": {
"properties": {
"$type": {
"const": "contains"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-contains"
}
},
{
"if": {
"properties": {
"$type": {
"const": "and"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-and"
}
},
{
"if": {
"properties": {
"$type": {
"const": "or"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-or"
}
},
{
"if": {
"properties": {
"$type": {
"const": "one-of"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-oneOf"
}
},
{
"properties": {
"$type": {
"enum": [
"is",
"contains",
"and",
"or",
"one-of"
]
}
},
"required": [
"$type"
]
}
]
}
}
},
"additionalProperties": false,
"required": [
"$type",
"members"
]
},
"rule-or": {
"type": "object",
"properties": {
"$type": {
"const": "or"
},
"not": {
"type": "boolean"
},
"members": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"allOf": [
{
"if": {
"properties": {
"$type": {
"const": "is"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-is"
}
},
{
"if": {
"properties": {
"$type": {
"const": "contains"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-contains"
}
},
{
"if": {
"properties": {
"$type": {
"const": "and"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-and"
}
},
{
"if": {
"properties": {
"$type": {
"const": "or"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-or"
}
},
{
"if": {
"properties": {
"$type": {
"const": "one-of"
}
},
"required": [
"$type"
]
},
"then": {
"$ref": "#/$defs/rule-oneOf"
}
},
{
"properties": {
"$type": {
"enum": [
"is",
"contains",
"and",
"or",
"one-of"
]
}
},
"required": [
"$type"
]
}
]
}
}
},
"additionalProperties": false,
"required": [
"$type",
"members"
]
},
"rule-true": {
"type": "object",
"properties": {
"$type": {
"const": "true"
},
"not": {
"type": "boolean"
}
},
"additionalProperties": false,
"required": [
"$type"
]
},
"rule-oneOf": {
"type": "object",
"properties": {
"$type": {
"const": "one-of"
},
"field": {
"type": "string",
"minLength": 1
},
"not": {
"type": "boolean"
},
"values": {
"type": "array",
"items": {
"oneOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "boolean"
},
{
"type": "integer"
},
{
"type": "null"
}
]
}
}
},
"additionalProperties": false,
"required": [
"$type",
"field",
"values"
]
}
}
} |
Hi @justin-tay , Thanks a million for this, this is a far better version of it. |
Uh oh!
There was an error while loading. Please reload this page.
Hi,
(version is 1.5.6)
We are facing an out-of-memory error while validating a nested data structure against a "one-of" restriction of a recursive schema.
In the attached
definitions copy.json
, if we change "one-of" to "any-of" in lines 147 and 187, theAnyOfValidator
is being triggered instead and problem is not reproducible. However, doing that change on our side will lead to a looser schema and we want to avoid that.In order to reproduce the problem, trying running the following unit test with -Xmx512m. Files being used are attached.
data copy.json
definitions copy.json
Setting the
-Xmx
lower to 256m leads to the following stacktrace if of any help:edit: more information
The text was updated successfully, but these errors were encountered: