wkennedy / swagger4spring-web

Swagger support for Spring MVC
89 stars 46 forks source link

Class Cast #4

Closed Miamoto-Musashi closed 11 years ago

Miamoto-Musashi commented 11 years ago

Hi, I have this exception during model parsing:

my config is: <bean id="documentationController" class="com.knappsack.swagger4springweb.controller.ApiDocumentationController" p:basePath="http://localhost" p:baseControllerPackage="eu.cobiz.web.controller" p:baseModelPackage="eu.cobiz.web.domain" p:apiVersion="v1" />

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class at com.wordnik.swagger.core.ApiPropertiesReader$.getDataType(SpecReader.scala:84) at com.wordnik.swagger.core.ApiPropertiesReader$.getDataType(SpecReader.scala:74) 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.parseRecurrsive(SwaggerJsonSchemaProvider.scala:86) at com.wordnik.swagger.jsonschema.ApiModelParser.parse(SwaggerJsonSchemaProvider.scala:68) at com.knappsack.swagger4springweb.parser.DocumentationSchemaParser.getParameterDocumentationSchema(DocumentationSchemaParser.java:42) at com.knappsack.swagger4springweb.parser.ApiParserImpl.processMethods(ApiParserImpl.java:139) at com.knappsack.swagger4springweb.parser.ApiParserImpl.processControllers(ApiParserImpl.java:82) at com.knappsack.swagger4springweb.parser.ApiParserImpl.createDocuments(ApiParserImpl.java:66) at com.knappsack.swagger4springweb.controller.ApiDocumentationController.getDocs(ApiDocumentationController.java:117) at com.knappsack.swagger4springweb.controller.ApiDocumentationController.getResourceList(ApiDocumentationController.java:130) at com.knappsack.swagger4springweb.controller.ApiDocumentationController.getResources(ApiDocumentationController.java:32)

cbraun commented 11 years ago

Similar issue here with 0.1.4.

My exception:

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) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser.parsePropertyAnnotations(SwaggerJsonSchemaProvider.scala:150) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser.com$wordnik$swagger$jsonschema$ApiModelParser$$parseMethod(SwaggerJsonSchemaProvider.scala:96) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser$$anonfun$parseRecurrsive$1.apply(SwaggerJsonSchemaProvider.scala:79) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser$$anonfun$parseRecurrsive$1.apply(SwaggerJsonSchemaProvider.scala:77) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34) ~[scala-library-2.9.1.jar:na] at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:38) ~[scala-library-2.9.1.jar:na] at com.wordnik.swagger.jsonschema.ApiModelParser.parseRecurrsive(SwaggerJsonSchemaProvider.scala:77) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser.parseRecurrsive(SwaggerJsonSchemaProvider.scala:86) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.wordnik.swagger.jsonschema.ApiModelParser.parse(SwaggerJsonSchemaProvider.scala:68) ~[swagger-core_2.9.1-1.2.0.jar:1.2.0] at com.knappsack.swagger4springweb.parser.DocumentationSchemaParser.getResponseBodyDocumentationSchema(DocumentationSchemaParser.java:29) ~[swagger4spring-web-0.1.4.jar:na] at com.knappsack.swagger4springweb.parser.ApiParserImpl.processMethods(ApiParserImpl.java:133) ~[swagger4spring-web-0.1.4.jar:na] at com.knappsack.swagger4springweb.parser.ApiParserImpl.processControllers(ApiParserImpl.java:82) ~[swagger4spring-web-0.1.4.jar:na] at com.knappsack.swagger4springweb.parser.ApiParserImpl.createDocuments(ApiParserImpl.java:66) ~[swagger4spring-web-0.1.4.jar:na] at com.knappsack.swagger4springweb.controller.ApiDocumentationController.getDocs(ApiDocumentationController.java:117) ~[swagger4spring-web-0.1.4.jar:na] at com.knappsack.swagger4springweb.controller.ApiDocumentationController.getDocumentation(ApiDocumentationController.java:43) ~[swagger4spring-web-0.1.4.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_17] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_17] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_17] at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_17] at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) ~[spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) [servlet-api.jar:na] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [spring-webmvc-3.2.2.RELEASE.jar:3.2.2.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) [servlet-api.jar:na] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.34] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.34] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.1.3.RELEASE.jar:3.1.3.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) [spring-web-3.2.2.RELEASE.jar:3.2.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [catalina.jar:7.0.34] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.34] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [catalina.jar:7.0.34] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [catalina.jar:7.0.34] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [catalina.jar:7.0.34] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [catalina.jar:7.0.34] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [catalina.jar:7.0.34] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) [catalina.jar:7.0.34] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.34] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [catalina.jar:7.0.34] at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) [tomcat-coyote.jar:7.0.34] at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) [tomcat-coyote.jar:7.0.34] at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-coyote.jar:7.0.34] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_17] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_17] at java.lang.Thread.run(Thread.java:722) [na:1.7.0_17]

An example from one of my controllers... .... @Controller @RequestMapping(value = "/users") public class UserController {

 ....

/**
 * Retrieves all of the users from the system.
 * 
 * Also can be used to get the current user making the request or associated
 * with the session
 * 
 * @return list of all of the users in the system
 */
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<List<UserResponseDTO>> getUsers(@RequestParam(value = "current", required = false) boolean wantsCurrentUser) {
   .....
 return new ResponseEntity<List<UserResponseDTO>>(userList, HttpStatus.OK);
}
wkennedy commented 11 years ago

Hey guys, this most likely is an issue of type erasure and Java generics. It looks like there is an issue for it out in Swagger, see here:

https://github.com/wordnik/swagger-core/issues/145

According to that issue, it is fixed in Swagger 1.2.2. I did try using the 1.2.2-SNAPSHOT jar and it did seem to work, but I don't feel comfortable updating spring4swagger-web to use a snapshot. I will suggest this possible work around for you, though. In your project you can include the Swagger 1.2.2-SNAPSHOT and exclude the swagger dependencies from swagger4spring-web, like this:

   <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-annotations_2.9.1</artifactId>
        <version>1.2.2-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.wordnik</groupId>
        <artifactId>swagger-core_2.9.1</artifactId>
        <version>1.2.2-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jackson-core</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jackson-databind</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
            <exclusion>
                <artifactId>guava</artifactId>
                <groupId>com.google.guava</groupId>
            </exclusion>
            <exclusion>
                <artifactId>paranamer</artifactId>
                <groupId>com.thoughtworks.paranamer</groupId>
            </exclusion>
            <exclusion>
                <artifactId>slf4j-api</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>com.knappsack</groupId>
        <artifactId>swagger4spring-web</artifactId>
        <version>0.1.5</version>
        <exclusions>
            <exclusion>
                <artifactId>slf4j-log4j12</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
            <exclusion>
                <artifactId>junit</artifactId>
                <groupId>junit</groupId>
            </exclusion>
            <exclusion>
                <artifactId>slf4j-api</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
            <exclusion>
                <artifactId>swagger-annotations_2.9.1</artifactId>
                <groupId>com.wordnik</groupId>
            </exclusion>
            <exclusion>
                <artifactId>swagger-core_2.9.1</artifactId>
                <groupId>com.wordnik</groupId>
            </exclusion>
        </exclusions>
    </dependency>

Let me know if that works for you.

cbraun commented 11 years ago

Will, Thanks for the info!

Do you know what repository the snapshots are being hosted on? Or if you could just send along the latest Jars I can put them in my own repo just to test this.

Thanks!

Chris

On Sat, Mar 30, 2013 at 6:18 PM, Will Kennedy notifications@github.comwrote:

Hey guys, this most likely is an issue of type erasure and Java generics. It looks like there is an issue for it out in Swagger, see here:

wordnik/swagger-core#145https://github.com/wordnik/swagger-core/issues/145

According to that issue, it is fixed in Swagger 1.2.2. I did try using the 1.2.2-SNAPSHOT jar and it did seem to work, but I don't feel comfortable updating spring4swagger-web to use a snapshot. I will suggest this possible work around for you, though. In your project you can include the Swagger 1.2.2-SNAPSHOT and exclude the swagger dependencies from swagger4spring-web, like this:

com.wordnik swagger-annotations_2.9.1 1.2.2-SNAPSHOT
<dependency>
    <groupId>com.wordnik</groupId>
    <artifactId>swagger-core_2.9.1</artifactId>
    <version>1.2.2-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <artifactId>jackson-annotations</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jackson-core</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
        <exclusion>
            <artifactId>jackson-databind</artifactId>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
        <exclusion>
            <artifactId>guava</artifactId>
            <groupId>com.google.guava</groupId>
        </exclusion>
        <exclusion>
            <artifactId>paranamer</artifactId>
            <groupId>com.thoughtworks.paranamer</groupId>
        </exclusion>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.knappsack</groupId>
    <artifactId>swagger4spring-web</artifactId>
    <version>0.1.5</version>
    <exclusions>
        <exclusion>
            <artifactId>slf4j-log4j12</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
        <exclusion>
            <artifactId>junit</artifactId>
            <groupId>junit</groupId>
        </exclusion>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
        <exclusion>
            <artifactId>swagger-annotations_2.9.1</artifactId>
            <groupId>com.wordnik</groupId>
        </exclusion>
        <exclusion>
            <artifactId>swagger-core_2.9.1</artifactId>
            <groupId>com.wordnik</groupId>
        </exclusion>
    </exclusions>
</dependency>

Let me know if that works for you.

— Reply to this email directly or view it on GitHubhttps://github.com/wkennedy/swagger4spring-web/issues/4#issuecomment-15682934 .

wkennedy commented 11 years ago

In order to get the snapshots, I think you have to configure your Maven settings.xml file. Something like this:

 <profiles>
   <profile>
     <id>allow-snapshots</id>
       <activation><activeByDefault>true</activeByDefault></activation>
     <repositories>
      <repository>
          <id>snapshots-repo</id>
          <url>https://oss.sonatype.org/content/repositories/snapshots</url>
          <releases><enabled>false</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
       </repository>
     </repositories>
   </profile>
 </profiles>

I'd attach the jars somewhere, but I don't have a place readily available to host the files.

cbraun commented 11 years ago

Thanks Will. I got this to work given your snapshot repo info. I am now getting json coming back from /doc/collectionName and /doc/resourceList!

wkennedy commented 11 years ago

Nice, glad that worked for you!

wkennedy commented 11 years ago

I just release 0.1.6, which now includes Swagger 1.2.2, so now you don't need to do this work around to include Swagger 1.2.2 instead of 1.2.0.