Intellij - Run scala main file - scala

I have installed Scala plugin and sbt executer in IntelliJ.
I have created a new Scala project and it created a build.sbt file.
In the project setting/Libraries I see a reference to the SBT I have on my computer.
I created a new Scala class with the following code:
class RunMe {
def main(args: Array[String]): Unit = {
println("Hello from main of class")
}
}
I can't seem to find a new type of run configuration to create for the scala class.
I don't see the green play button in the left column (IntelliJ Left Gutter)
What am I missing?
How can I configure a run configuration in the code?

Instead of a class with a static method, which is what you do in Java, you should use object in Scala:
object RunMe {
def main(args: Array[String]): Unit = {
println("Hello from main of class")
}
}
You can also mixin a trait called App instead of providing the main method:
object RunMe extends App {
println("Hello from main of class")
}
In both cases IntelliJ should pick the definition fine and offer you the green arrow to start the app.

I usually just mixin the App trait into my Runner object. Something like...
object RunMe extends App {
println("Hello from main of class")
}
should do the trick. Intellij should now pickup that this object is "runnable" and provide a "play" button as expected.

Related

Why IntelliJ doesn't run my script if it has main in it

I am observing an interesting behavior. I have an existing project in which I created a folder and created a Scala script in that folder. To run it I did
Write a Scala script, e.g. MyScript.scala
In the menu select: Run -> Edit Configurations... Press the "+" (⌘N also works on the Mac in this dialog) Select "Scala Script" Then select your Script file in this dialog
Interestingly, if the script is the following then I get error Scala script not found
object HelloWorld{
def main(args:Array[String]): Unit ={
println("hello world");
}
}
but if the script is
def greetings(): Unit ={
println("hello")
}
greetings();
then it works!
Why IntelliJ cannot run the 1st version of the script?
You could do the following:
Run it as a script.
You have to use the following code:
class HelloWorld {
def main(args:Array[String]): Unit ={
println("hello world");
}
}
object Foo extends HelloWorld
Foo.main(args)
Hint: I removed the 'build' action from 'Before launch' to show the warnings further down.
Run it as an Application.
You can keep your code. Just select 'Application' when creating the configuration.
object HelloWorld{
def main(args:Array[String]): Unit ={
println("hello world");
}
}
Why?
You have to provide an entry point for the script. So you could use the following code:
object HelloWorld {
def main(args:Array[String]): Unit ={
println("hello world");
}
}
HelloWorld.main(args) //without this line, Script is not found!
But this gives an error (expected class or object definition):
An If you try to extend from App trait, you get 2 warnings:
object HelloWorld extends App {
override def main(args:Array[String]): Unit ={
println("hello world");
}
}
HelloWorld.main(args)
So I guess its best to use one of two Solutions above.

Eclipse scala "Could not find or load main class"

I have just started learning scala, i am using the eclipse ide for it, in the run configuration i have set scala application with the project name and as main class main when i compile i have
Error: Could not find or load main class main
when i check the console i see it's reading from Java/jre directory, is it normal or should i change that ?
This is the code
package one
class Main {
object Bottles {
def main(args: Array[String]){
var n : Int=2;
while(n<=6){
println(s"Hello ${n} bottles");
n+=1;
}
}
}
}
Okay, also had the same error Error: "Could not find or load main class main" in my Scala IDE and the reason of that was that when I created Main, I immediately moved it to a package.
So I had to:
Move my main class back to default package.
Clean, compile, run.
The main method needs to be on a toplevel object. Your Bottles object is wrapped in a Main class. Remove that Main class and your code should run.
object Bottles {
def main(args: Array[String]){
var n : Int=2;
while(n<=6){
println(s"Hello ${n} bottles");
n+=1;
}
}
}

Why args are compulsory for main

If I use like below considering I don't need to take arguments, it doesn't detect for Scala in eclipse.
object HelloWorld {
def main(): Unit = {
println("Hello Scala!!!")
}
}
It works fine with args: Array[String]
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello Scala!!!")
}
}
Well it's simply a convention on the JVM. You won't be able to invoke your object as entry point when running your program. For example, in Scala.js you have main() without arguments.
If you don't need the arguments you can mixin the App trait:
object HelloWorld extends App {
println("Hello Scala!!!")
}

Run menu item disappear in IntelliJ

I have scala code in IntelliJ as follows:
HelloWorld.scala
object HelloWorld {
//var matchExample = new MatchExample()
def main(args: Array[String]) = {
printHello()
//matchExample.oddEven(1)
}
def printHello() = {
println("hello")
}
}
MatchExample.scala
class MatchExample {
def oddEven(x: Int): String = {
"Hello"
}
}
If I un-comment those two lines and try to do run by right-clicking in object I don't have Run menu item, but if I comment out those two lines then I do have "Run" menu item.
What I am missing?
The reason is that your main method signature(un-comment matchExample.oddEven(1)) is incompatible with what Scala compiler requires for a runnable program.
Yours is (args: Array[String])String, the runnable program's main method signature is (args: Array[String])Unit. If you run your code in Terminal, compiler will emit a warning.
allen:Desktop allen$ scalac HelloWorld.scala
HelloWorld.scala:1: warning: HelloWorld has a main method with
parameter type Array[String], but HelloWorld will not be a runnable program.
Reason: main method must have exact signature (Array[String])Unit
object HelloWorld {
^
one warning found
In Scala, if you wanna write a runnable program, you'd better use App trait.
The post has a detailed explaination on Scala App val initialization in main method.

Scala println not working with App trait

When I use the scala App trait, I can't get println to work.
This simple example prints as expected,
object HelloWorld {
def main(args: Array[String]) {
println("Hello, world!")
}
}
But once I introduce the trait it does not,
object HelloWorld extends App {
println("Hello, world!")
}
I get no errors but nothing prints to the console.
Did you compile it first (running scalac HelloWorld.scala)? See this comment: http://www.scala-lang.org/node/9483#comment-40627
Edited to add more explanation:
The first version actually was compiled. Scala files without an explicit main method are run uncompiled as scripts. That means that for your second version, the commands in the file are run sequentially, as though they had been entered into the interpreter--so, the object HelloWorld is created, but no method is called on it. There's more information about Scala as a scripting language here (scroll to Step 5): http://www.artima.com/scalazine/articles/steps.html
Add a line
object HelloWorld extends App {
/* code */
}
HelloWorld.main(args)
at the end of your file.
The Class defines the method but it need to be called too.
According to
http://www.scala-lang.org/api/current/scala/App.html
you want to do
object Main extends App {
Console.println("Hello World: " + (args mkString ", "))
}