2010-07-21 70 views
4

我试图用IntelliJ 9.0将它导出为jar。我的项目在Intellij中编译和运行时没有问题,但是当我将它写入一个.jar并打开它时,它将显示一个错误。从scala文件创建可执行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.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类,但我确信他们在那里。还有什么可以解决的问题,我该如何解决?

回答

5

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

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

我不知道IntelliJ如何构建你的jar:它是否打开你的所有库jars并将它们和你的代码一起放到一个大的jar中,或者它将库jar原样添加到你的大jar中并操纵类路径来获取罐子里的罐子?

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

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

+0

当IntelliJ构建一个Jar时,它只是在jar中添加jar。 这是一个很好的窍门。我试过你的想法,它会返回jar文件。也就是说,它会打印'myScalaApp.jar'。这是否意味着他不是在将舱单放入舱内? – Skuge 2010-07-21 08:52:12

+0

准确地说,存在这样的问题:这些类在* scalaApp.jar中不是*,即它们不直接位于其目录结构中。你的类路径需要包含对每个“内部”jar的引用,我不确定它的语法,或者如果有的话。我已经取得了很好的成功,可以爆炸所有的组件罐并将所有组件重新打包成一个罐子,但是除非你有一个工具(或者一个蚂蚁任务)来做到这一点,否则这是行得通的。 – 2010-07-21 09:03:16

+0

是的,它看起来像清单没有被尊重。由于我只是处于边缘帮助,所以我建议你不要再提到Scala就再次提出这个问题。很多人可以在纯Java环境下回答这个问题。 – 2010-07-21 09:05:31

2

至少有三种方法可以做到这一点。 (一个适用于NetBeans,但应在思想工作太)

  • 使用jarjar作为解释here
  • 使用理念上this page(不那么优雅,但最简单的) - 本质上解压,从斯卡拉库Scala的目录。 jar并将此目录添加到您的jar。
  • 使用this page(NB)上的想法 - 基本上将“scala-library.jar”添加到项目库中。