title: AWS Lambda handler throws a ClassCastException with Scala generics
body: <p>I'm building an AWS lambda function with their <a href="https://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-pojo.html" rel="noreferrer">POJO handler</a>, but abstracting over the <code>RequestHandler</code> interface results in an erased type. When this happens AWS can't cast to the input type of my lambda function:</p>
  
  <pre><code>java.util.LinkedHashMap cannot be cast to com.amazonaws.services.lambda.runtime.events.SNSEvent: java.lang.ClassCastException
  java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.amazonaws.services.lambda.runtime.events.SNSEvent
  </code></pre>
  
  <p>The following code works when uploaded to AWS:</p>
  
  <pre><code>import com.amazonaws.services.lambda.runtime._
  import com.amazonaws.services.lambda.runtime.events.SNSEvent
  
  // Only working version
  class PojoTest1 extends Handler1[SNSEvent]{
    override def handleRequest(input: SNSEvent, context: Context): Unit =
      println(s"message: ${input.getRecords.get(0).getSNS.getMessage}")
  }
  
  trait Handler1[Event] extends RequestHandler[Event, Unit]{
    override def handleRequest(input: Event, context: Context): Unit
  }
  </code></pre>
  
  <p>Now because I'm using Scala I'm abstracting away the Java RequestHandler with generic traits. The following is a minified example of what doesn't work:</p>
  
  <pre><code>// Doesn't work
  class PojoTest2 extends Handler2[SNSEvent]{
    override def act(input: SNSEvent): Unit =
      println(s"message: ${input.getRecords.get(0).getSNS.getMessage}")
  }
  
  trait Handler2[Event] extends RequestHandler[Event, Unit]{
    def act(input: Event): Unit
    override def handleRequest(input: Event, context: Context): Unit = act(input)
  }
  </code></pre>
  
  <p>When I run <code>javap PojoTest1.class</code> this is the method that makes everything work:</p>
  
  <pre><code>public void handleRequest(com.amazonaws.services.lambda.runtime.events.SNSEvent, com.amazonaws.services.lambda.runtime.Context);
  </code></pre>
  
  <p>When I run <code>javap PojoTest2.class</code> You can see from this signature that the type of <code>SNSEvent</code> has been erased to <code>Object</code>:</p>
  
  <pre><code>public void handleRequest(java.lang.Object, com.amazonaws.services.lambda.runtime.Context);
  </code></pre>
  
  <p>This looks exactly like the issue described in <a href="https://issues.scala-lang.org/browse/SI-8905" rel="noreferrer">SI-8905</a>. Unfortunately the posted workaround doesn't seem to work either:</p>
  
  <pre><code>// Doesn't work
  abstract class Handler3[T] extends Handler2[T]
  
  class PojoTest3 extends Handler3[SNSEvent]{
    override def act(input: SNSEvent): Unit =
      println(s"message: ${input.getRecords.get(0).getSNS.getMessage}")
  }
  </code></pre>
  
  <p>Even extending an abstract class directly doesn't yield better results:</p>
  
  <pre><code>// Doesn't work
  class PojoTest4 extends Handler4[SNSEvent]{
    override def act(input: SNSEvent): Unit =
      println(s"message: ${input.getRecords.get(0).getSNS.getMessage}")
  }
  
  abstract class Handler4[Event] extends RequestHandler[Event, Unit] {
    def act(input: Event): Unit
    override def handleRequest(input: Event, context: Context): Unit = act(input)
  }
  </code></pre>
  
  <p>When I use <code>javap</code> on any of the classes that don't work I still get the same method signature with the erased type.</p>
  
  <p>I'm using Scala 2.12.7, sbt 1.1.2, and sbt-assembly 0.14.8.</p>
  
  <p>I'm looking for any sort of work around to deal with this.</p>