IttayD
IttayD

Reputation: 29123

Scala: defining main method that can be used by 'java'

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!")
  }
}

Upvotes: 6

Views: 6290

Answers (4)

Ken Bloom
Ken Bloom

Reputation: 58770

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.

Upvotes: 0

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297185

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.

Upvotes: 7

Shaun
Shaun

Reputation: 4018

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

Upvotes: 7

Randall Schulz
Randall Schulz

Reputation: 26486

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

Upvotes: 3

Related Questions