-
Notifications
You must be signed in to change notification settings - Fork 397
Status
This page mentions the status of the latest version -- ie, master.
The current stable version works fine (some bugs are still found and fixed), but the architecture itself is limitating. A rewrite is therefore in order.
In particular, id
is a nightmare to handle, and the current stable version does not really do what is dictated by the spec here. Also, reporting is limited, and you cannot do, say, syntax validation only.
All things the current rewrite aims to change.
The writeup below is still up to date for the stable version.
All validation aspects of draft v3 and (yet to be adopted) draft v4 are supported, apart from the limitations mentioned below. Supported features include:
- union types (in type as well as in disallow) (draft v3),
- full dependencies (ie, property dependencies as well as schema dependencies) (draft v3),
- "multiple extends" (ie, an array of schemas) (draft v3),
- tuple/non-tuple validation for arrays,
- $ref with loop detection,
- formats (however, see below),
- enums,
-
$schema
detection, - etc etc.
Even though Jackson has the ability to parse many malformed JSON documents, this project asks Jackson to obey the specification to the letter (which is the default behavior anyway):
- no comments are allowed;
- strings must be surrounded by double quotes, not single quotes;
- there is no type inference: "true" is a JSON String, not JSON boolean true; "42" is a string, but 42 is an integer; "null" is... You get the picture.
There is one element differing from the default Jackson behavior: it is asked to use BigDecimal to store decimal numbers instead of double. This is on purpose, see below.
The API supports extension to allow for any scheme to be registered. Natively, the only supported schemes are resource, http, file, ftp and jar (save for resource
, these are all the schemes natively sypported by Java's URL class; support for https has deliberately been omitted).
You can override builtin schemes as well.
This is for security reasons. It is perfectly possible to fetch content at, say, http://foo.bar/baz#
and obtain in return a schema which says:
{
"id": "http://other.site/schema.json"
}
In this kind of situation, the implementation, by default, ignores what id
says and takes for granted that the schema's URI is the URI the schema has been fetched from. If you want to trust id
nevertheless, you have to tell the implementation to trust it explicitly.
This can be viewed as a severe limitation, your mileage may vary. At this moment, the implementation caches a URI dereferencing result only once, and keeps the result cached permanently (unless you re-initialize a complete validator...).
This library contains all format attributes defined by draft v3 except for color and style.
In a schema, these enforce resp. the minimum/maximum length of a string instance, the minimum/maximum number of items of an array instance, and the minimum/maximum number of members in an object instance. This project is Java, as such the implementation won't accept any values for these which are greater than Integer.MAX_VALUE, that is 2^31 - 1. You don't have JSON documents that big, do you? Well, OK, some modern NoSQL databases may have JSON data as large, if not even larger.
(for some definition of "implicit")
Unknown keywords in schemas will be reported as warnings, not errors. The specification dictates that members which are not keywords be ignored, so beware of spelling mistakes!
This is an implementation choice. The draft does not say anything about what should happen in the event of a JSON Reference resolution failure: in this implementation, any reference resolution failure is considered a fatal error, and validation stops immediately (and fails).
This applies to integer and number JSON nodes, and therefore to the minimum, maximum and divisibleBy keywords. And especially to the latter.
The first thing to know is that the JSON spec itself does not specify a limit on the precision or scale of numeric instances, and neither does the JSON Schema draft (regardless of the fact that JavaScript limits itself to IEEE 745 floating point numbers -- JSON is not JavaScript).
For this reason, the implementation chooses to use Java's BigDecimal for numeric instance validation, and falls back to long if and only if both the schema keyword value and the instance value fit into this type. For decimal validation however, rounding has to be taken into account... And rounding means rounding errors, which means inaccuracies, which means wreaking havoc to the divisibleBy/multipleOf
keyword validations in particular. I don't like inaccuracy, so, for decimal numbers, BigDecimal
it is and it will likely remain so for the foreseeable future.
The draft is quite clear that regexes should conform to ECMA 262. This rules out java.util.regex entirely (for instance, possessive quantifiers, like in a++, are legal in Java, but are not supported by ECMA 262). The only Java library (that I know of) in existence which is able to process ECMA 262 regexes is Rhino and its Javascript engine. This project uses it for that very reason (and, again, I don't like inaccuracy).
Also, even though the draft only implies it, please note that a regex can match anywhere in the input. Remember this when writing your schemas -- if you want your regex to match the whole input, you must anchor it. This is valid for the pattern keyword, but also for keys in patternProperties. A JSON Schema implementation which doesn't act this way simply does not obey the draft!