Как запустить jar, сгенерированный пакетом (возможно, с другими jar-файлами из lib)?

Как я могу бежать .jar файл, который генерируется sbt's 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 работает отлично.

Я прикрепил весь проект, включая сгенерированный.jar на dropbox.

Что действительно странно, так это то, что .jar Манифест содержит правильный класс для загрузки, т.е. 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.

Спасибо за помощь.

3 ответа

Решение

Вы можете использовать плагин https://github.com/sbt/sbt-assembly:

sbt-сборка>= 0,12,0 с sbt >= 0,13,6

Поскольку sbt-assembly теперь является автоматическим плагином, достаточно добавить project/assembly.sbt в ваш проект sbt:

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

SBT-сборка 0,11

Добавьте project/assembly.sbt в ваш проект sbt:

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

Добавьте также сборку.sbt:

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

assemblySettings

использование

Это дает вам другую команду sbt:

sbt assembly

который производит "толстый фляга" (который включает все зависимости, включая библиотеки Scala).

Теперь вы можете начать свою программу

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

так что вам нужна только установка Java и "толстый кувшин".

Для тех, кто не хочет создавать толстую банку, все зависимости будут загружены как часть успешного запуска sbt package, Информация о пути к классам хранится в файле внутри target каталог, который можно передать в java команда.

Пример:

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

Пытаться

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

Тем не менее, в classpath вам может понадобиться добавить дополнительные банки, например -cp "jar1.jar:jar2.jar"

Другие вопросы по тегам