airframe icon indicating copy to clipboard operation
airframe copied to clipboard

rpc: java.lang.NoSuchMethodError in NettyResponseHandler (Scala 3)

Open xerial opened this issue 2 years ago • 0 comments

When updating RPC method parameters, recompilation of classes defining RxRouter.add[...Impl] is always required (e.g., via clean; compile). Otherwize, NoSuchMethodError can be thrown like this:

server[ERROR] java.lang.NoSuchMethodError: (RPC response type) (RPC Method name)
server[ERROR] 	at ----
server[ERROR] 	at wvlet.airframe.surface.StaticMethodParameter.get$$anonfun$1(Surfaces.scala:109)
server[ERROR] 	at scala.Option.map(Option.scala:242)
server[ERROR] 	at wvlet.airframe.surface.StaticMethodParameter.get(Surfaces.scala:109)
server[ERROR] 	at wvlet.airframe.codec.ParamListCodec.packAsMap$$anonfun$2(ObjectCodec.scala:85)
server[ERROR] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
server[ERROR] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
server[ERROR] 	at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:575)
server[ERROR] 	at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:573)
server[ERROR] 	at scala.collection.AbstractIterable.foreach(Iterable.scala:933)
server[ERROR] 	at scala.collection.IterableOps$WithFilter.foreach(Iterable.scala:903)
server[ERROR] 	at wvlet.airframe.codec.ParamListCodec.packAsMap(ObjectCodec.scala:89)
server[ERROR] 	at wvlet.airframe.codec.ObjectMapCodec.pack(ObjectCodec.scala:259)
server[ERROR] 	at wvlet.airframe.codec.ObjectMapCodec.packAsMap(ObjectCodec.scala:261)
server[ERROR] 	at wvlet.airframe.codec.MessageCodec.toMsgPack(MessageCodec.scala:67)
server[ERROR] 	at wvlet.airframe.codec.MessageCodec.toMsgPack$(MessageCodec.scala:26)
server[ERROR] 	at wvlet.airframe.codec.ObjectMapCodec.toMsgPack(ObjectCodec.scala:251)
server[ERROR] 	at wvlet.airframe.http.netty.NettyResponseHandler.toHttpResponse(NettyResponseHandler.scala:43)
server[ERROR] 	at wvlet.airframe.http.netty.NettyResponseHandler.toHttpResponse(NettyResponseHandler.scala:27)

I guess this RxRouter code is always recompiled when Api changes:

object MyApi extends RxRouterProvider {
  override def router = RxRouter.of[MyApi]
}

But when binding the concrete implementation like this, recompilation will not be triggered:

RxRouter.of[MyApiImpl]

Probably instead of binding concrete API implementation in the router, it should have another way to provide the implementation.

xerial avatar Aug 04 '23 21:08 xerial