2010-07-21 50 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」添加到項目庫中。