Giter Club home page Giter Club logo

json-schema's Introduction

JSON Schema Validator

Deprecation notice

This library is currently in maintenance mode and superseded by erosb/json-sKema.

This repository and won't see any new features. It provides solid support for draft-04, draft-06 and draft-07 versions of the JSON Schema specification.

The latest draft 2020-12 is supported only by erosb/json-sKema.

Apache 2.0 License Build Status Coverage Status

This project is an implementation of the JSON Schema Draft v4, Draft v6 and Draft v7 specifications. It uses the org.json API (created by Douglas Crockford) for representing JSON data.

When to use this library?

Lets assume that you already know what JSON Schema is, and you want to utilize it in a Java application to validate JSON data. But - as you may have already discovered - there is also an other Java implementation of the JSON Schema specification. So here are some advices about which one to use:

  • if you use Jackson to handle JSON in Java code, then java-json-tools/json-schema-validator is obviously a better choice, since it uses Jackson
  • if you want to use the org.json API then this library is the better choice
  • if you need JSON Schema Draft 6 / 7 support, then you need this library.
  • if you want to use anything else for handling JSON (like GSON or javax.json), then you are in a little trouble, since currently there is no schema validation library backed by these libraries. It means that you will have to parse the JSON twice: once for the schema validator, and once for your own processing. In a case like that, this library is probably still a better choice, since it seems to be twice faster than the Jackson-based java-json-tools library.

Maven installation

Add the following dependency to your pom.xml:

<dependency>
	<groupId>com.github.erosb</groupId>
	<artifactId>everit-json-schema</artifactId>
	<version>1.14.4</version>
</dependency>

Note about older versions: versions between 1.6.0 and 1.9.1 can only be found on JitPack with com.github.everit-org.json-schema:org.everit.json.schema coordinates. Versions 1.0.0 ... 1.5.1 are available on Maven Central under org.everit.json:org.everit.json.schema coordinates.

Java6/7 versions

There were a couple of attempts to make the library work on Java 6/7.

A java6 port of version 1.9.2 was developed by @mindbender1 and it is accessible through Maven Central with the following coordinates:

    <dependency>
        <groupId>com.github.erosb</groupId>
        <artifactId>everit-json-schema-jdk6</artifactId>
        <version>1.9.2</version>
    </dependency>

Backports of older versions:

  • version 1.4.1 was backported by Doctusoft with coordinates com.doctusoft:json-schema-java7:1.4.1
  • version 1.1.1 was backported by @rdruilhe and is available on JitPack as com.github.rdruilhe.json-schema:org.everit.json.schema:1.1.1

Quickstart

import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
// ...
try (InputStream inputStream = getClass().getResourceAsStream("/path/to/your/schema.json")) {
  JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
  Schema schema = SchemaLoader.load(rawSchema);
  schema.validate(new JSONObject("{\"hello\" : \"world\"}")); // throws a ValidationException if this object is invalid
}

Draft 4, Draft 6 or Draft 7?

JSON Schema has currently 4 major releases, Draft 3, Draft 4, Draft 6 and Draft 7. This library implements the 3 newer ones, you can have a quick look at the differences here and here. Since the two versions have a number of differences - and draft 6 is not backwards-compatible with draft 4 - it is good to know which version will you use.

The best way to denote the JSON Schema version you want to use is to include its meta-schema URL in the document root with the "$schema" key. This is a common notation, facilitated by the library to determine which version should be used.

Quick reference:

  • if there is "$schema": "http://json-schema.org/draft-04/schema" in the schema root, then Draft 4 will be used
  • if there is "$schema": "http://json-schema.org/draft-06/schema" in the schema root, then Draft 6 will be used
  • if there is "$schema": "http://json-schema.org/draft-07/schema" in the schema root, then Draft 7 will be used
  • if none of these is found then Draft 4 will be assumed as default

If you want to specify the meta-schema version explicitly then you can change the default from Draft 4 to Draft 6 / 7 by configuring the loader this way:

SchemaLoader loader = SchemaLoader.builder()
                .schemaJson(yourSchemaJSON)
                .draftV6Support() // or draftV7Support()
                .build();
Schema schema = loader.load().build();

Investigating failures

Starting from version 1.1.0 the validator collects every schema violations (instead of failing immediately on the first one). Each failure is denoted by a JSON pointer, pointing from the root of the document to the violating part. If more than one schema violations have been detected, then a ValidationException will be thrown at the most common parent elements of the violations, and each separate violations can be obtained using the ValidationException#getCausingExceptions() method.

To demonstrate the above concepts, lets see an example. Lets consider the following schema:

{
	"type" : "object",
	"properties" : {
		"rectangle" : {"$ref" : "#/definitions/Rectangle" }
	},
	"definitions" : {
		"size" : {
			"type" : "number",
			"minimum" : 0
		},
		"Rectangle" : {
			"type" : "object",
			"properties" : {
				"a" : {"$ref" : "#/definitions/size"},
				"b" : {"$ref" : "#/definitions/size"}
			}
		}
	}
}

The following JSON document has only one violation against the schema (since "a" cannot be negative):

{
	"rectangle" : {
		"a" : -5,
		"b" : 5
	}
}

In this case the thrown ValidationException will point to #/rectangle/a and it won't contain sub-exceptions:

try {
  schema.validate(rectangleSingleFailure);
} catch (ValidationException e) {
  // prints #/rectangle/a: -5.0 is not higher or equal to 0
  System.out.println(e.getMessage());
}

Now - to illustrate the way that multiple violations are handled - let's consider the following JSON document, where both the "a" and "b" properties violate the above schema:

{
	"rectangle" : {
		"a" : -5,
		"b" : "asd"
	}
}

In this case the thrown ValidationException will point to #/rectangle, and it has 2 sub-exceptions, pointing to #/rectangle/a and #/rectangle/b :

try {
  schema.validate(rectangleMultipleFailures);
} catch (ValidationException e) {
  System.out.println(e.getMessage());
  e.getCausingExceptions().stream()
      .map(ValidationException::getMessage)
      .forEach(System.out::println);
}

This will print the following output:

#/rectangle: 2 schema violations found
#/rectangle/a: -5.0 is not higher or equal to 0
#/rectangle/b: expected type: Number, found: String

JSON report of the failures

Since version 1.4.0 it is possible to print the ValidationException instances as JSON-formatted failure reports. The ValidationException#toJSON() method returns a JSONObject instance with the following keys:

  • "message": the programmer-friendly exception message (description of the validation failure)
  • "keyword": the JSON Schema keyword which was violated
  • "pointerToViolation": a JSON Pointer denoting the path from the input document root to its fragment which caused the validation failure
  • "schemaLocation": a JSON Pointer denoting the path from the schema JSON root to the violated keyword
  • "causingExceptions": a (possibly empty) array of sub-exceptions. Each sub-exception is represented as a JSON object, with the same structure as described in this listing. See more above about causing exceptions.

Please take into account that the complete failure report is a hierarchical tree structure: sub-causes of a cause can be obtained using #getCausingExceptions() .

ValidationListeners - Tracking the validation process

ValidationListeners can serve the purpose of resolving ambiguity about how does an instance JSON match (or does not match) against a schema. You can attach a ValidationListener implementation to the validator to receive event notifications about intermediate success/failure results.

Example:

import org.everit.json.schema.Validator;
...
Validator validator = Validator.builder()
	.withListener(new YourValidationListenerImplementation())
	.build();
validator.performValidation(schema, input);

The currently supported events:

  • a "$ref" reference being resolved
  • a subschema under an "allOf" / "anyOf" / "oneOf" schema matching
  • a subschema under an "allOf" / "anyOf" / "oneOf" schema failing to match
  • an "if" schema matching
  • an "if" schema failing to match
  • an "then" schema matching
  • an "then" schema failing to match
  • an "else" schema matching
  • an "else" schema failing to match

See the javadoc of the org.everit.json.schema.event.ValidationListener interface for more details. The particular event classes also have proper #toJSON() and #toString() implementations so you can print them in an easily parse-able format.

Early failure mode

By default the validation error reporting in collecting mode (see the "Investigating failures" chapter). That is convenient for having a detailed error report, but under some circumstances it is more appropriate to stop the validation when a failure is found without checking the rest of the JSON document. To toggle this fast-failing validation mode

  • you have to explicitly build a Validator instance for your schema instead of calling Schema#validate(input)
  • you have to call the failEarly() method of ValidatorBuilder

Example:

import org.everit.json.schema.Validator;
...
Validator validator = Validator.builder()
	.failEarly()
	.build();
validator.performValidation(schema, input);

Note: the Validator class is immutable and thread-safe, so you don't have to create a new one for each validation, it is enough to configure it only once.

Lenient mode

In some cases, when validating numbers or booleans, it makes sense to accept string values that are parseable as such primitives, because any successive processing will also automatically parse these literals into proper numeric and logical values. Also, non-string primitive values are trivial to convert to strings, so why not to permit any json primitives as strings?

For example, let's take this schema:

{
    "properties": {
        "booleanProp": {
            "type": "boolean"
        },
        "integerProp": {
            "type": "integer"
        },
        "nullProp": {
            "type": "null"
        },
        "numberProp": {
            "type": "number"
        },
        "stringProp": {
          "type": "string"
        }
    }
}

The following JSON document fails to validate, although all of the strings could easily be converted into appropriate values:

{
  "numberProp": "12.34",
  "integerProp": "12",
  "booleanProp": "true",
  "nullProp": "null",
  "stringProp": 12.34
}

In this case, if you want the above instance to pass the validation against the schema, you need to use the lenient primitive validation configuration turned on. Example:

import org.everit.json.schema.*;
...
Validator validator = Validator.builder()
	.primitiveValidationStrategry(PrimitiveValidationStrategy.LENIENT)
	.build();
validator.performValidation(schema, input);

Note: in lenient parsing mode, all 22 possible boolean literals will be accepted as logical values.

Default values

The JSON Schema specification defines the "default" keyword for denoting default values, though it doesn't explicitly state how it should affect the validation process. By default this library doesn't set the default values, but if you need this feature, you can turn it on by the SchemaLoaderBuilder#useDefaults(boolean) method, before loading the schema:

{
  "properties": {
    "prop": {
      "type": "number",
      "default": 1
    }
  }
}
JSONObject input = new JSONObject("{}");
System.out.println(input.get("prop")); // prints null
Schema schema = SchemaLoader.builder()
	.useDefaults(true)
	.schemaJson(rawSchema)
	.build()
	.load().build();
schema.validate(input);
System.out.println(input.get("prop")); // prints 1

If there are some properties missing from input which have "default" values in the schema, then they will be set by the validator during validation.

RegExp Implementations

For supporting the "regex" keyword of JSON Schema the library offers two possible implementations:

  • the default is based on the java.util.regex package
  • the other one is based on the RE2J library

While the RE2J library provides significantly better performance than java.util.regex, it is not completely compatible with the syntax supported by java.util or ECMA 262. So RE2J is recommended if you are concerned about performance and its limitations are acceptable.

The RE2J implementation can be activated with the SchemaLoaderBuilder#regexpFactory() call:

SchemaLoader loader = SchemaLoader.builder()
    .regexpFactory(new RE2JRegexpFactory())
    // ...
    .build();

Notes:

  • if you don't need the RE2J implementation, it is recommended to exclude it in your pom.xml so it doesn't increase your artifact's size unnecessarily
  • version history: in versions 1.0.0 ... 1.7.0 the java.util implementation was used, in 1.8.0 the RE2J implementation was used, and in 1.9.0 we made it configurable, due to some reported regressions.

readOnly and writeOnly context

The library supports the readOnly and writeOnly keywords which first appeared in Draft 7. If you want to utilize this feature, then before validation you need to tell the validator if the validation happens in read or write context. Example:

schema.json:

{
   "properties": {
     "id": {
       "type": "number",
       "readOnly": true
     }
   }  
}

Validation code snippet:

Validator validator = Validator.builder()
                .readWriteContext(ReadWriteContext.WRITE)
                .build();

validator.performValidation(schema, new JSONObject("{\"id\":42}"));

In this case we told the validator that the validation happens in WRITE context, and in the input JSON object the "id" property appears, which is marked as "readOnly" in the schema, therefore this call will throw a ValidationException.

Format validators

Starting from version 1.2.0 the library supports the "format" keyword (which is an optional part of the specification).

The supported formats vary depending on the schema spec version you use (since the standard formats were introduced in different versions on the validation specification).

Here is a compatibility table of the supported standard formats:

Draft 4 Draft 6 Draft 7
date-time
email
hostname
ipv4
ipv6
uri
uri-reference
uri-template
json-pointer
date
time
regex
relative-json-pointer

The library also supports adding custom format validators. To use a custom validator basically you have to

  • create your own validation in a class implementing the org.everit.json.schema.FormatValidator interface
  • bind your validator to a name in a org.everit.json.schema.loader.SchemaLoader.SchemaLoaderBuilder instance before loading the actual schema

Example

Lets assume the task is to create a custom validator which accepts strings with an even number of characters.

The custom FormatValidator will look something like this:

public class EvenCharNumValidator implements FormatValidator {

  @Override
  public Optional<String> validate(final String subject) {
    if (subject.length() % 2 == 0) {
      return Optional.empty();
    } else {
      return Optional.of(String.format("the length of string [%s] is odd", subject));
    }
  }

}

To bind the EvenCharNumValidator to a "format" value (for example "evenlength") you have to bind a validator instance to the keyword in the schema loader configuration:

JSONObject rawSchema = new JSONObject(new JSONTokener(inputStream));
SchemaLoader schemaLoader = SchemaLoader.builder()
	.schemaJson(rawSchema) // rawSchema is the JSON representation of the schema utilizing the "evenlength" non-standard format
	.addFormatValidator("evenlength", new EvenCharNumValidator()) // the EvenCharNumValidator gets bound to the "evenlength" keyword
	.build();
Schema schema = schemaLoader.load().build(); // the schema is created using the above created configuration
schema.validate(jsonDocument);  // the document validation happens here

$ref resolution

In a JSON Schema document it is possible to use relative URIs to refer previously defined types. Such references are expressed using the "$ref" and "$id" keywords. While the specification describes resolution scope alteration and dereferencing in detail, it doesn't explain the expected behavior when the first occurring "$ref" or "$id" is a relative URI.

In the case of this implementation it is possible to explicitly define an absolute URI serving as the base URI (resolution scope) using the appropriate builder method:

SchemaLoader schemaLoader = SchemaLoader.builder()
        .schemaJson(jsonSchema)
        .resolutionScope("http://example.org/") // setting the default resolution scope
        .build();

Loading from the classpath

As your schemas grow you will want to split that up into multiple source files and wire them with "$ref" references. If you want to store the schemas on the classpath (instead of eg. serving them through HTTP) then the recommended way is to use the classpath: protocol to make the schemas reference each other. To make the classpath: protocol work:

  • if you use the Spring framework you don't have to do anything, spring installs the necessary protocol handler out of the box
  • otherwise you can utilize the library's built-in classpath-aware SchemaClient, example:
SchemaLoader schemaLoader = SchemaLoader.builder()
        .schemaClient(SchemaClient.classPathAwareClient())
        .schemaJson(jsonSchema)
        .resolutionScope("classpath://my/schemas/directory/") // setting the default resolution scope
        .build();

Given this configuration, the following references will be properly resolved in jsonSchema:

{
    "properties": {
        "sameDir": { "$ref": "sameDirSchema.json" },
        "absPath": { "$ref": "classpath://somewhere/else/otherschema.json" },
        "httpPath": { "$ref": "http://example.org/http-works-as-usual" },
    }
}

and sameDirSchema.json will be looked for in /my/schemas/directory/sameDirSchema.json on the classpath.

Registering schemas by URI

Sometimes it is useful to work with preloaded schemas, to which we assign an arbitary URI (maybe an uuid) instead of loading the schema through a URL. This can be done by assigning the schemas to a URI with the #registerSchemaByURI() method of the schema loader. Example:

SchemaLoader schemaLoader = SchemaLoader.builder()
        .registerSchemaByURI(new URI("urn:uuid:a773c7a2-1a13-4f6a-a70d-694befe0ce63"), aJSONObject)
        .registerSchemaByURI(new URI("http://example.org"), otherJSONObject)
        .schemaJson(jsonSchema)
        .resolutionScope("classpath://my/schemas/directory/")
        .build();

Notes:

  • the passed schema object must be a JSONObject or a Boolean (the formal parameter type is Object only because these two don't have any other common superclass).
  • if you want, you can pass a URL with HTTP protocol, it is still a valid URI. Since in this case you pre-assigned a schema to a URI, there will be no network call made. This can be a caching strategy (though defining your own SchemaClient implementation works too, or you can even utilize the extensible protocol handling of the java.net package)

Excluding dependencies

Some of the dependencies can be excluded from the library, and it still remains usable, with some limitations:

  • if you exclude the com.damnhandy:handy-uri-templates dependency, then your schema shouldn't use the "uri-template" format
  • if you exclude the commons-validator:commons-validator dependency, then your schema shouldn't use the following formats: "email", "ipv4", "ipv6", "hostname"

Javadoc

By library version:

The generated javadoc of versions 1.0.0 - 1.5.1 is available at javadoc.io

For the versions in between (1.6.0 - 1.9.1) it isn't published anywhere.

json-schema's People

Contributors

adyach avatar afranzi avatar agebhar1 avatar andrejserafim avatar asherbar avatar balazs-zsoldos avatar blacktooth avatar dab-libs avatar dependabot[bot] avatar erosb avatar expeaneparaczki avatar gstoupis avatar halvorgb avatar hwcy avatar lmontrieux avatar markatwood avatar mtokumaru avatar pertyjons avatar rjruizes avatar rkeytacked avatar rodrigosaito avatar rugvedb avatar slinkydeveloper avatar snazarenko67 avatar srfarley avatar tledkov avatar tylersouthwick avatar vierbergenlars avatar zgyorffi avatar zsigmond-czine-everit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-schema's Issues

Include line and column info in a validation error

I would like to be able to locate the component from a JSON instance document that is invalid according to the schema rules.
I think this can be achieved if the validation error would contain the start line and column (or offset) of the invalid component from the instance document. It would be great if it is possible to also include the end line and column in order to fully locate the component.

Unhelpful error message: a JSON pointer should start with '/' or '#/'

I'm trying to test out this project but after loading my schema I got following exception:

An exception or error caused a run to abort: a JSON pointer should start with '/' or '#/' 
java.lang.IllegalArgumentException: a JSON pointer should start with '/' or '#/'
    at org.json.JSONPointer.<init>(JSONPointer.java:155)
    at org.everit.json.schema.loader.internal.JSONPointer.queryFrom(JSONPointer.java:183)
    at org.everit.json.schema.loader.internal.JSONPointer.query(JSONPointer.java:171)
    at org.everit.json.schema.loader.SchemaLoader.lookupReference(SchemaLoader.java:578)
    at org.everit.json.schema.loader.SchemaLoader.buildSchemaWithoutExplicitType(SchemaLoader.java:435)
    at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:517)
    at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:530)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
    at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110)
    at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at org.everit.json.schema.loader.SchemaLoader.tryCombinedSchema(SchemaLoader.java:640)
    at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:514)
    at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:223)
    at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:206)

(I think the actual contents of the schema is unimportant)

This is unhelpful for me because the message should include information where the problem is happening so I could fix it without manually looking at the schema

java7 version enum issue

Not sure if I should leave this issue here or somewhere else because it has to do with the java 7 version.

I have a schema entry that looks like this:
"taxRate": { "type": "integer", "required": true, "enum": [ 0, 16 ] },

When I attempt to use it to validate json I get the following:
java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator;

at org.everit.json.schema.loader.SchemaLoader.buildEnumSchema(SchemaLoader.java:241)
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:312)
at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:397)
at org.everit.json.schema.loader.ObjectSchemaLoader$7.accept(ObjectSchemaLoader.java:109)
at org.everit.json.schema.loader.ObjectSchemaLoader$7.accept(ObjectSchemaLoader.java:106)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl$1.accept(TypeBasedMultiplexer.java:86)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl$1.accept(TypeBasedMultiplexer.java:74)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:251)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:261)
at org.everit.json.schema.loader.ObjectSchemaLoader.addPropertySchemaDefinition(ObjectSchemaLoader.java:112)
at org.everit.json.schema.loader.ObjectSchemaLoader.populatePropertySchemas(ObjectSchemaLoader.java:98)
at org.everit.json.schema.loader.ObjectSchemaLoader.access$000(ObjectSchemaLoader.java:13)
at org.everit.json.schema.loader.ObjectSchemaLoader$3.accept(ObjectSchemaLoader.java:44)
at org.everit.json.schema.loader.ObjectSchemaLoader$3.accept(ObjectSchemaLoader.java:40)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl$1.accept(TypeBasedMultiplexer.java:86)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl$1.accept(TypeBasedMultiplexer.java:74)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:251)
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:261)
at org.everit.json.schema.loader.ObjectSchemaLoader.load(ObjectSchemaLoader.java:46)
at org.everit.json.schema.loader.SchemaLoader.buildObjectSchema(SchemaLoader.java:369)
at org.everit.json.schema.loader.SchemaLoader.loadForExplicitType(SchemaLoader.java:362)
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:380)
at org.everit.json.schema.loader.SchemaLoader$6.get(SchemaLoader.java:321)
at com.google.common.base.Absent.or(Absent.java:65)
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:315)
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:182)
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:167)

It appears to be in this method:
private EnumSchema.Builder buildEnumSchema() { JSONArray arr = ls.schemaJson.getJSONArray("enum"); Set<Object> possibleValues = Sets.newHashSet(arr.iterator()); return EnumSchema.builder().possibleValues(possibleValues); }

This is my gradle entry:
compile(group: "com.doctusoft", name: "json-schema-java7", version: "1.4.1")

Creative Commons License found in test file issue25/subject-valid.json

My company uses your very good validation library (currently at level 1.3.0) in our product, and upon attempting to upgrade our version to the latest.. our lawyers detected that one of your test files (https://github.com/everit-org/json-schema/tree/master/tests/src/test/resources/org/everit/json/schema/issues/issue25/subject-valid.json) has a Creative Commons License (https://creativecommons.org/licenses/by-sa/3.0) attributed to it.

This license has been deemed problematic by our lawyers due to the 'Sharealike' clauses in the license.

Is it possible for you to delete this test file ?

NOTE: From what I have been told, it would appear that your actually violating the Creative Commons License by having this file in your repository and not formally recognizing the license (but you should defer to your lawyers advice on this topic given I'm personally not an expert in this area).

Patterns do not work as expected.

Anchored regexes do not work as I would expect:
the (very simple) pattern "^.+@.+$" does not correctly validate strings missing @.

examples of strings that should fail to be matched by this pattern, but do not:
"", "@", "@@", "bear"

validator giving false results for the following schema and json

The validator is not throwing schema violations(which it should) while validating the schema for the data i am trying to validate.

Schema Sample:

{
      "required": [
        "arrayOfObjs",
        "anotherArrayOfObjs"
      ],
      "properties": {
        "arrayOfObjs": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "StringArrayObj": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "enum": [
                    "testString"
                  ]
                }
              },
              "numObj": {
                "type": "number",
                "maximum": -1
              }
            }
          }
        },
        "anotherArrayOfObjs": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "StringArrayObj": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "type": "string",
                  "enum": [
                    "testString"
                  ]
                },
                "numObj": {
                  "type": "number",
                  "maximum": -1
                }
              }
            }
          }
        }
      }
    }

SAMPLE JSON:

{
	
	"arrayOfObjs": [
		{
			"numObj": 3,
			"StringArrayObj": [
				"NotATestString"
			]
		},
		{
			"numObj": 8,
			"StringArrayObj": [
				"NotATestString1",
				"NotATestString2",
				"NotATestString3"
			]
		},
		{
			"numObj": 4,
			"numObj2": 43,
			"StringArrayObj": [
				"NotATestString5",
				"NotATestString6"
			]
		}
	],
	"anotherArrayOfObjs": []
}

Tested the above schema and input sample data on http://www.jsonschemavalidator.net and am getting validation errors as expected.

Thanks in advance.

Relative paths for JSON references are not supported

given a root schema and a subschema in a different file:

parent.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"child": { "$ref": "child.json"}
}
}

child.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "child.json",
"type": "object",
"properties": {
"foo": {"type": "string"},
"bar": {"type": "string"}
}
}

I would expect to be able to reference child.json as relative to the location of the root schema. Currently I would have to provide an absolute URI for the root schema id (i.e "id": "http://localhost:/myschemas/parent.json") and deploy that to a web container.

Validator for Java 6

Hello,

I'd like to use this json schema validator library for a personal project using an old version of OSGi (which runs on Java 6). I am not familiar with the Function/Consumer classes from Java 8. Could you give me a clue to replace this Function/Consumer pattern to be compliant with Java 6.

Thanks.

Is it possible to have all errors reported in one step?

The validator reports only the first error it encounters and stops. It would be useful to report all the errors.

For the JSON instance and JSON Schema samples below, I would expect to get both errors without having to fix one error and then validate again in order to get the second error:
expected type: String, found: Integer
extraneous key [otherProp] is not permitted

Schema:

{
  "properties" : {
    "prop" : {
      "type" : "string"
    }
  },
  "additionalProperties":false
}

Instance:

{
  "prop": 4,
  "otherProp": 5
}

Release request

Please do a new release including the updates to the datetime regex made in November. Thank you.

"required key not found" for simple example

I cannot get the library to work with a very simple example. I am happy to create a PR but this cannot possibly be a bug?

schema:

{
  "type":"object",
  "$schema": "http://json-schema.org/draft-04/schema",
  "required": ["one"],
  "properties":{
    "one": {
      "type":"string",
      "id": "http://example.com/one"
    }
  }
}

input:

{"one":"1"}

but I think it could just be that I'm not using the library properly?

Here is the error:

{
  "pointerToViolation": "#",
  "causingExceptions": [],
  "keyword": "required",
  "message": "required key [one] not found"
}

I've tried this on http://www.jsonschemavalidator.net/ and it appears to be valid.

Fetching $refs also when type is explicitly defined

Currently SchemaLoader does not resolve "$ref" references if the same schema object also has a "type" key. Example:

{
   "type" : "object",
   "$ref" : "#/definitions/Stuff"
}

This reference should be resolved, but it isn't.

JSON representation for validation failures

ValidationException instances should be able to provide a JSON description about themselves.

A ValidationException#toJSON() method should be implemented which returns a JSONObject. The object should minimally contain the following keys:

  • "message" : (string) the exception message
  • "causingExceptions" : (array) the array of JSON descriptions of causing exceptions
  • "pointerToViolation": (string) a JSON Pointer denoting the invalid fragment of the document

i18n support

Would be nice if this library supported internationalization for the exception messages.

version 1.4?

The readme references JSON report for failures that was added in 1.4. Is this an upcoming release? the maven dependency and the git tag still show 1.3 as the latest

Validator thinks integers should be 32-bits? Need very large integers. Larger than Long should be handled as well

Schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "JSON Schema X3D V3.3",
    "description": "Experimental JSON Schema for X3D V3.3 ",
    "type": "object",
    "properties": {
        "PixelTexture": {
            "type": "object",
            "properties": {
                "@image": {
                    "type": "array",
                    "minItems": 3,
                    "items": [
                        {
                            "type": "integer",
                            "default": 0
                        },
                        {
                            "type": "integer",
                            "default": 0
                        },
                        {
                            "type": "integer",
                            "default": 0
                        }
                    ],
                    "additionalItems": {
                        "type": "integer"
                    }
                }
            }
        }
    }
}

JSON:

{ "PixelTexture":
{
"@image":[4278190335,4278190207, 45]
}
}

Errors produced (from my code:)

json-schema Validation error org.everit.json.schema.ValidationException: #/PixelTexture/@image/0: expected type: Integer, found: Long image.json
json-schema Validation error org.everit.json.schema.ValidationException: #/PixelTexture/@image/1: expected type: Integer, found: Long image.json

StackOverflowError on combined schemas

I have defined two schemas. One extends the other using allOf and $ref

When I try to validate a json document I get StackOverflowError exception.

I have done some debugging and even if I pass the child schema to the SchemaLoader.load() method, the SchemaClient seems loads child again via http. I think it should load parent instead.

Test document passed to validate:

{n:1, s: "test" }

parent schema

{
  "_$schema":"http://json-schema.org/draft-04/schema#"
  "id":"http://127.0.0.1:8080/test/_schemas/parent#",
  "type":"object",
  "properties":{ "n":{ "type":"number" } },
  "required":[ "n" ]
}

child schema

{
  "_$schema":"http://json-schema.org/draft-04/schema#",
  "id":"http://127.0.0.1:8080/test/_schemas/child#",
  "allOf":[ 
    { "_$ref":"parent" },
    {
      "_$schema":"http://json-schema.org/draft-04/schema#",
      "required":[ "s" ],
      "type":"object",
      "properties":{ "s":{ "type":"string" } }
    }
  ],
  "additionalProperties":false
}

Exception

java.lang.StackOverflowError: null
    at org.everit.json.schema.CombinedSchema.succeeds(CombinedSchema.java:155) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.CombinedSchema.lambda$validate$9(CombinedSchema.java:165) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.CombinedSchema$$Lambda$90/207956499.test(Unknown Source) ~[na:na]
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) ~[na:1.8.0]
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) ~[na:1.8.0]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) ~[na:1.8.0]
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0]
    at java.util.stream.LongPipeline.reduce(LongPipeline.java:438) ~[na:1.8.0]
    at java.util.stream.LongPipeline.sum(LongPipeline.java:396) ~[na:1.8.0]
    at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526) ~[na:1.8.0]
    at org.everit.json.schema.CombinedSchema.validate(CombinedSchema.java:166) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.ReferenceSchema.validate(ReferenceSchema.java:61) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.CombinedSchema.succeeds(CombinedSchema.java:155) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.CombinedSchema.lambda$validate$9(CombinedSchema.java:165) ~[org.everit.json.schema-1.1.0.jar:na]
    at org.everit.json.schema.CombinedSchema$$Lambda$90/207956499.test(Unknown Source) ~[na:na]
...

Problem with simple schema

I've created a simple schema that does NOT throw validation exception regardless of the values i validate against the schema. adding "required" properties doesn't change the outcome. i'm using v1.4.1.
the code to validate is as follows (note: this was hand type & not copied/pasted). If there is another forum to post "issues" or questions, please let me know.

try {
jsonFileStr = FileUtils.readFileToString(jsonFile);
jsonSchemaStr = FileUtils.readFileToString(jsonSchemaFile);

JSONObject rawSchema = new JSONObject(newJSONTokener(jsonSchemaStr);
Schema schema = SchemaLoader.load(rawSchema);
JSONObject inputFile = new JSONObject(jsonFileStr);
schema.validate(inputFile);
} catch (ValidationException e){
}
{ "rectangle" : {
"description" : "this is a rectangle",
"type" : "object",
"properties" : {
"a" : { "type" : "number", "minimum" : 0 },
"b" : { "type" : "number", "minimum" : 0 }
}
}
}

and a json file { "rectangle" : { "a": -5, "b": true } }

ObjectSchema.getAdditionalPropeties throws NPE on empty object

For example

  @Test
  public void validateMetaSchema() {

    JSONObject jsonSchema = new JSONObject(new JSONTokener(
        MetaSchemaTest.class
            .getResourceAsStream("/org/everit/json/schema/json-schema-draft-04.json")));

    JSONObject jsonSubject = new JSONObject("{\n" +
            "  \"type\": \"object\",\n" +
            "  \"properties\": {}\n" +
            "}");

    Schema schema = SchemaLoader.load(jsonSchema);
    schema.validate(jsonSubject);
  }

throws

java.lang.NullPointerException
    at java.util.Arrays.stream(Arrays.java:5004)
    at org.everit.json.schema.ObjectSchema.getAdditionalProperties(ObjectSchema.java:259)
    at org.everit.json.schema.ObjectSchema.testAdditionalProperties(ObjectSchema.java:251)
    at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:320)
    at org.everit.json.schema.ObjectSchema.testProperties(ObjectSchema.java:269)
    at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:318)
...

This is because JSONObject.getNames(subject) can return null. Do you mind if I raise a PR to fix?

minProperties constraint ignored when using definitions/references in JSON schema

I have a JSON schema that defines a type language_object with some properties and then uses that on one of the fields, along with a minProperties constraint.

However, when validating against this schema, submitting an empty object in said field does not raise a ValidationException. It appears that the minProperties constraint is ignored when it is placed alongside $ref

I have prepared a schema that defines my field once as name using references and once as nameEx with explicit properties. As far as I can tell these should be equivalent:

{
    "type":"object",
    "$schema":"http://json-schema.org/draft-04/schema#",
    "definitions":{
        "language_object":{
            "type":"object",
            "additionalProperties":false,
            "patternProperties":{
                "^[a-z]{2}$":{
                    "type":"string"
                }
            }
        }
    },
    "properties":{
        "name":{
            "$ref":"#/definitions/language_object",
            "minProperties":1
        },
        "nameEx":{
            "type":"object",
            "patternProperties":{
                "^[a-z]{2}$":{
                    "type":"string"
                }
            },
            "additionalProperties":false,
            "minProperties":1
        },
        "date":{
            "type":"string",
            "format":"date-time"
        }
    }
}

When I validate the following JSON

{
   "name":{},
    "nameEx":{}
}

I only get #/nameEx: minimum size: [1], found: [0], not both. Other situations, like this disallowed key/property work fine on both:

{
   "name":{"nbb":"bla"},
   "nameEx":{"nbb":"bla"}
}

Returns

#: 2 schema violations found
#/nameEx: extraneous key [nbb] is not permitted
#/name: extraneous key [nbb] is not permitted

Thank you for your patience!

allOf keyword resolve problem

Hi ,

I have json schema attached which includes "allOf" keyword and I am facing the following error for the attached request . Does the library support allOf keyword ?

org.everit.json.schema.ValidationException: #/CARDConfirmCashAdvanceWithInstallmentCompositionRequest/Body: #: only 0 subschema matches out of 2
at org.everit.json.schema.ValidationException.prepend(ValidationException.java:214)
at org.everit.json.schema.ValidationException.prepend(ValidationException.java:193)
at org.everit.json.schema.ObjectSchema.lambda$testProperties$7(ObjectSchema.java:322)
at java.util.Optional.map(Optional.java:215)
at org.everit.json.schema.ObjectSchema.testProperties(ObjectSchema.java:322)
at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:384)
at

request.txt
jsonschema.txt

Could implement full Java Spec date/time formats

Currently, if using the format keyword, you can specify 'date-time' which allows validation against ISO standards as per RFC 3339 section 5.6.

However, there are a range of keywords in that RFC (link here: https://www.ietf.org/rfc/rfc3339.txt) including "full-date". I currently have a use case where the full-date format would be useful - i.e. validate against something like "1990-04-23".

Would this be useful - or, more specifically would anyone object to a pull request adding the remainder of the date-time RFCs?

When you defined additionalProperties to false and have an empty object, NPE happens

In ObjectSchema.getAdditionalProperties if additionalProperties is defined to false we don't test that object is empty.

Exception in thread "main" java.lang.NullPointerException
at java.util.Arrays.stream(Arrays.java:5004)
at org.everit.json.schema.ObjectSchema.getAdditionalProperties(ObjectSchema.java:259)
at org.everit.json.schema.ObjectSchema.testAdditionalProperties(ObjectSchema.java:247)
at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:320)
at org.everit.json.schema.ObjectSchema.testProperties(ObjectSchema.java:269)
at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:318)

Json schema allowing String parameter type receive a string without the double quotation marks.

According to the official spec, a String should be between quotation marks (""). However, when I test against a string parameter without the quotation marks (eg: "key": MyValue instead of "key": "MyValue") it doesn't fail the validation. Also, it only passes the validation if there is a word in the value, but if I send "key": 1234 it will fail with the correct as expected.

Json String spec

There is any configuration to make it fail if the quotation marks are missing from a string value?

Schema validation

Hi

The schema below should catch an error in an object below.
But id does not :(

Map schemaMap = getSchemaMap();
JSONObject rawSchema = new JSONObject(schemaMap);
Schema schema = SchemaLoader.load(rawSchema);
schema.validate(....)

{
"type" : "object",
"id" : "urn:jsonschema:com:zzzzz:tests:commons:jsonschema:models:Person",
"properties" : {
"book" : {
"type" : "object",
"id" : "urn:jsonschema:com:zzzzz:tests:commons:jsonschema:models:PhoneBook",
"properties" : {
"numbers" : {
"type" : "array",
"items" : {
"type" : "object",
"id" : "urn:jsonschema:com:zzzzz:tests:commons:jsonschema:models:PhoneNumber",
"properties" : {
"number" : {
"type" : "string",
"pattern" : "+?\d+"
},
"type" : {
"type" : "string"
}
}
}
}
}
},
"phoneBooks" : {
"type" : "array",
"items" : {
"type" : "object",
"$ref" : "urn:jsonschema:com:zzzzz:tests:commons:jsonschema:models:PhoneBook"
}
}
}
}

{
"book" : {
"numbers" : [ {
"number" : "22222"
}, {
"number" : "11111"
} ]
},
"phoneBooks" : [ {
"numbers" : [ {
"number" : "22222"
}, {
"number" : "11111"
}, {
"number" : "aaaaa"
} ]
} ]
}

Relative $ref's against absolute id URL don't (always) work

One of the schemas at http://json-schema.org/example2.html ("The full entry schema") cannot be parsed by json-schema unless you remove the "id" property.
That's because relative references are resolved against the id obtaining an absolute URL (like http://json-schema.org/draft-04/schema#/definitions/diskDevice) and that is used to fetch references, however the id points to a non-existing resource (it is made up) and the fetch fails.
I think relative references starting with the "#" character should always be resolved against the current JSON object, regardless of its id.

Validator ignores custom format

When validating against this JSON schema
{
"$schema":"http://json-schema.org/draft-04/schema#",
"type":"object",
"properties": {
"id": {
"type": "string",
"maxLength": 10,
"minLength": 3,
"format": "evenlength"
}
},
"required": ["id"]
}
JSON Document is:
{
"id": "everitorg"
}

Try with your documentation example. But i got no response/error. Only string validation is working fine(success/error). But custom format "evenlength" is not working. why?

Unable to validate array property. [key type: expected type is one of JSONArray, String, found: JSONObject]

Code:

	try{
	 String jsonData =
			 getStringFromInputStream(stringToStream(getRequestBody(jsonObject)));
	 
	String url = "http://localhost:"+port+"/schema/";
	Schema schema = SchemaLoader.builder().resolutionScope(url)
			.schemaJson(new JSONObject(
					new JSONTokener(JsonRequestValidator.class.getResourceAsStream(jsonFileName))))
			.build().load().build();
	
	schema.validate(new JSONObject(jsonData));
	}catch(IOException | ValidationException  e ) {
		logger.info("Error - > "+e);
	}

Schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"GlobalData": {
"type": "object",
"properties": {
"ConnectionModes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"Name": {
"type": {
"enum": [
"Bridge",
"Implicit NAT",
"UPnP NAPT"
]
}
},
"Status": {
"type": {
"enum": [
"Enabled",
"Disabled"
]
}
}
}
}
}
}
}
},
"required": [
"GlobalData"
]
}
Json Data:
{
"GlobalData": {
"ConnectionModes": [
{
"Name": "Bridged",
"Status": "Enabled"
},
{
"Name": "UPnP",
"Status": "Disabled"
},
{
"Name": "Implicit NAT",
"Status": "Enabled"
}
]
}
}

org.everit.json.schema.SchemaException: key type: expected type is one of JSONArray, String, found: JSONObject
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:544) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:503) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:514) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$addPropertySchemaDefinition$5(SchemaLoader.java:316) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.addPropertySchemaDefinition(SchemaLoader.java:318) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$populatePropertySchemas$16(SchemaLoader.java:581) ~[org.everit.json.schema-1.4.1.jar:na]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_66]
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_66]
at org.everit.json.schema.loader.SchemaLoader.populatePropertySchemas(SchemaLoader.java:580) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$buildObjectSchema$9(SchemaLoader.java:385) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.buildObjectSchema(SchemaLoader.java:386) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForExplicitType(SchemaLoader.java:532) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:542) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:503) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:514) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$buildArraySchema$7(SchemaLoader.java:347) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.buildArraySchema(SchemaLoader.java:349) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForExplicitType(SchemaLoader.java:530) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:542) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:503) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:514) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$addPropertySchemaDefinition$5(SchemaLoader.java:316) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.addPropertySchemaDefinition(SchemaLoader.java:318) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$populatePropertySchemas$16(SchemaLoader.java:581) ~[org.everit.json.schema-1.4.1.jar:na]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_66]
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_66]
at org.everit.json.schema.loader.SchemaLoader.populatePropertySchemas(SchemaLoader.java:580) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$buildObjectSchema$9(SchemaLoader.java:385) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.buildObjectSchema(SchemaLoader.java:386) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForExplicitType(SchemaLoader.java:532) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:542) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:503) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadChild(SchemaLoader.java:514) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$addPropertySchemaDefinition$5(SchemaLoader.java:316) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.addPropertySchemaDefinition(SchemaLoader.java:318) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$populatePropertySchemas$16(SchemaLoader.java:581) ~[org.everit.json.schema-1.4.1.jar:na]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_66]
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_66]
at org.everit.json.schema.loader.SchemaLoader.populatePropertySchemas(SchemaLoader.java:580) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.lambda$buildObjectSchema$9(SchemaLoader.java:385) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer$IdModifyingTypeConsumerImpl.lambda$then$0(TypeBasedMultiplexer.java:76) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.orElse(TypeBasedMultiplexer.java:231) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.internal.TypeBasedMultiplexer.requireAny(TypeBasedMultiplexer.java:241) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.buildObjectSchema(SchemaLoader.java:386) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForExplicitType(SchemaLoader.java:532) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.loadForType(SchemaLoader.java:542) ~[org.everit.json.schema-1.4.1.jar:na]
at org.everit.json.schema.loader.SchemaLoader.load(SchemaLoader.java:503) ~[org.everit.json.schema-1.4.1.jar:na]

Expose formatValidator in StringSchema

I'm trying to use the latest version of your library for a purpose slightly different that that is intended for the library. I see that StringSchema doesnt have a getter for formatValidator. I assume, I can get the required property from its parent requiredProperties getter. However, I cant get access to its formats. Also, NotSchema, doesnt have a getter for the mustNotMatch Schema. It would be helpful to get access to it as well.

Java7 backport

Currently I can't use this library in older projects because it is written in Java 8.

I wrote a backport of this libraray in a fork (aliz-ai#1), which I'd like to merge back here. Could you create a branch for my pull request, review it and deploy the java7 versions to maven central?

Thread Safety

Thanks for an excellent and fast schema validator. One question, is it possible to call Schema.validate() concurrently so that we can validate two or more documents simultaneously?

This would be fantastic as we could then build the Schema once and reuse it and potentially parallelize validations.

Thanks again. Great work.

Peter

Optional attributes with null values

If I have an optional field, for exapmle of type string, to be valid a document can either have the string, have the field missing or have null instead of the string. Are my expectations incorrect?

Currently the null case errors with a ValidationException.

JSON Schema With AdditionalProperties=false

Hi all,

When we are trying to validate a JSON Body against a JSON Schema that has set the additionalProperties to false, we are founding that the Schema.validate() function just return the first parameter that it is not permitted. We can see that behavior in the org.everit.json.schema.ObjectSchema class at line 279. (Version 1.1.1)

We have seen that there is a commit (

.map(unneeded -> String.format("extraneous key [%s] is not permitted", unneeded))
) that resolves this behavior.

When will be this new version available to download from Maven repository?

Thanks in advance.

Json schema validation fails when date-time has single digit in seconds fraction

Currently if json schema has a field with date-time format and json has a value e.g. "2011-12-03T10:15:30.1Z", which I believe is a valid RFC-3339 format, then json fails validation againt schema.

I had a look at the implementation and it seems that we are only allowing two or three digits in seconds fraction, where as according to the spec (link https://tools.ietf.org/html/rfc3339#section-5.6) time-secfrac is "." 1*DIGIT, which could mean any number of digits as there is no limit specified.

Personally I think we should allow parsing of variable length seconds fraction, which has between 1 to 9 digits, supporting upto nano seconds. I believe Java has support upto nano seconds as well. I have got the PR tested and ready to be pushed. If you can provide me the relevant permission then I could push the PR and once your happy can be merged?

Validation fails for JSON arrays when errors exist across multiple contained objects

When using the JSON validation library with JSON arrays, I have found a problem in which some validation errors are not reported. If the input JSON array contains multiple JSON objects, and validation errors exist in each of these objects, then only one error is reported in the CausingExceptions list, and the others go unreported. For instance, given the following schema:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Product set",
    "type": "array",
    "items": {
        "title": "Product",
        "type": "object",
        "properties": {
            "id": {
                "description": "The unique identifier for a product",
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number",
                "minimum": 0,
                "exclusiveMinimum": true
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                },
                "minItems": 1,
                "uniqueItems": true
            },
            "dimensions": {
                "type": "object",
                "properties": {
                    "length": {"type": "number"},
                    "width": {"type": "number"},
                    "height": {"type": "number"}
                },
                "required": ["length", "width", "height"]
            },
            "warehouseLocation": {
                "description": "Coordinates of the warehouse with the product",
                "$ref": "http://json-schema.org/geo"
            }
        },
        "required": ["id", "name", "price"]
    }
}

And given the following input JSON array:

[
    {
        "id": 2,
        "name": ["An ice sculpture"],
        "price": 12.50,
        "tags": ["cold", "ice"],
        "dimensions": {
            "length": 7.0,
            "width": "12.0",
            "height": 9.5
        },
        "warehouseLocation": {
            "latitude": -78.75,
            "longitude": 20.4
        }
    },
    {
        "id": 3,
        "name": "A blue mouse",
        "dimensions": {
            "length": 3.1,
            "width": 1.0,
            "height": 1.0
        },
        "warehouseLocation": {
            "latitude": 54.4,
            "longitude": -32.7
        }
    }
]

The expected validation failures are:
#/0/name: expected type: String, found: JSONArray
#/1: required key [price] not found

However, the CausingExceptions provide this output:
#/0: 2 schema violations found
#/1: required key [price] not found

I will work on a testcase as suggested by your guidelines...
Thank you!

Problem using json-schema in Android

Thanks for writing this library, it looks neat and easy to use.

I have trouble however using the library on Android. I'm not sure if this is supposed to work at all, but when I add the following dependency to my build.gradle:

dependencies {
    // ...
    compile 'org.everit.json:org.everit.json.schema:1.0.1'
}

I get the following error when building:

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
    at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
    at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
    at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
    at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
    at com.android.dx.command.dexer.Main.processClass(Main.java:704)
    at com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)
    at com.android.dx.command.dexer.Main.access$300(Main.java:83)
    at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:602)
    at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:284)
    at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:166)
    at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
    at com.android.dx.command.dexer.Main.processOne(Main.java:632)
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)
    at com.android.dx.command.dexer.Main.run(Main.java:246)
    at com.android.dx.command.dexer.Main.main(Main.java:215)
    at com.android.dx.command.Main.main(Main.java:106)
...while parsing org/everit/json/schema/ArraySchema$Builder.class
1 error; aborting
Error:Execution failed for task ':preDexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/jdk1.7.0_79/bin/java'' finished with non-zero exit value 1

Any idea on how to solve this?

Incorrect error message for arrays

When an array has the "maxItems" set. The validation error message fails to display the maxItems value.

  try
  {
     String schemaString = "{\"type\": \"object\", \"properties\": {\"foo\": {\"type\": \"array\", \"maxItems\": 1, \"items\": {\"type\": \"string\"}}}}";
     Schema schema = SchemaLoader.load(new JSONObject(schemaString));
     schema.validate(new JSONObject("{\"foo\": [\"\", \"\"]}"));
  } catch (ValidationException e)
  {
     System.out.println(e.getMessage());
  }

The error message:

#/foo: expected maximum item count: null, found: 2

The "null" should be 1 in this example.

Validator ignores format:date-time

When validating against this JSON schema

{
    "type":"object",
    "$schema":"http://json-schema.org/draft-04/schema#",
        "date":{
            "type":"string",
            "format":"date-time"
        }
    }
}

sending any String as the date will do. I've read somewhere that support for format is optional, is this the case for this validator?

Only first element of an array is validated

I defined a schema that contains an array of objects. When validating a JSON file against that schema only the first element of an array is validated. If there is a missing property in the second element of that array, the validation does not complain.

Schema:

{
    "type": "object",
    "required":
    [ "addresses" ],

    "properties":
    {
        "addresses":
        {
            "type": "array",
            "items":
            [
                {
                    "type": "object",
                    "required": [ "name", "city" ],

                    "properties":
                    {
                        "name": { "type": "string" },

                        "city": { "type": "string" }
                    }
                }
            ]
        }
    }
}

File to validate (should fail but passes)

{
    "addresses":
    [
        {
            "name": "Peter",
            "city": "Berlin"
        },
        {
            "no_name_here": "Susi",
            "city": "Frankfurt"
        }

    ]
}

Validate if field exists in schema

Hi!
I would like to add new feature to validate if field exists in schema.

Schema schema = SchemaLoader.load(schemaAsJsonObject);
Assert.assertTrue(schema.hasField('rectangle.a'))

In first glance I think that I have to validate only propertySchemas recursievly and patternProperties.
Could you please point if there are some corner cases of this solution?

Json validator not working with array and type object

Hello,
I'm the user that is using the Java6 backport library re-compiled for Java7
http://stackoverflow.com/a/38345475/1013317

I found the problem and I cannot tell if the problem is related to the backport or it is even in the main library.

I have this schema

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "organizations": {
            "type": "array",
            "additionalProperties": false,
            "items": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "title": {
                        "type": "string"
                    },
                    "department": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

and this json

{
    "organizations": [
        {
            "name": "name",
            "title": "title",        
            "department": "department"
        }
    ]
}

and the code

try {
    // Read the schema into json
    JSONObject rawSchema = new JSONObject(new JSONTokener(schemaStream));

    // Load the schema
    Schema schema = SchemaLoader.load(rawSchema);

    // throws a ValidationException if this object is invalid
    schema.validate(json);
} catch (JSONException | ValidationException e) {
    throw new FailedOperationException(e);
}

I used different online tools to test the validation and they all give a pass for correct json

But with the library I get the following error:

Caused by: org.everit.json.schema.ValidationException: extraneous key [title] is not permitted
    at org.everit.json.schema.ObjectSchema.failure(ObjectSchema.java:210)
    at org.everit.json.schema.ObjectSchema.testAdditionalProperties(ObjectSchema.java:268)
    at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:379)
    at org.everit.json.schema.ArraySchema.testItems(ArraySchema.java:199)
    at org.everit.json.schema.ArraySchema.validate(ArraySchema.java:246)
    at org.everit.json.schema.ObjectSchema.testProperties(ObjectSchema.java:304)
    at org.everit.json.schema.ObjectSchema.validate(ObjectSchema.java:377)
    at it.noovle.ape.project.tools.json.schema.SchemaValidator.validate(SchemaValidator.java:37)
    ... 50 more

Considering that the online tools are correct I can consider my schema as correct, so I'm wondering if there is a problem with the library itself or only the java6 backport version.

Regards

Reference Resolver parentScrope cannot be null, but cannot be set

ReferenceResolver requires a parent scope even when the reference is local to the current schema. Following the call stack back, the "id" field of SchemaLoader is being used for the parent scope. That can only be set from the "id" field of the SchemaLoaderBuilder, which isn't publicly available. Ideally, id wouldn't need to be set if only using local references.

Test fails

Hi,

I am using this repo for json validation,
but the below test fails if I have required element in the schema definition.
Is there any other option available to validate the schema ?

Note: V1 and V2 are same

JSONObject jsonSchema = new JSONObject(new JSONTokener(
PeopleSchemaContractValidationTest.class
.getResourceAsStream("/json/schema/dob-updated_v1.json")));

JSONObject jsonSubject = new JSONObject(new JSONTokener(
PeopleSchemaContractValidationTest.class
.getResourceAsStream("/json/schema/dob-updated_v2.json")));

Schema schema = SchemaLoader.load(jsonSchema);
schema.validate(jsonSubject); - Fails

//Schema
{
"id": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"dateOfBirth": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"dateOfBirth"
]
}

Regards
CK

No causing exceptions

Hi,
I have an error "#: only 1 subschema matches out of 2" but it's not possible to know what exactly caused the error since the getCausingExceptions() returns an empty list.

org json vs google gson

I don't mean to cause controversy but what's the merit of using org.json rather than gson? The org.json license is not accepted within most corporations which prevents the use of otherwise great projects. See https://dzone.com/articles/jsonorg-license-literally-says. Is org.json significantly faster than gson? Is it more popular than gson? I don't mind submitting a pull request that would move it to gson, I don't think that would be a lot of work.

Support for JDK 1.7

Hello, I try to use your library, but I get the next exception:

Exception in thread "main" java.lang.UnsupportedClassVersionError: org/everit/json/schema/loader/SchemaLoader : Unsupported major.minor version 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

I saw in the manifest.mf you are using jdk 1.8.0_60, is it possible update the maven repository with a version compilated with JDK 1.7 ?

Thanks,
Emmerson.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.