2

This the code that I have written in Scala.

object Main extends App {
    println("Hello World from Scala!")
}

This is my build.sbt.

name := "hello-world"
version := "1.0"
scalaVersion := "2.11.5"
mainClass := Some("Main")

This is the command that I have run to create the jar file.

sbt package

My problem is that a jar file named hello-world_2.11-1.0.jar has been created at target/scala-2.11. But I cannot run the file. It is giving me an error saying NoClassDefFoundError.

What am I doing wrong?

halfer
  • 19,824
  • 17
  • 99
  • 186
odbhut.shei.chhele
  • 5,834
  • 16
  • 69
  • 109

4 Answers4

5

It also says what class is not found. Most likely you aren't including scala-library.jar. You can run scala target/scala-2.11/hello-world_2.11-1.0.jar if you have Scala 2.11 available from the command line or java -cp "<path to scala-library.jar>:target/scala-2.11/hello-world_2.11-1.0.jar" Main (use ; instead of : on Windows).

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
1

The procedure depicted proves valid up to the way the jar file is executed. From target/scala-2.11 try running it with

scala hello-world_2.11-1.0.jar

Check whether it is runnable also from the project root folder with sbt run.

elm
  • 20,117
  • 14
  • 67
  • 113
0

To run the jar file(containing scala code) with multiple main classes use following approach

scala -cp "<jar-file>.jar;<other-dependencies>.jar" com.xyz.abc.TestApp

This command will take care of including scala-library.jar in dependency and will also identify TestApp as main class if it has a def main(args:Array[String]) method. Please note that multiple jar files should be separated by semi-colon(";")

Gaurav Khare
  • 2,203
  • 4
  • 25
  • 23
0

We can use sbt-assembly to package and run the application.

First, create or add the plugin to project/plugins.sbt

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

The sample build.sbt looks like below:

name := "coursera"

version := "0.1"

scalaVersion := "2.12.10"
mainClass := Some("Main")
val sparkVersion = "3.0.0-preview2"
val playVersion="2.8.1"

val jacksonVersion="2.10.1"

libraryDependencies ++= Seq(
  "org.scala-lang" % "scala-library" % scalaVersion.toString(),
  "org.apache.spark" %% "spark-streaming" % sparkVersion,
  "org.apache.spark" %% "spark-core" % sparkVersion,
  "org.apache.spark" %% "spark-sql" % sparkVersion,
  "com.typesafe.play" %% "play-json" % playVersion,
  // https://mvnrepository.com/artifact/org.apache.spark/spark-streaming-kafka-0-10
  "org.apache.spark" %% "spark-streaming-kafka-0-10" % sparkVersion,
  // https://mvnrepository.com/artifact/org.mongodb/casbah
  "org.mongodb" %% "casbah" % "3.1.1" pomOnly(),
  // https://mvnrepository.com/artifact/com.typesafe/config
  "com.typesafe" % "config" % "1.2.1"
)

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

From console, we can run sbt assembly and the jar file gets created in target/scala-2.12/ path.

sbt assembly will create a fat jar. Here is an excerpt from the documentation :

sbt-assembly is a sbt plugin originally ported from codahale's assembly-sbt, which I'm guessing was inspired by Maven's assembly plugin. The goal is simple: Create a fat JAR of your project with all of its dependencies.

ForeverLearner
  • 1,901
  • 2
  • 28
  • 51