Search code examples
scalasbtakkaakka-stream

Can't assembly scala/akka project


I'm newby with sbt and scala. Just want to make jar file to run in on server, but when I try to compile jar file I get error. Program code is very simple, only one class (can't post it here, stackoverflow doesn't allow). When I run it in Intellij everything is fine. But sbt assembly fires this error:

[info] Merging files...
[error] scala.MatchError: akka\stream\OverflowStrategies$.class (of class java.lang.String)
[error]         at $a019333dc409d47a4d92$.$anonfun$$sbtdef$2(D:\workspace_scala\TestSbt2\build.sbt:25)
[error]         at sbtassembly.Assembly$.$anonfun$applyStrategies$6(Assembly.scala:115)
[error]         at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
[error]         at scala.collection.Iterator.foreach(Iterator.scala:929)
[error]         at scala.collection.Iterator.foreach$(Iterator.scala:929)
[error]         at scala.collection.AbstractIterator.foreach(Iterator.scala:1417)
[error]         at scala.collection.IterableLike.foreach(IterableLike.scala:71)
[error]         at scala.collection.IterableLike.foreach$(IterableLike.scala:70)
[error]         at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
[error]         at scala.collection.TraversableLike.map(TraversableLike.scala:234)
[error]         at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
[error]         at scala.collection.AbstractTraversable.map(Traversable.scala:104)
[error]         at sbtassembly.Assembly$.applyStrategies(Assembly.scala:114)
[error]         at sbtassembly.Assembly$.x$1$lzycompute$1(Assembly.scala:26)
[error]         at sbtassembly.Assembly$.x$1$1(Assembly.scala:24)
[error]         at sbtassembly.Assembly$.stratMapping$lzycompute$1(Assembly.scala:24)
[error]         at sbtassembly.Assembly$.stratMapping$1(Assembly.scala:24)
[error]         at sbtassembly.Assembly$.inputs$lzycompute$1(Assembly.scala:68)
[error]         at sbtassembly.Assembly$.inputs$1(Assembly.scala:58)
[error]         at sbtassembly.Assembly$.apply(Assembly.scala:85)
[error]         at sbtassembly.Assembly$.$anonfun$assemblyTask$1(Assembly.scala:249)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:66)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:271)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:36)
[error]         at java.util.concurrent.FutureTask.run(Unknown Source)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
[error]         at java.util.concurrent.FutureTask.run(Unknown Source)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
[error]         at java.lang.Thread.run(Unknown Source)
[error] (assembly) scala.MatchError: akka\stream\OverflowStrategies$.class (of class java.lang.String)
[error] Total time: 1 s, completed Jun 20, 2018 1:20:02 PM

built.sbt

name := "TestSbt2"
version := "0.1"
scalaVersion := "2.12.4"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.13"
libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.5.13"
libraryDependencies += "com.typesafe.akka" %% "akka-http" % "10.1.0"

assemblyMergeStrategy in assembly := {
  case PathList("reference.conf") => MergeStrategy.concat
}

project/assembly.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")

Program code:

import akka.actor._
import akka.http.scaladsl._
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.Directives._
import akka.stream._
import akka.stream.scaladsl._

import scala.io.StdIn

object Server2 {
  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()

    def echoFlow: Flow[Message, Message, Any] =
      Flow[Message].map {
        case tm: TextMessage.Strict => TextMessage.Strict("Test " + tm.text)
        case _ => TextMessage("Message type unsupported")
      }

    val websocketRoute =
      path("chat") {
        handleWebSocketMessages(echoFlow)
      }

    val bindingFuture = Http().bindAndHandle(websocketRoute, "127.0.0.1", 8080)

    // the rest of the sample code will go here
    println("- Started server at 127.0.0.1:8080, press enter to kill server")
    StdIn.readLine()
    system.terminate()
  }
}

Solution

  • Not really sure what's going on, but if you add a default case to your assemblyMergeStrategy definition, it should work just fine.

    For example:

    assemblyMergeStrategy in assembly := {
      case "reference.conf" => MergeStrategy.concat
      case x =>
        val oldStrategy = (assemblyMergeStrategy in assembly).value
        oldStrategy(x)
    }
    

    Little edit:

    Actually on the repo it says

    assemblyMergeStrategy in assembly expects a function. You can't do assemblyMergeStrategy in assembly := MergeStrategy.first