【问题标题】:Problem creating an executable jar from scala file从 scala 文件创建可执行 jar 的问题
【发布时间】:2011-03-18 20:27:47
【问题描述】:

我正在尝试使用 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.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 类,但我确保它们在那里。还有什么问题,我该如何解决?

【问题讨论】:

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


    【解决方案1】:

    我想说两件事中的一件出了问题:

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

    我不知道 IntelliJ 如何构建您的 jar:它是解压缩所有库 jar 并将它们与您的代码一起放入一个大 jar 中,还是将库 jar 按原样添加到您的大 jar 中并操作获取 jars-within-jar 的类路径?

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

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

    【讨论】:

    • 当 IntelliJ 构建 Jar 时,它只是在 jar 中添加 jar。这是一个不错的技巧。我尝试了你的想法,它返回了 jar 文件。也就是说,它打印“myScalaApp.jar”。这是否意味着他不会为了让罐子里面而变红清单?
    • 没错,问题出在:这些类not 在 yourScalaApp.jar 中,即它们不直接位于其目录结构中。您的类路径需要包含对每个“内部”jar 的引用,我不确定它的语法,或者是否有一个。我在分解所有组件 jar 并将所有内容重新打包到一个 jar 中取得了很好的成功,但除非您有工具(或 ant 任务)来执行此操作,否则它是可行的。
    • 是的,清单似乎没有得到尊重。由于我只是提供微不足道的帮助,因此我建议您在不参考 Scala 的情况下再次尝试问这个问题。很多人可能可以在纯 Java 上下文中回答这个问题。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2010-10-22
      • 2010-12-06
      相关资源
      最近更新 更多