Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI stalling when API returns a ResponseEntity<String> #50

Closed
agentgonzo opened this issue Mar 25, 2013 · 33 comments
Closed

UI stalling when API returns a ResponseEntity<String> #50

agentgonzo opened this issue Mar 25, 2013 · 33 comments
Labels

Comments

@agentgonzo
Copy link

I'm using 0.4.0 and springMVC running in jetty.

When I have my API definitions as returning a ResponseEntity object (or any derived class from HttpEntity, the UI will stall at "fetching resource : http://localhost:8085/api-docs/core/metrics?api_key=special-key"

If I make it return a String, or Object, then it will work fine. Strangely, the XML returned when accessing the data directly is exactly the same.

Good:
@RequestMapping(method = RequestMethod.GET, value="/v0.1/test", produces = CONTENT_TYPE)
@ApiOperation(value = "Register DNS service name", notes = "A Path representing the DNS name to register is pas")
@responsebody
public Object test() {
return null;
}

Bad:
@RequestMapping(method = RequestMethod.GET, value="/v0.1/test", produces = CONTENT_TYPE)
@ApiOperation(value = "Register DNS service name", notes = "A Path representing the DNS name to register is pas")
@responsebody
public ResponseEntity test() {
return null;
}

@dilipkrish
Copy link
Member

@agentgonzo This is a known issue! This is because there is a limitation with the schema generation to not be able to generate generic types very well.

The UI is not stalled, if you look closely it has a javascript error in the browser. One way to prevent "stalling" and working around the problem, is to add a configuration extension to ignore (ResponseEntity.class) and decorate your controller method with @apimodel(type=String.class). The configuration should look something like the example below

    <bean id="swaggerConfiguration" class="com.mangofactory.swagger.SwaggerConfiguration">
        <property name="basePath" value="http://localhost:8080/swagger-springmvc-test"/>
        <property name="extensions">
            <bean class="com.mangofactory.swagger.SwaggerConfigurationExtension" >
...
                <property name="ignorableParameterTypes">
                    <list>
                        <value type="java.lang.Class">org.springframework.http.ResponseEntity</value>
                    </list>
                </property>
                <property name="documentationTransformer" value="some class"/>
            </bean>
        </property>
...

    </bean>

There was a regression that has now been fixed. This should be available in the 0.4.1 release in the next couple of days.

@agentgonzo
Copy link
Author

OK, thanks for the info. I'll await the new release!

@agentgonzo
Copy link
Author

I've just tried out the above code again in 0.4.1. Where it was stalling before (javascript error), I now get a 500 error. If curling the URL directly at http://localhost:8080/api-docs/core/metrics?api_key=special-key I get the following stack trace:

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
at com.wordnik.swagger.core.ApiPropertiesReader$.getDataType(SpecReader.scala:91)
at com.wordnik.swagger.jsonschema.ApiModelParser.parsePropertyAnnotations(SwaggerJsonSchemaProvider.scala:150)
at com.wordnik.swagger.jsonschema.ApiModelParser.com$wordnik$swagger$jsonschema$ApiModelParser$$parseMethod(SwaggerJsonSchemaProvider.scala:96)
at com.wordnik.swagger.jsonschema.ApiModelParser$$anonfun$parseRecurrsive$1.apply(SwaggerJsonSchemaProvider.scala:79)
at com.wordnik.swagger.jsonschema.ApiModelParser$$anonfun$parseRecurrsive$1.apply(SwaggerJsonSchemaProvider.scala:77)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34)
at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:38)
at com.wordnik.swagger.jsonschema.ApiModelParser.parseRecurrsive(SwaggerJsonSchemaProvider.scala:77)
at com.wordnik.swagger.jsonschema.ApiModelParser.parseRecurrsive(SwaggerJsonSchemaProvider.scala:86)
at com.wordnik.swagger.jsonschema.ApiModelParser.parse(SwaggerJsonSchemaProvider.scala:68)
at com.wordnik.swagger.jsonschema.SwaggerJsonSchemaProvider.read(SwaggerJsonSchemaProvider.scala:26)
at com.mangofactory.swagger.Models$Fn$1.apply(Models.java:23)
at com.mangofactory.swagger.Models$Fn$1.apply(Models.java:19)
at com.google.common.collect.Maps$2.transformEntry(Maps.java:766)
...

@dilipkrish
Copy link
Member

@agentgonzo I believe thats a regression. We experimented with trying to use the wordnik schema provider and that seemed to not work out as you've found out! We're working on a rewrite of the schema generation for the next release, but in the mean time. I'll have another build out to revert the schema generation back to what it was (however sub-optimal).

@dilipkrish dilipkrish reopened this Apr 8, 2013
@dilipkrish
Copy link
Member

@agentgonzo This issue should be resolved now. Well its reverted to its earlier behavior. You might find that you get further along in the process only to get another error. Its not worth chasing that problem however since its being re-written anyways in the next release.

Do let me know how the 0.4.2 works out.

@agentgonzo
Copy link
Author

Thanks. I'll take a look at it today and get back to you then wait for the rewrite.

Thanks for the good work!

On 9 Apr 2013, at 00:14, Dilip Krishnan notifications@github.com wrote:

@agentgonzo This issue should be resolved now. Well its reverted to its earlier behavior. You might find that you get further along in the process only to get another error. Its not worth chasing that problem however since its being re-written anyways in the next release.

Do let me know how the 0.4.2 works out.


Reply to this email directly or view it on GitHub.

@agentgonzo
Copy link
Author

Yes, I can confirm that 0.4.2 has exactly the same behaviour as 0.4.0, namely:

public Object test() {...} works fine
public ResponseEntity() {...} results in UI not working and JS error in the web console of:
TypeError: obj is null @ http://petstore.swagger.wordnik.com/lib/swagger.js:361

@aliaksei-lithium
Copy link

Hi,
Can I ask in what status fixing this bug? I want(cause apimodel annotations work right) to use latest version(0.4.2). But we also need to use ResponseEntity in controller methods. But it doesn't work with the same error as @agentgonzo already said. So, in 0.3.4 it work great. I try to put c72fc7c commit on top of rel-0.3, but this commit also break ResponseEntity support. Maybe you can provide workaround? Or I can give some more information to reproduce? Sorry, now I can't help to fix it.

@dilipkrish
Copy link
Member

@Daigotsu This has been fixed and should be available in 0.5.0. Would you mind trying 0.5.0-SNAPSHOT to see if you have any issues?

@andrzejpa
Copy link

Looks that the problem still occur. After upgrading to the 0.5.0 StackOverflowError is thrown. Below you will find the stack trace which I hope will help you in finding the reason:

java.lang.StackOverflowError
at sun.reflect.generics.reflectiveObjects.TypeVariableImpl.(TypeVariableImpl.java:57)
at sun.reflect.generics.reflectiveObjects.TypeVariableImpl.make(TypeVariableImpl.java:90)
at sun.reflect.generics.factory.CoreReflectionFactory.makeTypeVariable(CoreReflectionFactory.java:94)
at sun.reflect.generics.visitor.Reifier.visitFormalTypeParameter(Reifier.java:83)
at sun.reflect.generics.tree.FormalTypeParameter.accept(FormalTypeParameter.java:54)
at sun.reflect.generics.repository.GenericDeclRepository.getTypeParameters(GenericDeclRepository.java:76)
at java.lang.reflect.Method.getTypeParameters(Method.java:203)
at sun.reflect.generics.scope.AbstractScope.lookup(AbstractScope.java:86)
at sun.reflect.generics.factory.CoreReflectionFactory.findTypeVariable(CoreReflectionFactory.java:110)
at sun.reflect.generics.visitor.Reifier.visitTypeVariableSignature(Reifier.java:165)
at sun.reflect.generics.tree.TypeVariableSignature.accept(TypeVariableSignature.java:43)
at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.visitor.Reifier.visitArrayTypeSignature(Reifier.java:159)
at sun.reflect.generics.tree.ArrayTypeSignature.accept(ArrayTypeSignature.java:42)
at sun.reflect.generics.repository.ConstructorRepository.getParameterTypes(ConstructorRepository.java:94)
at java.lang.reflect.Method.getGenericParameterTypes(Method.java:291)
at com.fasterxml.jackson.databind.introspect.AnnotatedMethod.getGenericParameterType(AnnotatedMethod.java:207)
at com.fasterxml.jackson.databind.introspect.AnnotatedWithParams.getParameter(AnnotatedWithParams.java:119)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:421)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(POJOPropertiesCollector.java:233)
at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:142)
at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:68)
at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:11)
at com.fasterxml.jackson.databind.SerializationConfig.introspect(SerializationConfig.java:490)
at com.mangofactory.swagger.models.Jackson2SchemaDescriptor.serializableFields(Jackson2SchemaDescriptor.java:45)
at com.mangofactory.swagger.models.SchemaProvider.getResolvedFields(SchemaProvider.java:113)
at com.mangofactory.swagger.models.ResolvedTypeMemberVisitor.schema(ResolvedTypeMemberVisitor.java:96)
at com.mangofactory.swagger.models.SchemaProvider.schema(SchemaProvider.java:75)
at com.mangofactory.swagger.models.ResolvedArrayMemberVisitor.schema(ResolvedArrayMemberVisitor.java:40)
at com.mangofactory.swagger.models.SchemaProvider.schema(SchemaProvider.java:69)
at com.mangofactory.swagger.models.ResolvedTypeMemberVisitor.schema(ResolvedTypeMemberVisitor.java:103)
at com.mangofactory.swagger.models.SchemaProvider.schema(SchemaProvider.java:75)
...

Unfortunately solving this issue is getting quite urgent to me so I would ask when the final fix will be provided (stable version). If you need any additional information, don't hesistate to ask.

@dilipkrish
Copy link
Member

@Daigotsu i just fixed another issue #69, most likely that will fix your problem. Would you mind retrying and reporting back? If everything goes as planned 0.5 will be released this weekend.

@andrzejpa
Copy link

@dilipkrish fix of #69 helped. Now works much better, thanks for that (no exception is thrown) but I've experienced other issue. After opening the main page I'm receiving: "fetching resource xxx-controller: http://localhost:8080/......" and nothing happend. But after pasting the url manually into the browser I'm receiving the json (I think correct) response.
It is possible that I've changed something in my configuration but i cannot imagine what. The last message from tomcat is:
013 10:04:05.370] DEBUG - Written [com.mangofactory.swagger.ControllerDocumentation@19bd7849] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@50d567fc]
[îr maj 2013 10:04:05.377] DEBUG - Null ModelAndView returned to DispatcherServlet with name 'spring': assuming HandlerAdapter completed request handling
[îr maj 2013 10:04:05.378] DEBUG - Successfully completed request

@dilipkrish
Copy link
Member

@Daigotsu Could you see if you're getting a javascript error in the browser? I know of an existing bug in the swagger ui that is fixed in the swagger-springmvc-example project. It doesnt seem like an issue with this library however

@agentgonzo
Copy link
Author

Previously I'd just been using the maven releases. As 0.5.0-SNAPSHOT hasn't
been released in maven, I downloaded it and try to compile it but get the
following error:

[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR]
/c:/WorkArea/swagger-springmvc/src/main/java/com/mangofactory/swagger/annotations/ApiModel.java:[13,41]
c:\WorkArea\swagger-springmvc\src\main\java\com\mangofactory\swagger\annotations\ApiModel.java:13:
incompatible types
found : com.mangofactory.swagger.annotations.ListType
required: com.mangofactory.swagger.annotations.ListType
[ERROR]
/c:/WorkArea/swagger-springmvc/src/main/java/com/mangofactory/swagger/annotations/ApiModel.java:[13,41]
c:\WorkArea\swagger-springmvc\src\main\java\com\mangofactory\swagger\annotations\ApiModel.java:13:
incompatible types
found : com.mangofactory.swagger.annotations.ListType
required: com.mangofactory.swagger.annotations.ListType

I don't know what to do about that error unfortunately given the 'found'
and 'required' ListTypes are the same!

If I can get a working version of 0.5.0 I can test to see whether I still
get the same problem, but don't have the time to try and figure out why
it's not compiling without a little help.

On 1 May 2013 14:41, Dilip Krishnan notifications@github.com wrote:

@Daigotsu https://github.com/daigotsu Could you see if you're getting a
javascript error in the browser? I know of an existing bug in the swagger
ui that is fixed in the swagger-springmvc-examplehttps://github.com/martypitt/swagger-springmvc-exampleproject. It doesnt seem like an issue with this library however


Reply to this email directly or view it on GitHubhttps://github.com//issues/50#issuecomment-17281765
.

@andrzejpa
Copy link

@Daigotsu I didn't get any javascript error (at least the console in my browser don't show any error). I will take a look on the example that you attached, maybe it will help me in finding the reason why it doesn't work.

@dilipkrish
Copy link
Member

@agentgonzo Its hard to figure out these problems as I have no idea what your set up is (IDE, Environment etc.). It seems to be building just fine from the repository. Are you using git to get the latest codebase or are you just downloading the zip file?

@dilipkrish
Copy link
Member

@Daigotsu Are you perhaps running into a stack overflow error on the browser? I think you need to wait a bit before the swagger ui throws an error. I know that swagger has a bug with generating models with recursive types. for e.g. A -- has a property of type --> B -- has a property of type (parent) --> A

@agentgonzo
Copy link
Author

I got the latest source from git. then just ran 'mvn package'. Tried this
on both windows and linux hosts, java 1.6.

On 2 May 2013 15:28, Dilip Krishnan notifications@github.com wrote:

@Daigotsu https://github.com/daigotsu Are you perhaps running into a
stack overflow error on the browser? I think you need to wait a bit before
the swagger ui throws an error. I know that swagger has a bug with
generating models with recursive types. for e.g. A -- has a property of
type --> B -- has a property of type (parent) --> A


Reply to this email directly or view it on GitHubhttps://github.com//issues/50#issuecomment-17341075
.

@dilipkrish
Copy link
Member

Try doing a mvn clean install

@agentgonzo
Copy link
Author

same error

On 2 May 2013 15:44, Dilip Krishnan notifications@github.com wrote:

Try doing a mvn clean install


Reply to this email directly or view it on GitHubhttps://github.com//issues/50#issuecomment-17342048
.

@agentgonzo
Copy link
Author

if you can release 0.5.0-SNAPSHOT into the maven repo I can check it with
that. No idea why I can't build it!

On 2 May 2013 15:45, Steve Arch steve@quorg.org wrote:

same error

On 2 May 2013 15:44, Dilip Krishnan notifications@github.com wrote:

Try doing a mvn clean install


Reply to this email directly or view it on GitHubhttps://github.com//issues/50#issuecomment-17342048
.

@aliaksei-lithium
Copy link

Sorry for late answer. Just mention answers.
Ok, today i will make build and answer. The main problem was, that ResponseEntity as method return object break model creation.
But after adding this:

<bean id="swaggerConfiguration" class="com.mangofactory.swagger.SwaggerConfiguration">
        <property name="basePath" value="/rest/"/>
        <property name="extensions">
            <bean class="com.mangofactory.swagger.SwaggerConfigurationExtension">
                <property name="ignorableParameterTypes">
                    <list>
                        <value type="java.lang.Class">org.springframework.http.ResponseEntity
                        </value>
                    </list>
                </property>
            </bean>
        </property>
 </bean>

Everything ok.

@andrzejpa
Copy link

@dilipkrish I've checked the javascript console again. I'm receiving the "Uncaught TypeError: Cannot call method 'toLowerCase' of undefined" that comes from swagger.js:362 ( this.isArray = this.dataType.toLowerCase() === 'array').

btw. The DocumentationController returns xml. Shouldn't the controller produce an application/json?

@aliaksei-lithium
Copy link

So, i try to start application with 0.5.0 version, but get an error on ui SwaggerOperations must have a nickname. According this updated api manual https://github.com/wordnik/swagger-core/wiki/API-Declaration#apis nickname field mandatory. But i can't find where i must specify this 'nickname'. Can u help me?

@andrzejpa
Copy link

@Daigotsu I think, you don't need to specify the nickname. I think that the nickname is just a name of the controller method responsible for handling the request

@andrzejpa
Copy link

@dilipkrish I think I found the reason why swagger-ui hangs on fetching the data. I have a private method in my controller that returns URL (java.net). It seems that the DocumentationController takes all methods (even if a method is private and is not annotated). In result URL class is included in the model ("models"). Furthermore URL class has a method getContent that returns ... Object and type information is not generated for that (but the property "content" is created in the output xml/json). In result, swagger-ui throws an error.

@aliaksei-lithium
Copy link

@andrzejpa Yeah i see it, but I doesn't make any changes. Controller public methods all under ApiOperation. I have never explicit set method name. Only response type.

@andrzejpa
Copy link

@dilipkrish I fixed it (I'm not able to commit the code). The type information in ObjectMemberVisitor was not set. The following lines added to the "schema" method solved my issue:
Class<?> returnType = member.getType();
String propertyType = returnType.getSimpleName().toLowerCase();
propertySchema.setType(propertyType);

In addition junit test (SimpleModelTest:schemaHasAnObjectProperty) needs to be updated as well to verify that the "object" type is returned.

@ghost
Copy link

ghost commented May 8, 2013

@agentgonzo Did you ever get the compilation issue you were having resolved? I am experiencing the same.

@dilipkrish
Copy link
Member

@beeler78 Seems like this stack overflow question might help with figuring out the problem. It works just fine on the mac, I'll check the windows vm and see if that works as well.

EDIT: I tested it on windows and it works just fine. Java version 1.6.0_34-b04

@agentgonzo
Copy link
Author

@beeler78 - no, I haven't managed to get it working. The workaround that I have in place at the moment is to just have the methods return Object rather than ResponseEntity<?> and am waiting on a release of 0.5.0 which I hope will fix it.

@ghost
Copy link

ghost commented May 8, 2013

@dilipkrish Thanks for the help. After downloading the most recent Java 6 update (45) it is now compiling successfully.

@datumgeek
Copy link

#50 (comment)
error in swagger-ui saying toLowerCase is not a function of undefined.
i had a similar error and believe it was fixed by not using any capital letters in the path variable
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants