Проблема с созданием исполняемого jar из файла scala - PullRequest
4 голосов
/ 21 июля 2010

Я пытаюсь экспортировать свой проект как банку с IntelliJ 9.0. Мой проект компилируется и выполняется без проблем в Intellij, но когда я запишу его в .jar и открою, он выдаст ошибку.

Мой основной класс - это что-то вроде:

package Main

//Imports

object Main{
  def main(args: Array[String]) {
    println("Main: Hello, world!")
    //do stuff
}

Теперь в окне артефактов я создал .jar со следующим:

  1. Основной класс: Main.Main
  2. Путь к классу: lib/javacsv lib/scala-compiler.jar lib/scala-library.jar lib/scalatest-1.0-test.jar lib/scalatest-1.0.jar lib/tools.jar lib/jtds-1.2.2.jar lib/flex-messaging-common.jar lib/flex-messaging-core.jar lib/spring.jar lib/mysql-connector-java-5.1.7-bin.jar lib/ojdbc14.jar lib/commons-logging.jar lib/postgresql-8.4-701.jdbc3.jar lib/log4j-1.2.15.jar lib/poi-3.6-20091214.jar lib/poi-ooxml-3.6-20091214.jar lib/dom4j-1.6.1.jar lib/poi-ooxml-schemas-3.6-20091214.jar lib/geronimo-stax-api_1.0_spec-1.0.jar lib/xmlbeans-2.3.0.jar lib/rt.jar lib/ifxjdbc.jar lib/db2jcc4.jar

Я дважды проверил, что все эти классы находятся в проекте и являются единственными классами в нем. Обратите внимание, что в него входят lib/scala-compiler.jar и lib/scala-library.jar.

Создайте проект: java -jar myScalaApp.jar и я получу:

Exception in thread "main" java.lang.NoClassDefFoundError: scala/ScalaObject
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:675)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:288)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
    at Main.Main.main(Main.scala)
Caused by: java.lang.ClassNotFoundException: scala.ScalaObject
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:288)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:374)
    ... 13 more

Я понимаю, что там нет классов scala, но я убедился, что они там есть. В чем еще может быть проблема и как я могу это исправить?

Ответы [ 2 ]

5 голосов
/ 21 июля 2010

Я бы сказал, что одна из двух вещей пошла не так:

  • scala-library.jar не в вашей банке;или
  • путь к классу во время выполнения не включает scala-library.jar.

Я не знаю, как IntelliJ создает ваш jar: распаковывает ли он все ваши библиотечные jar и загружает ихвместе с вашим кодом в один большой jar-файл, или он добавляет jar-файлы библиотеки как есть в ваш большой jar-файл и манипулирует classpath, чтобы добраться до jars-inside-jar?

Первый пункт достаточно прост, чтобыcheck: либо используйте jar -tvf yourJar.jar, чтобы составить список содержимого вашего jar-файла, либо воспользуйтесь средством просмотра архива, чтобы просмотреть его графически.Обратите внимание, что .jar - это, по сути, .zip, поэтому вы можете переименовать расширение и затем использовать инструмент, который может просматривать файлы .zip.

Только что пришла идея насчет второй части: Можете ли выпостроить простой Java основной класс, который печатает System.getProperty("java.class.path")?Класс Java должен быть в состоянии работать в этом банке, даже если класс Scala нет.

2 голосов
/ 17 марта 2011

Есть как минимум три способа сделать это.(Один относится к Netbeans, но должен работать и в Idea)

  • Использовать jarjar как объяснено здесь
  • Использовать идею на this page (не такой элегантный, но самый простой) - по сути, распакуйте каталог Scala из scala-library.jar и добавьте этот каталог в свой jar.
  • Используйте идею на этой странице (для NB) - по существу добавьте "scala-library.jar" в свои библиотеки проектов.
...