bijection icon indicating copy to clipboard operation
bijection copied to clipboard

Inversion failure for TEnumCodec

Open declerambaul opened this issue 10 years ago • 1 comments

Scrooge generated ThriftEnum does extend the apache TEnum, e.g. https://github.com/twitter/scrooge/blob/master/scrooge-core/src/main/scala/com/twitter/scrooge/ThriftEnum.scala#L5

sealed trait EngagementType extends ThriftEnum with Serializable

But the com.twitter.bijection.thrift.TEnumCodec.toBinary[T <: TEnum] throws when used with scrooge TEnum.

Maybe the solution is to simply create a com.twitter.bijection.scrooge.ThriftEnumCodec, though it would be nice to catch this at compile time.

scala> import com.twitter.discover.summingbird.common.thriftscala.EngagementType
import com.twitter.discover.summingbird.common.thriftscala.EngagementType

scala> import EngagementType._
import EngagementType._

scala> val inj = com.twitter.bijection.thrift.TEnumCodec.toBinary[EngagementType]
inj: com.twitter.bijection.Injection[com.twitter.discover.summingbird.common.thriftscala.EngagementType,Array[Byte]] = com.twitter.bijection.Injection$$anon$1@12141052

scala> inj(Click)
res0: Array[Byte] = Array(0, 0, 0, 1)

scala> inj.invert(res0).get
java.lang.NoSuchMethodException: com.twitter.discover.summingbird.common.thriftscala.EngagementType.findByValue(int)
    at java.lang.Class.getMethod(Class.java:1622)
    at com.twitter.bijection.thrift.TEnumCodec.findByValue(ThriftCodecs.scala:117)
    at com.twitter.bijection.thrift.TEnumCodec$$anonfun$invert$3.apply(ThriftCodecs.scala:121)
    at com.twitter.bijection.thrift.TEnumCodec$$anonfun$invert$3.apply(ThriftCodecs.scala:121)
    at scala.collection.mutable.MapLike$class.getOrElseUpdate(MapLike.scala:176)
    at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:45)
    at com.twitter.bijection.thrift.TEnumCodec.invert(ThriftCodecs.scala:121)
    at com.twitter.bijection.thrift.TEnumCodec.invert(ThriftCodecs.scala:114)
    at com.twitter.bijection.Injection$$anon$1$$anonfun$invert$1.apply(Injection.scala:41)
    at com.twitter.bijection.Injection$$anon$1$$anonfun$invert$1.apply(Injection.scala:41)
    at scala.util.Success.flatMap(Try.scala:199)
    at com.twitter.bijection.Injection$$anon$1.invert(Injection.scala:41)
    at .<init>(<console>:14)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:722)

declerambaul avatar Mar 11 '14 22:03 declerambaul

So, the issue here is that when doing reflection on the TEnum, we can't see that the reflection will fail.

The right way to solve this is probably with a macro: the macro should look for the method at compile time so the error is seen (or actually, even better, we look for the correct method).

johnynek avatar Aug 29 '14 21:08 johnynek