Skip to content
Francis Galiegue edited this page Apr 29, 2014 · 83 revisions

Note

This page mentions the status of the latest version -- ie, master.

What is supported

All validation aspects of draft v4 and draft v3 are supported, apart from the limitations mentioned below.

This library also detects $schema and switches appropriately, has complete $ref support (including registering downloaders for arbitrary URI schemes and loop detection), allows to register new keywords/format attributes etc etc.

Limitations

Strict JSON input required by default

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.

Note that since 2.2.x you can add any options that the Jackson JsonParser will allow; so yes, you can have comments, use unquoted field names etc... But, well, don't do that.

URI dereferencing and id

Natively supported schemes

The API supports extension to allow for any scheme to be registered. Natively, the only supported schemes are resource, http, https, file, ftp and jar. Save for resource, these are all the schemes natively sypported by Java's URL class.

But this also means you have to do with URL's limitations. Fortunately, you can replace a scheme handler with your own.

id is not trusted by default

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.

URIs are fetched only once, or are not cached at all

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...).

You also have the option to fetch each and every time... There is no inbetween! Maybe in 3.x.

format

This library contains all format attributes defined by draft v3 except for color and style.

Limits on m{in,ax}Length, m{in,ax}Items and m{in,ax}Properties

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.

Discussions about some fine points of the draft

Unknown keywords in schemas

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!

Fortunately, you have full control over how reports are logged, so you can easily detect these.

Ref resolution failures are always fatal errors

This is an implementation choice. The JSON Reference draft says that reference resolution should fail to complete, and this implementation throws an exception in such a situation.

Numeric instance validation

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 (RFC 7159) 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.

Regex support: ECMA 262, and the real definition of "matching"

The draft is quite clear that regexes should conform to ECMA 262. This rules out java.util.regex entirely (for instance, lookbehinds 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!