简体   繁体   中英

Scala fails to run compiled class, but runs it directly

TL;DR: REPL runs object fine when I use the first variant, but everything, even successfully compiled code fails to run when I replace import test._ with package test in order to compile.

I have a simple Hello World app written in Scala:

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

The HelloWorldPrinter.output() method is just println("Hello World");

When I run the app with scala TestApp.scala it works and outputs Hello World, however, when I run fsc or scalac on it to compile, it produces a subfolder of the same package name "test" and puts TestApp.class in there. Then, if I run scala test/TestApp it doesn't work and throws this error:

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)

However, if I cd into "test" to run the compiled classes from there, I get a completely different error:

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)

What gives?

Edit:

This is my TestApp.scala object: https://gist.github.com/3863344

This is my Printers.scala class: https://gist.github.com/3863348

Running scala test/TestApp after compiling with fsc gives me the first error. Entering the test subfolder and running scala TestApp gives me the second error. Running scala TestApp.scala in the main folder gives me this:

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

Edit 2: I just found out that REPL cannot run code with package declarations, so I understand why the above error happens. I am still unable to run my compiled code, however.

Try running the compiled code as scala test.TestApp from the main folder (in the case of running compiled classes scala accepts class name as its argument, not a file name).

Scala (just as java) has a list of locations to search classes in - called classpath . By default, the location is set to the current directory. Then for given class packageX.packageY.ClassName it searches for the corresponding .class file packageX/packageY/ClassName.class . So if you run scala test.TestApp with no explicit classpath it locates the compiled file test/TestApp.class and runs it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM