Scala无法运行已编译的类,但直接运行它

时间:2012-10-09 18:30:08

标签: java scala jvm

TL; DR:当我使用第一个变体时,REPL运行对象很好,但是当我用包测试替换import test._以便编译时,一切,甚至成功编译的代码都无法运行。

我有一个用Scala编写的简单Hello World应用程序:

import test._
object TestApp {
  def main (args: Array[String]) {
    val p = new HelloWorldPrinter
    p.output()
  }
}

HelloWorldPrinter.output()方法只是println("Hello World");

当我使用scala TestApp.scala运行应用程序时,它可以工作并输出Hello World,但是,当我在其上运行fsc或scalac进行编译时,它会生成相同包名“test”的子文件夹并放置TestApp。在那里上课。然后,如果我运行scala test/TestApp它不起作用并抛出此错误:

Exception in thread "main" java.lang.RuntimeException: Cannot figure out how to run target: test/TestApp
    at scala.sys.package$.error(package.scala:27)
    at scala.tools.nsc.GenericRunnerCommand.scala$tools$nsc$GenericRunnerCommand$$guessHowToRun(GenericRunnerCommand.scala:38)
    at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
    at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
    at scala.Option.getOrElse(Option.scala:108)
    at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:48)
    at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:17)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:33)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

但是,如果我cd进入“test”从那里运行编译的类,我会得到一个完全不同的错误:

Exception in thread "main" java.lang.NoClassDefFoundError: TestApp (wrong name: test/TestApp)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.scala$tools$nsc$util$ScalaClassLoader$$super$findClass(ScalaClassLoader.scala:88)
    at scala.tools.nsc.util.ScalaClassLoader$class.findClass(ScalaClassLoader.scala:44)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.findClass(ScalaClassLoader.scala:88)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.scala$tools$nsc$util$ScalaClassLoader$$super$loadClass(ScalaClassLoader.scala:88)
    at scala.tools.nsc.util.ScalaClassLoader$class.loadClass(ScalaClassLoader.scala:50)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.loadClass(ScalaClassLoader.scala:88)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at scala.tools.nsc.util.ScalaClassLoader$$anonfun$tryClass$1.apply(ScalaClassLoader.scala:37)
    at scala.tools.nsc.util.ScalaClassLoader$$anonfun$tryClass$1.apply(ScalaClassLoader.scala:37)
    at scala.util.control.Exception$Catch$$anonfun$opt$1.apply(Exception.scala:104)
    at scala.util.control.Exception$Catch$$anonfun$opt$1.apply(Exception.scala:104)
    at scala.util.control.Exception$Catch.apply(Exception.scala:88)
    at scala.util.control.Exception$Catch.opt(Exception.scala:104)
    at scala.tools.nsc.util.ScalaClassLoader$class.tryClass(ScalaClassLoader.scala:36)
    at scala.tools.nsc.util.ScalaClassLoader$class.tryToLoadClass(ScalaClassLoader.scala:31)
    at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.tryToLoadClass(ScalaClassLoader.scala:88)
    at scala.tools.nsc.util.ScalaClassLoader$.classExists(ScalaClassLoader.scala:120)
    at scala.tools.nsc.GenericRunnerCommand.scala$tools$nsc$GenericRunnerCommand$$guessHowToRun(GenericRunnerCommand.scala:34)
    at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
    at scala.tools.nsc.GenericRunnerCommand$$anonfun$2.apply(GenericRunnerCommand.scala:48)
    at scala.Option.getOrElse(Option.scala:108)
    at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:48)
    at scala.tools.nsc.GenericRunnerCommand.<init>(GenericRunnerCommand.scala:17)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:33)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

是什么给出了?

编辑:

这是我的TestApp.scala对象:https://gist.github.com/3863344

这是我的Printers.scala课程:https://gist.github.com/3863348

使用fsc编译后运行scala test/TestApp给出了第一个错误。输入test子文件夹并运行scala TestApp会出现第二个错误。在主文件夹中运行scala TestApp.scala给我这个:

TestApp.scala:1: error: illegal start of definition
package test
^
one error found

编辑2:我刚发现REPL无法使用包声明运行代码,所以我理解为什么会出现上述错误。但是,我仍然无法运行我的编译代码。

1 个答案:

答案 0 :(得分:1)

尝试从主文件夹中运行已编译的代码scala test.TestApp(在运行已编译的类scala的情况下,接受类名作为其参数,而不是文件名)。

Scala(就像java一样)有一个搜索类的位置列表 - 名为 classpath 。默认情况下,该位置设置为当前目录。然后,对于给定的课程packageX.packageY.ClassName,它会搜索相应的.class文件packageX/packageY/ClassName.class。因此,如果您运行没有显式类路径的scala test.TestApp,它将找到已编译的文件test/TestApp.class并运行它。