从scala文件创建可执行jar的问题

时间:2010-07-21 07:45:50

标签: scala jar intellij-idea executable executable-jar

我尝试将我的项目导出为带有IntelliJ 9.0的jar。我的项目在Intellij中编译并运行没有任何问题,但是当我将它写入.jar并打开它时,它将显示错误。

我的主课程类似于:

package Main

//Imports

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

现在,在工件窗口中,我创建了一个带有以下内容的.jar:

  1. Main Clas: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
  3. 我已经仔细检查过所有这些类都在项目中并且是onnly类。请注意,它包括lib/scala-compiler.jarlib/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 个答案:

答案 0 :(得分:5)

我会说两件事中有一件出了问题:

  • scala-library.jar不在你的罐子里;或
  • 运行时的类路径不包含scala-library.jar

我不知道IntelliJ如何构建你的jar:它是否解压你的所有库jar并将它们与你的代码一起粘在一个大罐子里,或者它是否将库罐原样添加到你的大罐子里并操纵它classpath来获取jars-within-jar?

第一点很容易检查:使用jar -tvf yourJar.jar列出jar的内容,或使用存档查看器以图形方式查看它。请注意,.jar基本上是.zip,因此您可以重命名扩展程序,然后使用可以查看.zip个文件的工具。

刚开始了解第二部分:你能构建一个打印出System.getProperty("java.class.path")的简单 Java 主类吗?即使Scala类不是,Java类也应该能够在该jar中运行。

答案 1 :(得分:2)

至少有三种方法可以做到这一点。 (一个适用于Netbeans,但也应该在Idea中工作)

  • 按照jarjar
  • 的说明使用here
  • this page上使用这个想法(不是那么优雅但最简单) - 基本上从scala-library.jar解压缩Scala目录并将此目录添加到jar中。
  • this page上使用这个想法(对于NB) - 基本上将“scala-library.jar”添加到项目库中。