How can I run .jar
file which is generated by sbt's package
?
I created a really simple example with a single .scala
source:
package org.pack {
class ScalaParser(files: Array[String]) {
def doAll() = {
println("hello")
}
}
object Main {
def main(args: Array[String]): Unit = {
val sp = new ScalaParser(args)
sp.doAll()
}
}
}
After running
$ sbt
> compile
> package
.jar
is created in /target/scala-<version>
. If I try to run it, it fails giving this error:
$ java -jar package_2.9.2-0.1.jar
Exception in thread "main" java.lang.NoClassDefFoundError: scala/ScalaObject
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.pack.Main.main(Main.scala)
Caused by: java.lang.ClassNotFoundException: scala.ScalaObject
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 13 more
Note that no external libraries are used and sbt compile run
works fine.
I attached the whole project including generated .jar on dropbox.
What is really weird is the fact that .jar
Manifest contains right class to load, i.e. org.pack.Main
. Maybe it is caused by something else.
System info
$ java -version
java version "1.7.0_55"
OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)
OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)
$ scala -version
Scala code runner version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
Additional question - what if I had some external .jar
s in /lib
? How can I assure that they are packed? I need one .jar
runnable on (possibly) every JVM.
Thanks for help.
To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar. jar contains another JAR file called MyUtils. jar, you cannot use the Class-Path header in MyJar.
If it is a standalone (Main method) java project then Not any specific path put all the jars inside the project not any specific path then right click on the project - > export - > Runnable jar --> Select the lunch configuration and Library handeling then choose the radio button option "Package required libraries into ...
You can use the sbt plugin sbt-assembly:
Since sbt-assembly is now an auto plugin, it is sufficient to add project/assembly.sbt to your sbt project:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
Add project/assembly.sbt to your sbt project:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
Add assembly.sbt as well:
import AssemblyKeys._ // put this at the top of the file
assemblySettings
This gives you another sbt command:
sbt assembly
which produces a "fat jar" (which includes all dependencies, including the Scala libraries).
Now you can start your program
java -cp .../package-assembly.jar
so you only need a Java installation and the "fat jar".
For those who do not wish to build a fat jar, all dependencies will have been downloaded as part of a successful run of sbt package
. Classpath information is stored in a file within the target
directory, which can be passed into the java
command.
Example:
sbt package
java -cp target/scala-2.11/yourproject.jar:$(cat target/streams/compile/dependencyClasspath/\$global/streams/export) Main
Try
scala package_2.9.2-0.1.jar
Update
From Java the command would look like this,
java -cp $SCALA_HOME/lib/scala-library.jar -jar package_2.9.2-0.1.jar
Yet in the classpath you may need to add additional jar's, for instance -cp "jar1.jar:jar2.jar"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With