Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

scala

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!")
  }
}
like image 373
IttayD Avatar asked Nov 15 '09 14:11

IttayD


3 Answers

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.

like image 159
Daniel C. Sobral Avatar answered Nov 15 '22 09:11

Daniel C. Sobral


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
like image 37
Shaun Avatar answered Nov 15 '22 08:11

Shaun


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

like image 34
Randall Schulz Avatar answered Nov 15 '22 09:11

Randall Schulz