Repository navigation
Problem with Model containing an Array property #14
Copy link
Copy link
Closed
Description
I came across this while testing my api resourses.json with the validator
./bin/validate.sh http://localhost/restler3.dev/raw/swagger/resources.json "arul" ./swagger-errors.html
is throwing the following exception when my Author model contains a property called books of type Array
api.path: /resources/authors.{format}
calling: http://localhost/restler3.dev/raw/swagger/resources/authors.json?api_key=arul
swagger version: 1.1
basePath: http://localhost/restler3.dev/raw/swagger
api version: 1
java.lang.NullPointerException
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractModels$4$$anonfun$apply$11.apply(CoreUtils.scala:138)
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractModels$4$$anonfun$apply$11.apply(CoreUtils.scala:135)
at scala.collection.Iterator$class.foreach(Iterator.scala:660)
at scala.collection.JavaConversions$JMapWrapperLike$$anon$2.foreach(JavaConversions.scala:781)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:73)
at scala.collection.JavaConversions$JMapWrapper.foreach(JavaConversions.scala:792)
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractModels$4.apply(CoreUtils.scala:135)
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractModels$4.apply(CoreUtils.scala:134)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
at scala.collection.mutable.HashMap$$anonfun$foreach$1.apply(HashMap.scala:93)
at scala.collection.mutable.HashMap$$anonfun$foreach$1.apply(HashMap.scala:93)
at scala.collection.Iterator$class.foreach(Iterator.scala:660)
at scala.collection.mutable.HashTable$$anon$1.foreach(HashTable.scala:157)
at scala.collection.mutable.HashTable$class.foreachEntry(HashTable.scala:190)
at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:43)
at scala.collection.mutable.HashMap.foreach(HashMap.scala:93)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:194)
at scala.collection.mutable.HashMap.map(HashMap.scala:43)
at com.wordnik.swagger.codegen.util.CoreUtils$.extractModels(CoreUtils.scala:134)
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractAllModels$1.apply(CoreUtils.scala:45)
at com.wordnik.swagger.codegen.util.CoreUtils$$anonfun$extractAllModels$1.apply(CoreUtils.scala:44)
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
at scala.collection.immutable.List.foreach(List.scala:45)
at com.wordnik.swagger.codegen.util.CoreUtils$.extractAllModels(CoreUtils.scala:44)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.validateResponseModels(SwaggerSpecValidator.scala:63)
at com.wordnik.swagger.codegen.spec.SwaggerSpecValidator.validate(SwaggerSpecValidator.scala:57)
at com.wordnik.swagger.codegen.spec.Validator$.main(Validator.scala:54)
at com.wordnik.swagger.codegen.spec.Validator.main(Validator.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Here is the /resources/authors.json for your reference
{
"apiVersion": "1",
"swaggerVersion": "1.1",
"basePath": "http://localhost/restler3.dev/raw/swagger",
"apis": [
{
"path": "/authors.{format}/{id}",
"description": "API to list, modify Authors of the Restler",
"operations": [
{
"httpMethod": "GET",
"nickname": "authorsid",
"responseClass": "Author",
"parameters": [
{
"name": "id",
"description": "Author ID . ",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"summary": "Get Author for the specified Author ID",
"notes": "Passing a valid author id, will result in getting details (name, email, author id) of the specific Author.",
"errorResponses": [
{
"reason": "one or more of required fields missing",
"code": 417
},
{
"reason": "Author not found",
"code": 404
}
]
}
]
},
{
"path": "/authors.{format}",
"description": "API to list, modify Authors of the Restler",
"operations": [
{
"httpMethod": "POST",
"nickname": "authors",
"responseClass": "Array",
"parameters": [
{
"name": "request_data",
"description": "",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"summary": "Create new Author",
"notes": "",
"errorResponses": [
{
"reason": "one or more of required fields missing",
"code": 417
}
]
}
]
},
{
"path": "/authors.{format}/{id}",
"description": "API to list, modify Authors of the Restler",
"operations": [
{
"httpMethod": "PUT",
"nickname": "authorsid",
"responseClass": "Array",
"parameters": [
{
"name": "id",
"description": "Author ID . ",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "request_data",
"description": "",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"summary": "Update Author information",
"notes": "",
"errorResponses": [
]
}
]
},
{
"path": "/authors.{format}/something/{id}",
"description": "API to list, modify Authors of the Restler",
"operations": [
{
"httpMethod": "DELETE",
"nickname": "authorssomethingid",
"responseClass": "Array",
"parameters": [
{
"name": "id",
"description": "Author ID . ",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"summary": "Delete Author by ID",
"notes": "",
"errorResponses": [
]
}
]
}
],
"resourcePath": "/authors",
"models": {
"Author": {
"id": "Author",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"age": {
"type": "int"
},
"books": {
"type": "Array"
}
}
}
}
}if I remove , "books":{ "type":"Array"} validator is fine
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
fehguy commentedon Aug 28, 2012
Looks lik your array doesn't specify the
typeof object in it. If made astring, you'll get a valid spec:Will fix the validation step so you get a proper error.
fehguy commentedon Aug 28, 2012
OK pushed a fix to do a null check on the item if it's an array. I found three other issues in your model, namely:
DELETEmethod must returnvoidPUTmethod must returnvoidPOSTmethod is returning anArray[Author]notArrayThe entire
authors.jsonfile is here:{ "apiVersion": "1", "swaggerVersion": "1.1", "basePath": "http://localhost/restler3.dev/raw/swagger", "apis": [ { "path": "/authors.{format}/{id}", "description": "API to list, modify Authors of the Restler", "operations": [ { "httpMethod": "GET", "nickname": "authorsid", "responseClass": "Author", "parameters": [ { "name": "id", "description": "Author ID . ", "paramType": "path", "required": true, "allowMultiple": false, "dataType": "string" } ], "summary": "Get Author for the specified Author ID", "notes": "Passing a valid author id, will result in getting details (name, email, author id) of the specific Author.", "errorResponses": [ { "reason": "one or more of required fields missing", "code": 417 }, { "reason": "Author not found", "code": 404 } ] } ] }, { "path": "/authors.{format}", "description": "API to list, modify Authors of the Restler", "operations": [ { "httpMethod": "POST", "nickname": "authors", "responseClass": "Array[Author]", "parameters": [ { "name": "request_data", "description": "", "paramType": "path", "required": true, "allowMultiple": false, "dataType": "string" } ], "summary": "Create new Author", "notes": "", "errorResponses": [ { "reason": "one or more of required fields missing", "code": 417 } ] } ] }, { "path": "/authors.{format}/{id}", "description": "API to list, modify Authors of the Restler", "operations": [ { "httpMethod": "PUT", "nickname": "authorsid", "responseClass": "void", "parameters": [ { "name": "id", "description": "Author ID . ", "paramType": "path", "required": true, "allowMultiple": false, "dataType": "string" }, { "name": "request_data", "description": "", "paramType": "path", "required": true, "allowMultiple": false, "dataType": "string" } ], "summary": "Update Author information", "notes": "", "errorResponses": [ ] } ] }, { "path": "/authors.{format}/something/{id}", "description": "API to list, modify Authors of the Restler", "operations": [ { "httpMethod": "DELETE", "nickname": "authorssomethingid", "responseClass": "void", "parameters": [ { "name": "id", "description": "Author ID . ", "paramType": "path", "required": true, "allowMultiple": false, "dataType": "string" } ], "summary": "Delete Author by ID", "notes": "", "errorResponses": [ ] } ] } ], "resourcePath": "/authors", "models": { "Author": { "id": "Author", "properties": { "name": { "type": "string" }, "email": { "type": "string" }, "age": { "type": "int" }, "books": { "items":{ "type":"string" }, "type": "Array" } } } } }Thanks!
fehguy commentedon Aug 29, 2012
sweet!
venkata-denali commentedon Jun 6, 2013
Hi, I have a problem with model schema. It is not able to display the type for embedded class. For suppose, In one response body class I have is user defined class and it has List like objects. In swagger model schema it presents it as Array[any]. Is there is way specify the exact type.
fehguy commentedon Jun 6, 2013
Can you share the class itself that you're trying to represent? What version of codegen? Is it java or scala code?
venkata-denali commentedon Jun 6, 2013
I am using code generation for java. This is my pojo class.
@XmlRootElement(name="SubscriptionDetails")
public class SubscriptionDetails implements Serializable{
}
The web service class is
@OverRide
@put
@path("/subscriptions")
@consumes({"application/json","application/xml"})
@produces({"application/json","application/xml"})
@apioperation(value = "Updates an existing subscription", notes = "Updates the subscription details")
@ApiErrors(value = { @ApiError(code = 400, reason = "Subscription details are required") })
public Response updateSubscription(@ApiParam(value = "SubscriptionDetails that needs to be fetched", required = true) SubscriptionDetails subscription) throws DataRequiredException{
//Code
}
venkata-denali commentedon Jun 6, 2013
This is model schema was generated by swagger ui
SubscriptionDetails
class SubscriptionDetails(alertTypeId: int, criteria: string, updatedDate: Date, emailIds: string, protocols: Array[any], alertType: string, subscriptionId: int, subscriptionCriterias: Array[any], mobileNos: string, active: boolean, alertTimings: TimingDetails, notificationPreferences: Array[any], subscriber: UserDetails, createdDate: Date, protocolTypes: string)
Please note Array[any] notation for list typed property.
fehguy commentedon Jun 6, 2013
Can you confirm you're using swagger 1.2.4?
venkata-denali commentedon Jun 6, 2013
The maven repository for latest swagger-core_2.9.1 is 1.2.3.
This my dependency set
com.wordnik swagger-core_2.9.1 1.2.3 com.wordnik swagger-jaxrs_2.9.1 1.2.3venkata-denali commentedon Jun 6, 2013
But 1.2.4 is not available
fehguy commentedon Jun 6, 2013
Hi, there are a number of models missing from your sample, and not all the class variables are there, so without reproducing all of it, it's impossible to test.
I just ensured 1.2.4 was pushed to maven central, so if you can try that again shortly, or try 1.2.4-SNAPSHOT (in sonatype oss snapshots) I'd like to see if the issue is fixed with some model recursion fixes from that version.
venkata-denali commentedon Jun 6, 2013
This is one of missing models. Please remove all the other models from pojo. And consider this only.
@XmlRootElement(name="SubscriptionCriteria")
public class SubscriptionCriteria {
}
Thanks , 1.2.4-SNAPSHOT is look like not available. I am getting jar not available error in pom. I will wait for 1.2.4 and will see if this issue is fixed. Thank you very much.