如何运行由包生成的jar(可能与lib下的其他jar)?

pet*_*bel 19 sbt

如何运行.jar由sbt生成的文件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()
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

跑完之后

$ sbt
> compile
> package
Run Code Online (Sandbox Code Playgroud)

.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
Run Code Online (Sandbox Code Playgroud)

请注意,没有使用外部库并且sbt compile run工作正常.

我附加了整个项目,包括生成的.jar在dropbox上.

真正奇怪的是.jarManifest包含正确的类来加载,即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
Run Code Online (Sandbox Code Playgroud)

另外一个问题 - 如果我有一些外部.jar的东西/lib怎么办?我怎样才能保证它们已被包装好?我需要一个.jar可运行的(可能)每个JVM.

感谢帮助.

Ber*_*ium 22

你可以使用sbt插件sbt-assembly:

sbt-assembly> = 0.12.0,sbt> = 0.13.6

由于sbt-assembly现在是一个自动插件,将project/assembly.sbt添加到你的sbt项目就足够了:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5")
Run Code Online (Sandbox Code Playgroud)

sbt-assembly 0.11

project/assembly.sbt添加到您的sbt项目:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
Run Code Online (Sandbox Code Playgroud)

添加assembly.sbt:

import AssemblyKeys._ // put this at the top of the file

assemblySettings
Run Code Online (Sandbox Code Playgroud)

用法

这给你另一个sbt命令:

sbt assembly
Run Code Online (Sandbox Code Playgroud)

它产生一个"胖罐"(包括所有依赖项,包括Scala库).

现在你可以开始你的程序了

java -cp .../package-assembly.jar

所以你只需要一个Java安装和"胖罐子".


Ste*_*ari 11

对于那些不希望构建胖罐的人来说,所有依赖项都将作为成功运行的一部分下载sbt package.类路径信息存储在target目录中的文件中,该文件可以传递给java命令.

例:

sbt package
java -cp target/scala-2.11/yourproject.jar:$(cat target/streams/compile/dependencyClasspath/\$global/streams/export) Main
Run Code Online (Sandbox Code Playgroud)


elm*_*elm 6

尝试

scala package_2.9.2-0.1.jar
Run Code Online (Sandbox Code Playgroud)

更新

从Java开始,命令看起来像这样,

java -cp $SCALA_HOME/lib/scala-library.jar -jar  package_2.9.2-0.1.jar
Run Code Online (Sandbox Code Playgroud)

然而,在类路径中,您可能需要添加额外的jar -cp "jar1.jar:jar2.jar"