6

The usual way of defining main in Scala (as shown below) can be used to run classes with 'scala', but not 'java' (since the created method is not static). How do I write a Scala class/object that can be executed with 'java'?

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello, world!")
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
IttayD
  • 28,271
  • 28
  • 124
  • 178
  • 1
    The question is incorrect in that assumes that you can't run this stuff with java, because the created method is not static. You can, and the created method is static. – Daniel C. Sobral Nov 15 '09 at 23:18

4 Answers4

7

javap will in fact show you that your main is static.

javap HelloWorld
Compiled from "HelloWorld.scala"
public final class HelloWorld extends java.lang.Object{
    public static final void main(java.lang.String[]);
    public static final int $tag()  throws java.rmi.RemoteException;
}

Perhaps you just need the Scala jars on your classpath?

There is a similar question here on Stack Overflow: "Creating a jar file from a Scala file".

I just verified this works with the instructions (linked) above.

Just run via:

java -jar HelloWorld.jar
Community
  • 1
  • 1
Shaun
  • 3,928
  • 22
  • 21
7

You are incorrect. You can run it with "java", and the reason you gave for not being possible is not true. Here, let me show what is inside "scala".

Unix:

#!/bin/sh
...
exec "${JAVACMD:=java}" $JAVA_OPTS -cp "$TOOL_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Denv.emacs="$EMACS"  scala.tools.nsc.MainGenericRunner  "$@"

Windows:

@echo off
...
if "%_JAVACMD%"=="" set _JAVACMD=java
...
"%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" scala.tools.nsc.MainGenericRunner  %_ARGS%

However, if you happen to have a class with the same name defined, then there's a bug that might be affecting you, depending on the Scala version you are using.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Well, it indeed works for a toy example, in my code i have an object inside of a class and the resulting .class does not have a static main method. – IttayD Nov 16 '09 at 04:55
  • If you have an object inside of a class (as `class Foo{ object Bar{ def main(args: Array[String]) } }`) then I doubt this will work, for other reasons. – Ken Bloom Nov 16 '09 at 13:01
  • 1
    This is the bug Daniel was pointing to http://www.eishay.com/2009/05/scalas-main-issue.html – Ashwin Oct 18 '10 at 22:25
3

The simplest way, and the one I always use, is to define the object (as you did) but not a corresponding "companion" class. In that case, the Scala compiler will create a pair of classes, the one whose name is precisely the same as the object will contain static forwarding methods that, for the purposes of launcher entry points, are precisely what you need. The other class has the name of your object with a $ appended and that's where the code resides. Javap will disclose these things, if you're curious about details.

Thus your HelloWorld example will work as you want, allowing this:

% scala pkg.package.more.HelloWorld args that you will ignore

Randall Schulz

Randall Schulz
  • 26,420
  • 4
  • 61
  • 81
0

Did you happen to also define a class HelloWorld? There's a bug in Scala 2.7.x that prevents the static methods on the HelloWorld class from being generated when both object HelloWorld and class HelloWorld are defined.

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168