如何运行由{sbt .jar
生成的package
文件?
我使用单个.scala
来源创建了一个非常简单的示例:
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()
}
}
}
运行后
$ sbt
> compile
> package
.jar
在/target/scala-<version>
中创建。如果我尝试运行它,则无法发出此错误:
$ 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
请注意,没有使用外部库,sbt compile run
工作正常。
我附上the whole project including generated .jar on dropbox。
真正奇怪的是.jar
Manifest包含要加载的正确类,即org.pack.Main
。也许是由其他原因造成的。
系统信息
$ 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
其他问题 - 如果.jar
中有一些外部/lib
,该怎么办?我怎样才能保证它们已被包装好?我需要一个.jar
可运行(可能)每个JVM。
感谢您的帮助。
答案 0 :(得分:22)
您可以使用 sbt 插件sbt-assembly:
由于 sbt-assembly 现在是自动插件,将 project / assembly.sbt 添加到 sbt就足够了项目:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
将 project / assembly.sbt 添加到 sbt 项目中:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
添加 assembly.sbt :
import AssemblyKeys._ // put this at the top of the file
assemblySettings
这为您提供了另一个 sbt 命令:
sbt assembly
生成一个“胖jar”(包括所有依赖项,包括Scala库)。
现在你可以开始你的程序了
java -cp ... / package-assembly.jar
所以你只需要一个Java安装和“胖罐子”。
答案 1 :(得分:11)
对于那些不希望构建胖jar的人,所有依赖项都将作为成功运行sbt package
的一部分下载。类路径信息存储在target
目录中的文件中,该文件可以传递到java
命令中。
示例:
sbt package
java -cp target/scala-2.11/yourproject.jar:$(cat target/streams/compile/dependencyClasspath/\$global/streams/export) Main
答案 2 :(得分:6)
尝试
scala package_2.9.2-0.1.jar
<强>更新强>
从Java开始,命令看起来像这样,
java -cp $SCALA_HOME/lib/scala-library.jar -jar package_2.9.2-0.1.jar
然而,在类路径中,您可能需要添加额外的jar,例如-cp "jar1.jar:jar2.jar"