title: How to serialize functions in Scala?
body: <p>I'm cutting my teeth on akka-persistence and came upon the quintessential problem of object serialization. My objects (shown below) have basic types, and functions. I read <a href="http://erikerlandson.github.io/blog/2015/03/31/hygienic-closures-for-scala-function-serialization/" rel="nofollow noreferrer">this</a>, <a href="http://www.lyh.me/lambda-serialization.html#.WjIDnVQ-d24" rel="nofollow noreferrer">this</a> and <a href="https://stackoverflow.com/questions/9770353/serialization-of-scala-functions">this</a>, but none has helped me in making the following serializable.</p>
  
  <p><strong>Test Util</strong></p>
  
  <pre><code>object SerializationUtil {
    def write(obj: Any): String = {
      val temp = Files.createTempFile(null, null).toFile
      val out = new ObjectOutputStream(new FileOutputStream(temp))
      out.writeObject(obj)
      out.close()
  
      temp.deleteOnExit()
      temp.getAbsolutePath
    }
  
    def read[T](file: String) = {
      val in = new ObjectInputStream(new FileInputStream(new File(file)))
      val obj = in.readObject().asInstanceOf[T]
      in.close()
      obj
    }
  }
  </code></pre>
  
  <p><strong>Stats</strong></p>
  
  <pre><code>case class Stats(
                    app: String,
                    unit: ChronoUnit,
                    private var _startupDurations: List[Long]
                  ) {
    def startupDurations = _startupDurations.sorted
  
    def startupDurations_=(durations: List[Long]) = _startupDurations = durations
  
    @transient lazy val summary: LongSummaryStatistics = {
      _startupDurations.asJava.stream()
        .collect(summarizingLong(identity[Long]))
    }
  }
  </code></pre>
  
  <p><code>Stats</code> serializes just fine.</p>
  
  <pre><code>"SerializationUtil" should "(de)serialize Stats" in {
    val file = SerializationUtil.write(newStats())
    val state = SerializationUtil.read[Stats](file)
  
    verifyStats(state)
  }
  </code></pre>
  
  <p>But this doesn't: <code>case class GetStatsForOneRequest(app: String, callback: Stats =&gt; Unit)</code></p>
  
  <pre><code>java.io.NotSerializableException: org.scalatest.Assertions$AssertionsHelper
      at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
  </code></pre>
  
  <p>Also tried:</p>
  
  <pre><code>trait SerializableRunnable[T] extends scala.Serializable with ((T) =&gt; Unit)
  </code></pre>
  
  <p>implementing the callback as an instance of <code>SerializableRunnable</code>, but no luck.</p>
  
  <p>Ideas?</p>
  
  <p><strong>Edit</strong>:</p>
  
  <p>Perhaps I should clarify the actual use case that is running into this issue to provide more context. The function is a callback from Akka HTTP <a href="https://raw.githubusercontent.com/asarkar/akka/master/k8s-watcher/src/main/scala/org/abhijitsarkar/akka/k8s/watcher/web/Routes.scala" rel="nofollow noreferrer">route</a> like the following:</p>
  
  <pre><code>path("stats") {
    logRequest("/stats") {
      completeWith(instanceOf[List[Stats]]) { callback =&gt;
        requestHandler ! GetStatsRequest(callback)
      }
    }
  }
  </code></pre>
  
  <p>The <a href="https://github.com/asarkar/akka/blob/master/k8s-watcher/src/main/scala/org/abhijitsarkar/akka/k8s/watcher/web/RequestHandlerActor.txt" rel="nofollow noreferrer">handler</a> actor persists the request until it gets a response. It may take more than one response to construct the final output.</p>
  
  <p>I did some digging and it appears that the callback implementation is a <a href="https://github.com/scala/scala/blob/07d61ecf134dbba143531f5a1bd3c1289c437296/src/library/scala/concurrent/impl/Promise.scala#L54" rel="nofollow noreferrer">CallbackRunnable</a>.</p>