Unable to use "$ref" with "$id" and "jar" protocol
See original GitHub issueI am trying to refer a separate json schema file using $ref
but getting Malformed url exception
without adding file://
before the file name. After adding file://
, the code expects BaseJsonSchema.json
in the current directory instead of data/src/main/resources
Schema File: data/src/main/resources/TwitterJsonSchema.json
{
"description" : "Twitter data",
"type":"object",
"allOf":[
{ "$ref":"BaseJsonSchema.json#/definitions/baseData" },
{
"properties": {
"followersCount": {"type":"number" },
}
}]
}
Schema File: data/src/main/resources/BaseJsonSchema.json
{
"title": "baseData",
"type":"object",
"definitions":{
"baseData": {
"type": "object",
"properties": {
"sourceUrl": {
"type": "string"
},
}
}
}
}
Code:
package com.data.commons.validator
class JsonValidator{
public static void main(String[] args) {
validateJsonSchema(args[0], args[1])
}
static void validateJsonSchema(String jsonSchemaFile, String json) {
JSONObject jsonObject = new JSONObject(json)
Schema schema = SchemaLoader.builder().schemaJson(new JSONObject(new JSONTokener(this.getClass().getResourceAsStream(jsonSchemaFile)))).build().load().build()
schema.validate(jsonObject)
}
}
Exception:
Exception in thread "main" java.io.UncheckedIOException: java.net.MalformedURLException: no protocol: BaseJsonSchema.json
at org.everit.json.schema.loader.internal.DefaultSchemaClient.get(DefaultSchemaClient.java:35)
at org.everit.json.schema.loader.internal.JSONPointer.executeWith(JSONPointer.java:87)
at org.everit.json.schema.loader.internal.JSONPointer.lambda$forURL$1(JSONPointer.java:141)
at org.everit.json.schema.loader.internal.JSONPointer.query(JSONPointer.java:162)
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$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at com.tracxn.data.commons.validator.JsonValidator.validateJsonSchema(JsonValidator.groovy:19)
at com.tracxn.data.commons.validator.JsonValidator.main(JsonValidator.groovy:11)
Caused by: java.net.MalformedURLException: no protocol: BaseJsonSchema.json
at java.net.URL.<init>(URL.java:593)
at java.net.URL.<init>(URL.java:490)
at java.net.URL.<init>(URL.java:439)
at org.everit.json.schema.loader.internal.DefaultSchemaClient.get(DefaultSchemaClient.java:33)
... 24 more
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
Eclipse error: indirectly referenced from required .class files?
It means: "A class that you use needs another class that is not on the classpath." You should make sure (as Harry Joy...
Read more >Amend JarURLConnection::getJarFile() to return JarFile ...
JDK-8132359 : Amend JarURLConnection::getJarFile() to return JarFile object reference for nonexistent JAR file entry URL. Type: Bug; Component: core-libs ...
Read more >How to call to a shared flow in Mule 4 | MuleSoft Help Center
jar ' file) demonstrates a flow in the main Mule application XML re-using a flow named 'echoFlow', which is defined within the external...
Read more >Spring Boot Gradle Plugin Reference Guide
The Spring Boot Gradle Plugin provides Spring Boot support in Gradle. It allows you to package executable jar or war archives, run Spring ......
Read more >Apache Tomcat 9 (9.0.70) - JNDI Datasource How-To
Failure of a web application to close these resources can result in ... Tomcat will only use *.jar files installed in $CATALINA_HOME/lib ....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Okay. Will try to debug this oddity later. Thanks for the pointer.
I am not using spring. I have worked the issue out by modifying the json schema file at runtime. My base $refs are limited to one or two files, I read the definitions from these files and inject in other schemas at runtime - a bit hackish, but works for my use case.
Thanks for your time and support @erosb 👍
I’m not sure what version of json schema are you trying to use, but
"id"
works only for draft-4 schemas (which is an old version), and the keyword changed to"$id"
in draft-6.Also, the value you set
"jar:file:data/target/data-1.0.0.jar!/TwitterJsonSchema.json"
is not a valid URL so it definitely won’t work.There are multiple ways to make progress on it:
SchemaClient
interface and wire it into theSchemaLoader
. This part will look something like this:Then in the
YourSchemaClient
you load the schema from whatever source you would like to. You will be given a String as parameter and should return the InputStream of the found json content.