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

Schema type generator #61

Closed
michalkijas opened this issue Mar 7, 2016 · 9 comments
Closed

Schema type generator #61

michalkijas opened this issue Mar 7, 2016 · 9 comments
Labels

Comments

@michalkijas
Copy link

There is a problem with parsing custom types and used them as input or output definition. When trying use such class

package test

import org.joda.time.DateTime

final case class TestInput(
  value: Either[Unit, String],
  property: Either[Unit, Option[String]],
  dateTime: Either[Unit, Option[DateTime]],
  test: Either[Unit, Option[Test2Input]]
)

final case class Test2Input(
  propertyValue: Either[Unit, String]
)

on some route

###
# parameters:
#   - name: payload
#     in: body
#     schema:
#       $ref: '#/definitions/com.ticketfly.promotersuite.test.TestInput'
###
PATCH           /test @test.testAction()

i got exception

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ScalaReflectionException: class test
.Test2Input] in JavaMirror with ReloadableClassLoader(v13){file:/C:/workspace/src/api/target/scala-2.11/classes/} of 
type class play.runsupport.DelegatedResourcesClassLoader with classpath [...] not found.]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.6.jar:2.4.6]
    at test.play.ErrorHandler.onServerError(ErrorHandler.scala:36) [classes/:na]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:151) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:148) [play-netty-server_2.11-2.4.6.jar:2.4.6]
Caused by: scala.ScalaReflectionException: class test.Test2Input] in JavaMirror with 
ReloadableClassLoader(v13){file:/C:/workspace/src/api/target/scala-2.11/classes/} of type class play.runsupport.DelegatedResourcesClassLoader with classpath [...] not found.
    at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:123) ~[scala-reflect-2.11.7.jar:na]
    at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:22) ~[scala-reflect-2.11.7.jar:na]
    at com.iheart.playSwagger.DefinitionGenerator.definition(DefinitionGenerator.scala:41) ~[play-swagger_2.11-0.2.0.jar:0.2.0]
    at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1(DefinitionGenerator.scala:52) ~[play-swagger_2.11-0.2.0.jar:0.2.0]
    at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1$1.apply(DefinitionGenerator.scala:60) ~[play-swagger_2.11-0.2.0.jar:0.2.0]

it's only apear when add field
test: Either[Unit, Option[Test2Input]]

currentyl using Play 2.4.6 and

  "com.iheart" %% "play-swagger" % "0.2.0",
  "org.webjars" % "swagger-ui" % "2.1.4"

propably there will be problem with parsing types in

com.iheart.playSwagger.SwaggerParameterMapper
@kailuowang
Copy link
Member

can you be more specific about the following paragraph?

it's only apear when add field
test: Either[Unit, Option[Test2Input]]

seems to me the same field you have on the class above.

@michalkijas
Copy link
Author

Yes they looks similar

  value: Either[Unit, String],
  property: Either[Unit, Option[String]],
  dateTime: Either[Unit, Option[DateTime]]

but behave different, probably because types used for field above are mapped into default JS types from standard packages
com/iheart/playSwagger/SwaggerParameterMapper.scala#L21

@kailuowang
Copy link
Member

I think this is a bug when type with binary type parameters (in your case Either) is involved. In particular
https://github.com/iheartradio/play-swagger/blob/master/src/main/scala/com/iheart/playSwagger/SwaggerParameterMapper.scala#L11-L12
doesn't handle such high order types properly.
It might take us some time to get to this bug, but any contribution would be highly appreciated.

@kailuowang kailuowang added the bug label Mar 11, 2016
@michalkijas
Copy link
Author

Yes it's extract wrong type name eg. class test.Test2Input]

@kailuowang
Copy link
Member

How do you encode a high kinded type with binary type parameter in Json? We can parse a value to an Either for sure, but I am not sure how to express it as a swagger schema (like property left and property right?). @joprice any ideas?

@knordstrom
Copy link

I have the same problem with a Map[String, Set[B]]:

  final case class PlotPoint(left: BigDecimal, right: BigDecimal)
  final case class ScatterPlot(data: Map[String, Set[PlotPoint]])

With exception

[info] - Swagger - swagger spec exposed *** FAILED ***
[info] scala.ScalaReflectionException: class io.timeli.sdk.MeasurementsSDK.PlotPoint] in JavaMirror with sun.misc.Launcher$AppClassLoader@573fd745 of type class sun.misc.Launcher$AppClassLoader with classpath [...] not found.
[info] at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:123)
[info] at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:22)
[info] at com.iheart.playSwagger.DefinitionGenerator.definition(DefinitionGenerator.scala:44)
[info] at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1(DefinitionGenerator.scala:57)
[info] at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1$1.apply(DefinitionGenerator.scala:65)
[info] at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1$1.apply(DefinitionGenerator.scala:64)
[info] at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:124)
[info] at scala.collection.immutable.List.foldLeft(List.scala:84)
[info] at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1(DefinitionGenerator.scala:64)
[info] at com.iheart.playSwagger.DefinitionGenerator$$anonfun$allDefinitions$1.apply(DefinitionGenerator.scala:71)
[info] ...

@kailuowang
Copy link
Member

as of now, play-swagger does not understand type with multiple type parameters. One option is to use custom type mapping https://github.com/iheartradio/play-swagger#how-to-override-type-mappings

@reinier-pv
Copy link

Can anyone involved in this discussion has figured out a way to define a working custom mapping override for this example:
final case class ScatterPlot(data: Map[String, PlotPoint])
?

@asdcdow
Copy link
Contributor

asdcdow commented Apr 28, 2018

For swagger v3, you can express Either in a straightforward manner using the oneOf descriminator

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

6 participants