【问题标题】:Generate .jar from scala从 Scala 生成 .jar
【发布时间】:2025-12-27 22:40:11
【问题描述】:

我正在使用 Scala 在 Eclipse 上开发一个应用程序,并且想创建一个 .jar。我发现 tuto 可以做到这一点,但它使用包 scala.tools.nsc 我不知道在哪里可以找到这个东西。
我也尝试过生成.class,然后使用命令jar cmf .... 生成.jar,但是当我启动.jar 时发生错误。 (NoClassFound)
使用 sbt 我也尝试过,但是当我编译与 eclipse 一起使用的项目时,会出现很多错误。

谁能解释我如何使用 Eclipse 或其他工具简单地创建一个 .jar。

【问题讨论】:

  • 我将 'java cmf' 更正为 'jar cmf',如果可以,请查看。并查看常见问题解答、元数据和侧边栏,了解如何编辑您的帖子。布局等等。一般来说,当因为错误而询问时:你到底做了什么?命令?剪切并粘贴它,以避免传输错误。复制并粘贴确切的错误消息。你在哪个目录启动命令,你的文件结构是什么,你选择了什么项目名称,文件层次结构是否与目录对应?您之前是否使用过jar,例如使用Java 并取得了多大的成功?谢谢。

标签: eclipse scala jar


【解决方案1】:

Eclipse 有一个内置选项来生成可运行的 jar,但它被很好地隐藏了。它也不能识别 Scala 的 main() 签名,所以你必须创建一个带有 main() 方法的 Java 类。

  1. 使用 main() 方法创建一个 Java 类,该方法只是将调用转发到您的 Scala 代码。

  2. 然后右键单击新创建的 Java 类并选择:运行方式 -> Java 应用程序。 这将创建一个可运行的配置,稍后将用作可运行 jar 的一部分。

  3. 现在您已准备好从 Eclipse 的菜单中挖掘出可运行的 jar 选项: 文件 -> 导出 -> Java -> 可运行的 JAR 文件

  4. 在显示的对话框中选择您之前创建的启动配置(在步骤 2 中),命名您的 jar (myapp.jar),选择您的依赖项导出选项并单击完成。

  5. jar 默认会在 Eclipse 的工作区中创建。

  6. 使用以下行运行 jar:scala myapp.jar

您关于丢失图像的问题:添加或删除文件时,Eclipse 需要手动刷新。右键单击您的项目并选择刷新。

关于高度直观的 Eclipse 界面的教程到此结束。

注意:Eclipse 版本 3.6.2 的说明。

【讨论】:

  • 谢谢,但它不起作用....我创建了一个带有 main() 的 java 类。然后创建了 .jar,当我想启动 jar 时,我的应用程序的名称出现在菜单和终端上我有这个错误:“lang.ClassNotFoundException: scala.ScalaObject”和“java.lang.reflect.InvocationTargetException”当我想用这条线启动时:scala myapp.jar 我有这个错误“Permission denied”
  • 我在 Scala 上安装了一个新版本,这是因为我有错误“权限被拒绝”,但现在我有一行:scala myapp.jar 这个错误:错误:解码时出现 IO 错误/Users/danymorard/Documents/workspace/myAppl1.jar with UTF-8
  • 自 Scala 2.9.0 起支持使用“scala myapp.jar”启动 jar。看起来您安装了一个旧版本,它试图将 jar 作为脚本文件加载。尝试使用“java -cp $SCALA_HOME/lib/scala-library.jar:myapp.jar mypackage.Mymain”启动jar
【解决方案2】:

罐子

当您从类中创建一个 jar 时,该 jar 中可能不包含依赖项。运行该 jar 时,您需要将包含依赖项的 jar 放在类路径上(使用 -cp 切换到 java)。最重要的依赖是scala-library jar。当然,知道 NoClassDefFound 没有找到什么会有所帮助。

Sbt

使用 sbt 构建时,可能缺少您手动添加到 Eclipse 项目中的依赖项? (注意:我没有使用 sbt)。

Maven

我发现最清晰和最轻松的方法是单独使用 maven,或者可能是 maven + Intellij Idea(社区版免费)+ Scala 插件。工作非常顺利。

对于 maven,您需要稍微调整可用的 scala 原型,因为它引用的库不是最新版本,但除此之外它非常好。

这是我正在使用的pom.xmlhttps://gist.github.com/1096870

使用标准的maven文件夹结构(源根目录是src/main/scala)然后mvn package创建jar就好了。

【讨论】:

  • @Snoopy:不要说“谢谢”,但要为有帮助的答案投票。最能解决您的问题的那个(如果有的话)应该被标记为接受的答案。
【解决方案3】:

暂时使用以下步骤。但这不是完整的解决方案。最好为 Spark-Scala 组合使用 sbt build jar。 使用java类的临时解决方案,调用scala主类。 MainClass.java

public class MainClass {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        app.main(args); }
}

SampleApp.scala

class SampleApp {
   def main(args: Array[String]) {  
     println("First Scala SampleApp")}  
}

通过选择 MainClass 主方法,使用普通的 java jar 导出将其导出为 jar。 将 jar 文件命名为 Sample.jar 使用以下命令在集群中运行它。

/spark/bin/spark-submit --class com.scala.MainClass SampleScala.jar

您可以获得的输出如下: 第一个 Scala SampleApp

【讨论】:

  • 这是为我做的。 Eclipse 无法识别 Scala 主文件,真是太烦人了!
  • 另外请注意,我创建了一个新的 Java 项目并添加了 Scala 库,如下所示:*.com/questions/11413888/…
【解决方案4】:
% cat a.scala 
package foo

object Whee {
  def main(args: Array[String]): Unit = {
    println("I'm in a jar")    
  }
}
% scalac29 -d whee.jar a.scala 
% scala29 -cp whee.jar foo.Whee
I'm in a jar
%

【讨论】:

  • 想知道答案,但我不明白你在做什么
  • 这不会为你创建一个可运行的 jar。它仅将您的代码压缩到 jar 文件中。要使其可运行,您需要在清单中定义主类。
【解决方案5】:

以@Kumar Basapuram 所写的内容为基础:

创建一个名为“Wrapper.java”的 java 类。

package animals;
public class Wrapper {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        app.main(args);
    }
}

将此主方法链接到“SampleApp.scala”类中的主方法。

package animals
class SampleApp {
  def main(args: Array[String]){
     var c = new Cow("Bessie", 100)
     println(c.speak)
     var h = new Horse("CJ", 50)
     println(h.speak)
     var s = new Sheep("Little Lamb", 25)
     println(s.speak)

     println(s.weigh)
     println(h.weigh)
     println(c.weigh)
  }
}

Project with Java and Scala Classes Picture

右键单击项目 ScalaPracticeCreation。 点击导出... 单击 Java 文件夹下的 Runnable JAR 文件 Exporting Scala Class into a jar Executable Picture

点击下一步>

选择包装器 - ScalaPracticeCreations

选择导出目的地到您计算机上的某个位置

在“Library”下选择“Extract required libraries into generated JAR” 处理:"选项

点击完成

通过 Eclipse IDE 运行该文件,它就可以工作了。

通过命令提示符运行它,它不起作用。 Command Prompt Picture

要解决此问题,请从“SampleApp.scala”中删除 println 方法。

package animals
class SampleApp {
  def main(args: Array[String]) {
    var c = new Cow("Bessie", 100)
    var h = new Horse("CJ", 50)
    var s = new Sheep("Little Lamb", 25)
    c.weigh().toString()
  }
}

添加“System.out.println(app.main(args));”替换“app.main(args);”在 Wrapper.java 类中

package animals;
public class Wrapper {
    public static void main(String[] args) {
        SampleApp app=new SampleApp();
        System.out.println(app.main(args));
    }
}

现在在运行程序后重新导出程序。 success in the command prompt Picture

现在可以了。

这里是额外的填充 .scala 类。请注意,Demo.scala 类是无关紧要的。

重量.scala:

package animals
abstract class Weight(size: Int) {
  def weigh = "My size is " + size
}

Animal.scala:

package animals
abstract class Animal(name: String, weight: Int) extends Weight(weight){
  def speak = name + " says " + sound
  def sound: String
  override def weigh() = "My name is " + name + " and I weigh: " + weight
}

Cow.scala:

package animals
class Cow (name: String, weight: Int) extends Animal(name,weight){
  override def sound() = "mooooo"
}

Horse.scala:

package animals
class Horse (name: String, weight: Int) extends Animal(name,weight){
  override def sound() = "neigh"
}

Sheep.scala:

package animals    
class Sheep (name: String, weight: Int) extends Animal(name,weight) {
  override def sound() = "baaaa"
}

请注意,尽管它是一种功能性解决方案,但它可能不是最佳解决方案。 Scala sbt 可能是一个更好的解决方案:Scala sbt 或这个Scala sbt-assembly

【讨论】: