0

I have developed a web app using scalatra 2.6.3 and scala 2.11.8 for the first time and it is not getting executed using jar. Below are my dependencies in build.sbt

scalaVersion := "2.11.8"
val scalatraVersion = "2.6.3"

dependencyOverrides += "com.fasterxml.jackson.core" % "jackson-core" % "2.9.4"
dependencyOverrides += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.4"
dependencyOverrides += "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.9.4"


libraryDependencies ++= Seq(
  "com.microsoft.sqlserver" % "mssql-jdbc" % "6.4.0.jre8", //Microsoft JDBC Driver For SQL Server
  "com.typesafe.play" %% "play-json" % "2.5.10",
  "com.typesafe" % "config" % "1.2.1", //Configuration
  "org.scalaj" %% "scalaj-http" % "2.3.0" % "compile",
  "org.apache.spark" %% "spark-core" % "2.2.0",
  "org.apache.spark" %% "spark-sql" % "2.2.0",
  "org.scala-lang" % "scala-library" % "${scala.version}",
  "org.apache.lucene" % "lucene-queryparser" % "7.2.1",
  "org.apache.lucene" % "lucene-queries" % "7.2.1",
  "org.apache.lucene" % "lucene-analyzers-common" % "7.2.1",
  "org.apache.lucene" % "lucene-codecs" % "7.2.1" ,
  "com.microsoft.azure" % "azure-storage" % "3.1.0",
  "com.microsoft.azure" % "azure-eventhubs" % "0.6.6",
  "org.apache.hadoop" % "hadoop-azure" % "2.7.0",
  "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.3-1",
  "com.amazonaws" % "aws-java-sdk-logs" % "1.10.40",

  //Logging
  "org.slf4j" % "slf4j-api" % "1.7.25",
  "ch.qos.logback" % "logback-classic" % "1.2.3",

  "org.scalatra" %% "scalatra" % scalatraVersion,
  "org.scalatra" %% "scalatra-scalatest" % scalatraVersion % "test",
  "org.eclipse.jetty" % "jetty-webapp" % "9.4.10.RC1",
  "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
  "org.scalatra" %% "scalatra-scalate" % scalatraVersion
)

unmanagedResourceDirectories in Compile += { baseDirectory.value / "src/main/webapp" }
enablePlugins(ScalatraPlugin)

assemblyMergeStrategy in assembly := {

  case PathList("META-INF", xs @ _*) =>
    (xs map {_.toLowerCase}) match {
       case "services" :: xs =>
        MergeStrategy.first
      case _ => MergeStrategy.discard
    }
   case x => MergeStrategy.first
}

I know scalatra internally uses jetty to run App, I have setup webapp directory (src/main/webapp/) in project and I am able to run App in local using intellij but when I run it from jar file (created using sbt assembly) then it fails to find web app folder. Below is the code of Main app.

val server = {
  val listenPort = if (System.getenv.containsKey("PORT")) System.getenv.get("PORT").toShort else ConfigFactory.load.getString("api.port_num").toShort;
  logger.info("Listen Port: " + listenPort)
  new Server(listenPort)
}

val context: WebAppContext = new WebAppContext();
val webappDirLocation = "src/main/webapp/"
context.setServer(server)
context.setContextPath("/");
context.setDescriptor(webappDirLocation + "/WEB-INF/web.xml")
context.setResourceBase(webappDirLocation)
server.setHandler(context);

try {
  server.start()
  server.join()
} catch {
  case e: Exception => logger.error(s"Error occurred while starting App : $e")
    throw new RuntimeException(s"Unable to start App : $e")
}

Please suggest how to resolve this error, I am completely stuck at this. Tried below steps to resolve it, but no luck: -set war location using context.setWar method. -getting absolute path of src/main/webapp before setting in context

Thanks in advance!

Monika
  • 143
  • 2
  • 3
  • 11
  • Can you show how you run this and what error do you get? – mfirry May 04 '18 at 07:13
  • I run it using "scala -classpath InputSuggester-assembly-1.0.jar com.affinio.app.StartJetty" where StartJetty is main file containing code shared above. Doesn't give me any error but servlet class doesn't execute(get no logs for servlet class which appears when I run in intellij, also unable to send request to servlet; results in HTTP ERROR 404), just get "18/05/04 13:18:46 INFO Server: Started @3519ms" – Monika May 04 '18 at 13:22
  • so this was not built using the usual "ScalatraBootstrap" suggested? – mfirry May 05 '18 at 16:20

1 Answers1

1

If your assembly jar file contains /WEB-INF/web.xml, you can setup WebAppContext as follows:

val context: WebAppContext = new WebAppContext()
val webXml = getClass.getResource("/WEB-INF/web.xml")

val webappDirLocation = if(webXml != null){
  // running the assembly jar
  webXml.toString.replaceFirst("/WEB-INF/web.xml$", "/")
} else {
  // running on the source tree
  "src/main/webapp/"
}

context.setResourceBase(webappDirLocation)
context.setDescriptor(webappDirLocation + "WEB-INF/web.xml")

In above example, configuration is switched because it needs different configuration for running on the source tree and for running the assembly jar.

In addition, note that you need to add following line to your build.sbt to include webapp/* to your assembly jar file by sbt-assembly-plugin:

unmanagedResourceDirectories in Compile += { baseDirectory.value / "src/main/webapp" }
Naoki Takezoe
  • 471
  • 2
  • 7
  • But now I get error like : java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps; at org.fusesource.scalate.util.ClassPathBuilder$.getClassPathFrom(ClassPathBuilder.scala:143) at org.fusesource.scalate.util.ClassPathBuilder.addPathFrom(ClassPathBuilder.scala:70) at org.fusesource.scalate.util.ClassPathBuilder.addPathFrom(ClassPathBuilder.scala:65) at org.fusesource.scalate.servlet.ServletTemplateEngine.buildClassPath(ServletTemplateEngine.scala:117) ... – Monika May 07 '18 at 17:18
  • Try to replace scalatra-scalate_2.11 dependency with "org.scalatra" %% "scalatra-scalate" % ScalatraVersion, and remove "org.scalatra.scalate" % "scalate-core_2.11" % "1.8.0". – Naoki Takezoe May 08 '18 at 03:44
  • Have you removed or replaced all _2.11 dependencies in your project? I guess your project works with Scala 2.12, but some libraries reference Scala 2.11. This question might help you: https://stackoverflow.com/questions/40328948/java-lang-nosuchmethoderror-scala-predef-refarrayops – Naoki Takezoe May 09 '18 at 02:15
  • Thanks Naoki for your response. Updated dependency in question statement. I am using scala 2.11.8 – Monika May 09 '18 at 02:47