Scala Akka Http: com.typesafe.config.ConfigException $Missing: для ключа «диспетчер» не найден параметр конфигурации

При создании API с использованием scala Akka код выполняется в IDE, но при создании jar код не может быть запущен: используйте scala 2.11.12 и ниже — build.sbt

ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.11.12"

lazy val root = (project in file("."))
  .settings(
    name := "JNPM_SCALA_DATA_API",
    // Ensure that the IDE-specific settings like 'idePackagePrefix' are necessary or correctly configured.
    idePackagePrefix := Some("org.jio.jnpm"),
    // Adding resolver within project settings
    resolvers += "Typesafe Repo" at "https://repo.typesafe.com/typesafe/releases/",
    // Library dependencies
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http" % "10.0.15",  // Updated to stable version
      "com.typesafe.akka" %% "akka-actor" % "2.4.20",
      "com.typesafe.akka" %% "akka-stream" % "2.4.20",
      "com.typesafe.akka" %% "akka-http-spray-json" % "10.0.15"  // JSON library for Akka HTTP
    ),
    // Assembly settings
//    assembly / assemblyMergeStrategy := {
//      case PathList("META-INF", xs @ _*) => MergeStrategy.discard
//      case "application.conf" => MergeStrategy.concat
//      case _ => MergeStrategy.first
//    }
//  )
    assembly / assemblyMergeStrategy := {
      case PathList("META-INF", xs @ _*) => MergeStrategy.discard
      case "application.conf" => MergeStrategy.concat
      case _ => MergeStrategy.first
    }
  )

Ниже приведен файл application.conf:

akka {
  loglevel = "INFO"
  actor {
    default-dispatcher {
      type = "Dispatcher"
      executor = "fork-join-executor"
      fork-join-executor {
        parallelism-min = 2
        parallelism-factor = 2.0
        parallelism-max = 10
      }
    }
  }
  stream {
    materializer {
      initial-input-buffer-size = 16
      max-input-buffer-size = 128
    }
  }
}

Основной метод:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.{HttpResponse, StatusCodes}
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Route
import models.{JsonSupport, ReportPayload}

import scala.concurrent.ExecutionContextExecutor
import akka.stream.ActorMaterializerSettings
import akka.http.scaladsl.server.RouteResult.route2HandlerFlow
import com.typesafe.config.ConfigFactory

object WebServer extends JsonSupport{
  def main(args: Array[String]): Unit = {

    implicit val system: ActorSystem = ActorSystem("akkaHttpServer", ConfigFactory.load())

    println("Dispatcher Config: " + system.settings.config.getConfig("akka.actor.default-dispatcher"))

    val materializerSettings = ActorMaterializerSettings(system).withDispatcher("akka.actor.default-dispatcher") //default-dispatcher
    implicit val materializer: ActorMaterializer = ActorMaterializer(materializerSettings)(system)

    implicit val executionContext: ExecutionContextExecutor = system.dispatcher

    val route: Route = concat(

      get {
        path("hello") {
          complete(HttpResponse(OK, entity = "Hello from Akka HTTP!"))
        }
      },
      post {
        path("echo") {
          entity(as[String]) { body =>
            complete(HttpResponse(OK, entity = body))  // Echoes back the posted content
          }
        }
      },

      post {
        path("jnpm" / "pm" / "data" / "network_element") {
          entity(as[ReportPayload]) { reportPayload =>
            // Log received report details (simple console output for demonstration).
            println(s"Received report for user: ${reportPayload.user_id}")
            // Responds with a confirmation message.
            complete(StatusCodes.OK, s"Report for ${reportPayload.report_name} received and is being processed.")
          }
        }
      }
    )

    import akka.http.scaladsl.server.RouteResult._
    val bindingFuture = Http().bindAndHandle(route, "0.0.0.0", 8088)
    println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
    scala.io.StdIn.readLine() // Blocks here to keep the app running until the ENTER key is pressed.
    bindingFuture
      .flatMap(_.unbind()) // Disconnects the server from the port.
      .onComplete(_ => system.terminate()) // Shuts down the actor system to clean up resources.
  }
}

Ошибка ниже:

Loading config from properties {java.runtime.name=Java(TM) SE Runtime Environment, sun.boot.library.path=C:\Program Files (x86)\Java\jre-1.8\bin, java.vm.version=25.371-b11, java.vm.vendor=Oracle Corporation, java.vendor.url=http://java.oracle.com/, path.separator=;, java.vm.name=Java HotSpot(TM) Client VM, file.encoding.pkg=sun.io, user.script=, user.country=IN, sun.java.launcher=SUN_STANDARD, sun.os.patch.level=, java.vm.specification.name=Java Virtual Machine Specification, user.dir=C:\SCALA_SPARK\JNPM_SCALA_DATA_API\target\scala-2.11, java.runtime.version=1.8.0_371-b11, java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment, java.endorsed.dirs=C:\Program Files (x86)\Java\jre-1.8\lib\endorsed, os.arch=x86, java.io.tmpdir=C:\Users\VIVEKA~1.DES\AppData\Local\Temp\, line.separator=
, java.vm.specification.vendor=Oracle Corporation, user.variant=, os.name=Windows 11, sun.jnu.encoding=Cp1252, java.library.path=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\WindowsPowerShell\Scripts;C:\Windows\CCM;C:\Windows\CCM;C:\Windows\CCM;C:\Program Files (x86)\Enterprise Vault\EVClient\x64\;C:\Windows\CCM;C:\Windows\CCM;C:\Windows\CCM;C:\Users\Vivekanand.Desai\AppData\Local\Programs\Python\Python310\Scripts\;C:\Users\Vivekanand.Desai\AppData\Local\Programs\Python\Python310\;C:\Users\Vivekanand.Desai\AppData\Local\Programs\Python\Launcher\;C:\Users\Vivekanand.Desai\AppData\Local\Microsoft\WindowsApps;C:\apps\hadoop\bin;C:\apps\spark-3.5.0-bin-hadoop3\spark-3.5.0-bin-hadoop3\bin;C:\apps\spark-3.5.0-bin-hadoop3\spark-3.5.0-bin-hadoop3\sbin;C:\Java\jre-8u202-windows-x64\jre1.8.0_202\bin;;., java.specification.name=Java Platform API Specification, java.class.version=52.0, sun.management.compiler=HotSpot Client Compiler, os.version=10.0, user.home=C:\Users\Vivekanand.Desai, user.timezone=, java.awt.printerjob=sun.awt.windows.WPrinterJob, file.encoding=Cp1252, java.specification.version=1.8, user.name=Vivekanand.Desai, java.class.path=JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar, java.vm.specification.version=1.8, sun.arch.data.model=32, java.home=C:\Program Files (x86)\Java\jre-1.8, sun.java.command=JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar, java.specification.vendor=Oracle Corporation, user.language=en, awt.toolkit=sun.awt.windows.WToolkit, config.trace=loads, java.vm.info=mixed mode, java.version=1.8.0_371, java.ext.dirs=C:\Program Files (x86)\Java\jre-1.8\lib\ext;C:\Windows\Sun\Java\lib\ext, sun.boot.class.path=C:\Program Files (x86)\Java\jre-1.8\lib\resources.jar;C:\Program Files (x86)\Java\jre-1.8\lib\rt.jar;C:\Program Files (x86)\Java\jre-1.8\lib\jsse.jar;C:\Program Files (x86)\Java\jre-1.8\lib\jce.jar;C:\Program Files (x86)\Java\jre-1.8\lib\charsets.jar;C:\Program Files (x86)\Java\jre-1.8\lib\jfr.jar;C:\Program Files (x86)\Java\jre-1.8\classes, sun.stderr.encoding=cp437, java.vendor=Oracle Corporation, java.specification.maintenance.version=4, file.separator=\, java.vendor.url.bug=http://bugreport.sun.com/bugreport/, sun.cpu.endian=little, sun.io.unicode.encoding=UnicodeLittle, sun.stdout.encoding=cp437, sun.desktop=windows, sun.cpu.isalist=}
Loading config from resource 'application.conf' URL jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/application.conf from class loader sun.misc.Launcher$AppClassLoader@647e05
Loading config from a URL: jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/application.conf
URL sets Content-Type: 'content/unknown'
'content/unknown' isn't a known content type
Loading config from class loader sun.misc.Launcher$AppClassLoader@647e05 but there were no resources called application.json
exception loading application.json: java.io.IOException: resource not found on classpath: application.json
Loading config from class loader sun.misc.Launcher$AppClassLoader@647e05 but there were no resources called application.properties
exception loading application.properties: java.io.IOException: resource not found on classpath: application.properties
Loading config from resource 'reference.conf' URL jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/reference.conf from class loader sun.misc.Launcher$AppClassLoader@647e05
Loading config from a URL: jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/reference.conf
URL sets Content-Type: 'content/unknown'
'content/unknown' isn't a known content type
Looking for 'version.conf' relative to ParseableResourceURL(jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/reference.conf)
Looking for 'version.json' relative to ParseableResourceURL(jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/reference.conf)
Looking for 'version.properties' relative to ParseableResourceURL(jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/reference.conf)
Loading config from resource 'version.conf' URL jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/version.conf from class loader sun.misc.Launcher$AppClassLoader@647e05
Loading config from a URL: jar:file:/C:/SCALA_SPARK/JNPM_SCALA_DATA_API/target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar!/version.conf
URL sets Content-Type: 'content/unknown'
'content/unknown' isn't a known content type
Loading config from class loader sun.misc.Launcher$AppClassLoader@647e05 but there were no resources called version.json
exception loading version.json: java.io.IOException: resource not found on classpath: version.json
Loading config from class loader sun.misc.Launcher$AppClassLoader@647e05 but there were no resources called version.properties
exception loading version.properties: java.io.IOException: resource not found on classpath: version.properties
Loading config from a String resizer.enabled=on
Dispatcher Config: Config(SimpleConfigObject({"executor":"fork-join-executor","fork-join-executor":{"parallelism-factor":2,"parallelism-max":10,"parallelism-min":2},"type":"Dispatcher"}))
Exception in thread "main" com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'dispatcher'
        at com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:152)
        at com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:170)
        at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:184)
        at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:189)
        at com.typesafe.config.impl.SimpleConfig.getString(SimpleConfig.java:246)
        at akka.stream.ActorMaterializerSettings$.apply(ActorMaterializer.scala:267)
        at akka.stream.ActorMaterializerSettings$.apply(ActorMaterializer.scala:258)
        at org.jio.jnpm.WebServer$.main(WebServer.scala:31)
        at org.jio.jnpm.WebServer.main(WebServer.scala)

Код отлично работает в IDE, но не использует файл jar. Он ищет диспетчер ключевых слов, не уверен, где он ищет.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша стратегия сборки плохая:

assembly / assemblyMergeStrategy := {
  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
  case "application.conf" => MergeStrategy.concat
  case _ => MergeStrategy.first
}

Удалите этот раздел assembly / assemblyMergeStrategy из build.sbt (тогда будет применена стратегия сборки по умолчанию), а затем

sbt clean
sbt assembly
java -jar ./target/scala-2.11/JNPM_SCALA_DATA_API-assembly-0.1.0-SNAPSHOT.jar

должно сработать.

Стратегия sbt-assembly по умолчанию:

  val defaultMergeStrategy: String => MergeStrategy = {
    case x if Assembly.isConfigFile(x) =>
      MergeStrategy.concat
    case PathList(ps @ _*) if Assembly.isReadme(ps.last) || Assembly.isLicenseFile(ps.last) =>
      MergeStrategy.rename
    case PathList("META-INF", xs @ _*) =>
      (xs map {_.toLowerCase}) match {
        case ("manifest.mf" :: Nil) | ("index.list" :: Nil) | ("dependencies" :: Nil) =>
          MergeStrategy.discard
        case ps @ (x :: xs) if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") =>
          MergeStrategy.discard
        case "plexus" :: xs =>
          MergeStrategy.discard
        case "services" :: xs =>
          MergeStrategy.filterDistinctLines
        case ("spring.schemas" :: Nil) | ("spring.handlers" :: Nil) =>
          MergeStrategy.filterDistinctLines
        case _ => MergeStrategy.deduplicate
      }
    case _ => MergeStrategy.deduplicate
  }

https://github.com/sbt/sbt-assembly/blob/develop/README.md#merge-strategy

https://github.com/sbt/sbt-assembly/blob/develop/src/main/scala/sbtassembly/MergeStrategy.scala#L185-L211

Для отладки вы можете использовать стратегию

assembly / assemblyMergeStrategy := (_ => MergeStrategy.singleOrError)

чтобы увидеть все дубликаты:

[error] SingleOrError found multiple files with the same target path:
[error]   Jar name = akka-actor_2.11-2.4.20.jar, jar org = com.typesafe.akka, entry target = reference.conf
[error]   Jar name = akka-http-core_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = reference.conf
[error]   Jar name = akka-http_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = reference.conf
[error]   Jar name = akka-stream_2.11-2.4.20.jar, jar org = com.typesafe.akka, entry target = reference.conf
[error]   Jar name = ssl-config-core_2.11-0.2.1.jar, jar org = com.typesafe, entry target = reference.conf
[error] SingleOrError found multiple files with the same target path:
[error]   Jar name = akka-actor_2.11-2.4.20.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = akka-http-core_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = akka-http-spray-json_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = akka-http_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = akka-parsing_2.11-10.0.15.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = akka-stream_2.11-2.4.20.jar, jar org = com.typesafe.akka, entry target = META-INF/MANIFEST.MF
[error]   Jar name = config-1.3.0.jar, jar org = com.typesafe, entry target = META-INF/MANIFEST.MF
[error]   Jar name = ssl-config-core_2.11-0.2.1.jar, jar org = com.typesafe, entry target = META-INF/MANIFEST.MF
[error]   Jar name = spray-json_2.11-1.3.4.jar, jar org = io.spray, entry target = META-INF/MANIFEST.MF
[error]   Jar name = reactive-streams-1.0.0.jar, jar org = org.reactivestreams, entry target = META-INF/MANIFEST.MF
[error]   Jar name = scala-java8-compat_2.11-0.7.0.jar, jar org = org.scala-lang.modules, entry target = META-INF/MANIFEST.MF
[error]   Jar name = scala-parser-combinators_2.11-1.0.4.jar, jar org = org.scala-lang.modules, entry target = META-INF/MANIFEST.MF
[error]   Jar name = scala-library-2.11.12.jar, jar org = org.scala-lang, entry target = META-INF/MANIFEST.MF

Итак, ваши дубликаты — это несколько файлов reference.conf и META-INF/MANIFEST.MF. Судя по всему, используя MergeStrategy.first вместо reference.conf, вы куда-то удалили dispatcher. Это и было причиной ошибки.

Когда вышеуказанной стратегии по умолчанию недостаточно, лучше выразить собственную стратегию, частично повторно используя стратегию по умолчанию:

assembly / assemblyMergeStrategy := {
  case ... => ... // additional cases
  case x   =>
    // default strategy
    val oldStrategy = (assembly / assemblyMergeStrategy).value 
    oldStrategy(x)
}

Минимальная стратегия, наиболее близкая к вашей:

assembly / assemblyMergeStrategy := {
  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
  case "reference.conf" => MergeStrategy.concat
  case _ => MergeStrategy.singleOrError
}

Неаккуратное использование пользовательских стратегий (например, невыборочное использование MergeStrategy.discard, MergeStrategy.first/MergeStrategy.last) может привести ко многим (иногда странным) проблемам:

Сборка SBT выводит 0xEFBFBD вместо 0xCAFEBABE в файле класса

sbt-assembly и Lucene «Класс SPI типа org.apache.lucene.codecs.Кодек с именем Lucene94 не существует.¨ исключение

Пухнет толстая банка nullpointer KieServices

Запустите проект Drools Kie из толстой банки

sbt-assembly: обнаружена ошибка дедупликации

Проблема решена после удаления из build.sbt приведенного ниже: преобразователи += «Typesafe Repo» на «repo.typesafe.com/typesafe/releases»

vivekdesai 10.05.2024 05:13

Другие вопросы по теме