Почему я не могу мариновать свои кейсы? Что я должен сделать, чтобы решить эту проблему вручную в следующий раз?
Изменить 2: Наблюдения и вопросы
Я почти уверен вместе с комментатором Джастином, что проблема связана с ошибкой
build.sbt
конфигурации. Тем не менее, я впервые вижу странствующегоbuild.sbt
конфигурация, которая буквально работает для всего остального, кроме сборщиков. Может быть, это потому, что они используют макросы, а я, как правило, избегаю их.Почему это важно
Flow.merge
используется противFlow.map
если проблема сsbt
?Подозрительный экстракт build.sbt
lazy val server = project .dependsOn(sharedJvm, client)
Подозрительный след стека
Так что это вершина стека: он идет от метода, который я не могу найти, к среде связывания с утилитами кодирования строк. Хорошо.
server java.lang.RuntimeException: stub
А? stub
?
server at scala.sys.package$.error(package.scala:27)
server at scala.scalajs.runtime.package$.linkingInfo(package.scala:143)
server at scala.scalajs.runtime.package$.environmentInfo(package.scala:137)
А?
server at scala.scalajs.js.Dynamic$.global(Dynamic.scala:78)
???
server at boopickle.StringCodec$.encodeUTF8(StringCodec.scala:56)
Редактировать 1: моя большая и красивая build.sbt может быть проблема
То, что вы не можете видеть, это то, что я организовал в своем project
папка:
JvmDependencies.scala
который имеет регулярные зависимости JvmSjsDependencies.scala
у которого естьDef.settingsKey
сlibraryDependencies
наJsModuleID
sWebJarDependencies.scala
который имеет JavaScript и CSS
build.sbt
lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared"))
.configure(_.enablePlugins(ScalaJSPlugin))
.settings(SjsDependencies.pickling.toSettingsDefinition(): _*)
.settings(SjsDependencies.tagsAndDom.toSettingsDefinition(): _*)
.settings(SjsDependencies.css.toSettingsDefinition(): _*)
lazy val sharedJvm = shared.jvm
lazy val sharedJs = shared.js
lazy val cmdlne = project
.dependsOn(sharedJvm)
.settings(
libraryDependencies ++= (
JvmDependencies.commandLine ++
JvmDependencies.logging ++
JvmDependencies.akka ++
JvmDependencies.serialization
)
)
lazy val client = project
.enablePlugins(ScalaJSPlugin, SbtWeb, SbtSass)
.dependsOn(sharedJs)
.settings(
(SjsDependencies.shapeless ++ SjsDependencies.audiovideo ++ SjsDependencies.databind ++ SjsDependencies.functional ++ SjsDependencies.lensing ++ SjsDependencies.logging ++ SjsDependencies.reactive).toSettingsDefinition(),
jsDependencies ++= WebjarDependencies.js,
libraryDependencies ++= WebjarDependencies.notJs,
persistLauncher in Compile := true
)
lazy val server = project
.dependsOn(sharedJvm, client)
.enablePlugins(SbtNativePackager)
.settings(
copyWebJarResources := { streams.value.log("Copying webjar resources")
val `Web Modules target directory` = (resourceManaged in Compile).value / "assets"
val `Web Modules source directory` = (WebKeys.assets in Assets in client).value / "lib"
final class UsefulFileFilter(acceptable: String*) extends FileFilter {
// TODO ADJUST TO EXCLUDE JS MAP FILES
import scala.collection.JavaConversions._
def accept(file: File) = (file.isDirectory && FileUtils.listFiles(file, acceptable.toArray, true).nonEmpty) || acceptable.contains(file.ext) && !file.name.contains(".js.")
}
val `file filter` = new UsefulFileFilter("css", "scss", "sass", "less", "map")
IO.createDirectory(`Web Modules target directory`)
IO.copyDirectory(source = `Web Modules source directory`, target = `Web Modules target directory` / "script")
FileUtils.copyDirectory(`Web Modules source directory`, `Web Modules target directory` / "style", `file filter`)
},
// run the copy after compile/assets but before managed resources
copyWebJarResources <<= copyWebJarResources dependsOn(compile in Compile, WebKeys.assets in Compile in client, fastOptJS in Compile in client),
managedResources in Compile <<= (managedResources in Compile) dependsOn copyWebJarResources,
watchSources <++= (watchSources in client),
resourceGenerators in Compile <+= Def.task {
val files = ((crossTarget in(client, Compile)).value ** ("*.js" || "*.map")).get
val mappings: Seq[(File,String)] = files pair rebase((crossTarget in(client, Compile)).value, ((resourceManaged in Compile).value / "assets/").getAbsolutePath )
val map: Seq[(File, File)] = mappings.map { case (s, t) => (s, file(t))}
IO.copy(map).toSeq
},
reStart <<= reStart dependsOn (managedResources in Compile),
libraryDependencies ++= (
JvmDependencies.akka ++
JvmDependencies.jarlocating ++
JvmDependencies.functional ++
JvmDependencies.serverPickling ++
JvmDependencies.logging ++
JvmDependencies.serialization ++
JvmDependencies.testing
)
)
Редактировать 0: В очень неясной теме чата есть парень, который говорит, что я чувствую: нет, не **** scala, но
Марк Эйбс @i-am-the-slime 15 октября 2015 09:37 @ochrons Я все еще сражаюсь. Я не могу больше мариновать. https://gitter.im/scala-js/scala-js/archives/2015/10/15
У меня довольно простое требование - у меня есть один маршрут веб-сокета на akka
http-сервер, который определен AkkaServerLogEventToMessageHandler()
:
object AkkaServerLogEventToMessageHandler
extends Directives {
val sourceOfLogs =
Source.actorPublisher[AkkaServerLogMessage](AkkaServerLogEventPublisher.props) map {
event ⇒
BinaryMessage(
ByteString(
Pickle.intoBytes[AkkaServerLogMessage](event)
)
)
}
def apply(): server.Route = {
handleWebSocketMessages(
Flow[Message].merge(sourceOfLogs)
)
}
}
Это вписывается в крошечный набор маршрутов наиболее очевидным способом.
Теперь почему я не могу получить boopickle
, upickle
, или же prickle
сериализовать что-то столь же простое, как этот тупой класс case?
sealed case class AkkaServerLogMessage(
message: String,
level: Int,
timestamp: Long
)
- Нет вложенности
- Все примитивные типы
- Нет дженериков
- Только три из них
Все это выдает примерно одинаковую ошибку
- Используя все три общих сборщика, чтобы написать
- С помощью
TextMessage
вместоBinaryMessage
и соответствующийupickle
или жеprickle
writeJs
или какими-либо методами - Меняя
case class
до нуля (ничего, как ни у кого из участников) - Изменяя сам вход в
case class
- Импорт различных перестановок
Implicits
и подчеркнуть вещи
... в частности, они дали мне вариации на одну и ту же глупую ошибку (не ту же ошибку, но значительно похожую)
server [ERROR] [04/21/2016 22:04:00.362] [app-akka.actor.default-dispatcher-7] [akka.actor.ActorSystemImpl(app)] WebSocket handler failed with stub
server java.lang.RuntimeException: stub
server at scala.sys.package$.error(package.scala:27)
server at scala.scalajs.runtime.package$.linkingInfo(package.scala:143)
server at scala.scalajs.runtime.package$.environmentInfo(package.scala:137)
server at scala.scalajs.js.Dynamic$.global(Dynamic.scala:78)
server at boopickle.StringCodec$.encodeUTF8(StringCodec.scala:56)
server at boopickle.Encoder.writeString(Codecs.scala:338)
server at boopickle.BasicPicklers$StringPickler$.pickle(Pickler.scala:183)
server at boopickle.BasicPicklers$StringPickler$.pickle(Pickler.scala:134)
server at boopickle.PickleState.pickle(Pickler.scala:511)
server at shindig.clientaccess.handler.AkkaServerLogEventToMessageHandler$$anonfun$1$Pickler$macro$1$2$.pickle(AkkaServerLogEventToMessageHandler.scala:35)
server at shindig.clientaccess.handler.AkkaServerLogEventToMessageHandler$$anonfun$1$Pickler$macro$1$2$.pickle(AkkaServerLogEventToMessageHandler.scala:35)
server at boopickle.PickleImpl$.apply(Default.scala:70)
server at boopickle.PickleImpl$.intoBytes(Default.scala:75)
server at shindig.clientaccess.handler.AkkaServerLogEventToMessageHandler$$anonfun$1.apply(AkkaServerLogEventToMessageHandler.scala:35)
server at shindig.clientaccess.handler.AkkaServerLogEventToMessageHandler$$anonfun$1.apply(AkkaServerLogEventToMessageHandler.scala:31)
Это сработало
- Не используется
Flow.merge
(побеждает цель, я хочу продолжать рассылку с журналами) - Использование статического значения
- Другие бесполезные вещи
призыв
Пожалуйста, дайте мне знать, где и почему я тупой... Я потратил четыре часа на эту проблему сегодня в разных формах, и это сводит меня с ума.
2 ответа
В вашем build.sbt
, у тебя есть:
lazy val shared = (crossProject.crossType(CrossType.Pure) in file("shared"))
.configure(_.enablePlugins(ScalaJSPlugin))
Не делайте этого. Вы никогда не должны включать плагин Scala.js для кросс-проекта. Это также добавляет это к стороне JVM, которая вызовет хаос. В частности, это приведет к %%%
разрешить артефакты Scala.js ваших зависимостей в проекте JVM, и это действительно плохо. Это то, что вызывает вашу проблему.
crossProject
уже добавляет плагин Scala.js к части JS, и только эту. Так просто убери это enablePlugins
линия.
Тайна разгадана. Спасибо @Justin du Coeur за то, что указал мне правильное направление.
Причина boopickle
не работал, в частности, потому что в цепочке зависимостей я включал как sjs
и jvm
версия boopickle
в server
проект.
Я удалил server
dependsOn
за client
и для sharedJs
а также удалены boopickle
из общих зависимостей. Теперь это работает.