NoSuchMethodException launching Scala App

This is a pretty standard thing to do in Java:

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

	public void start() {
		// do something
	}
}

So you reckon you’d be able to do this in Scala:

object App {
	def main(args: Array[String]) = {
		val app = new App()
		app.start()
	}
}

class App() {
	def start() = {
		// do something
	}
}

You go to run it and:
Exception in thread "main" java.lang.NoSuchMethodException: id.jakubkorab.App.main([Ljava.lang.String;)
at java.lang.Class.getMethod(Class.java:1605)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:107)

Turns out the Scala compiler doesn’t treat application launching in the same way that it treats other classes with companion objects. If you rename the object App to another name, it works.

object AppLauncher {
	def main(args: Array[String]) = {
		val app = new App()
		app.start()
	}
}

Go figure.


Posted

in

by

Tags:

Comments

4 responses to “NoSuchMethodException launching Scala App”

  1. James Strachan Avatar

    This is a side effect of how object’s get converted to bytecode. Since its a separate class in the JVM and if your object and class are the same names, the object class with the main has a different name (I think App$ though check).

    Incidentally you mean “val app = new App()” – def actually defines a function which returns a new App; its just with the universal access principle it looks like a variable

  2. Jake Avatar

    You’re right, mistyped 🙂 Corrected.

  3. Stephen Boesch Avatar
    Stephen Boesch

    I don’t get what you actually changed. In your second code fragment the object “App” is still same as the class. Pls clarify.(I’m asking since have same issue and interested in resolution).

    thanks

  4. Jake Avatar

    Must have missed the key detail when I updated the post last. Rename the object to another name, and you’re good to go. I have updated the post.