How to move main method to another class in Scala? - scala

IntelliJ IDEA 10.5 (probably this matters).
I am new to Scala, so I started in an akward way. I created one file with two classes -- empty MainApp and another class, HelloWorld with method main.
I compiled it and executed -- IntelliJ automatically detected HelloWorld as main class. It was OK.
Then, I moved main method to MainApp, and deleted (then empty) HelloWorld class. When I tried to run it, IntelliJ sticked to HelloWorld nevertheless. So I reconfigured project and selected MainApp as main class.
I tried to run it with such result:
MainApp main method should be static
I am completely puzzled. First of all, Scala does not have static methods. Second of all, why it does not compile now, when it compiled before (with HelloWorld class). I though that only requirement is having one main method.
Thank you in advance for your help.
Please note: I know I can start a new project from scratch to avoid the problem altogether, but I would like to learn something, i.e. get to know what is going on, and fixing this project.

static methods in Java roughly correspond to singleton methods in Scala. You should have
object MainApp {
def main(args : Array[String]) = ...
}
in your code, not class MainApp.

Related

eclipse does not list details about second class in outline, as well i can't put break point in the second class in the same file

I am trying to put a break point in a (any) method of TimerThread class. Its in java.util package .
Note that i don't have source code (is it because its JDK library and that's why source code not open source?) and i am using a decompiler(CFR) which shows me the decompiled code of the Timer.class in eclipse.
Timer.class has three classes in it.
public class Timer {
class TimerThread extends Thread {
class TaskQueue {
When i try to put breakpoint in any of the methods of the First class - Timer, i am able to put breakpoint.
But, for the second and third classes (TimerThread and TaskQueue), i can't put breakpoints in any of their methods. As well, eclipse does not list those two classes in the outline view.
Is there anything i can do to be able to put breakpoints in there?

Create a cheap new task class in Gradle

According to Groovy doc, Example 40.2, a new class for a task should be created so (simply copy that to the build.gradle):
task hello(type: GreetingTask)
class GreetingTask extends DefaultTask {
#TaskAction
def greet() {
println 'hello from GreetingTask'
}
}
But if you really try to do it, the class declaration is marked as an erroneous because no abstract methods are written. About ten of them should be here... Is it really impossible to do a task class in a cheap way as in documentation? What is the problem with documentation? Or rather with some settings on my IntelliJ?
You are using the wrong DefaultTask class. The one from Gradle is not abstract.
When I create the mentioned task in the empty Gradle/Groovy project, no errors is shown.
In the context of my project, the error IS shown. But the task runs OK! It again seems as some hallucination of IntelliJ.

Scala class decleration

I have used Scala but I worked with objects but now I have to use classes. I am creating a scala class in a package, however, when I try to run it, it asks me to choose between Scala Applet or Scala Application and none of them work. Anybody has an idea on how to fix this problem? And do you declare a main method inside a class (like in objects) ?
For running your application you need to have App extended object or an object with main method.
It is nice that you are using classes. But the entry point of your code must be an object with main method or ( App extended )
So use your classes to build the application but start your application from an object.
case class Test(val x: Int);
object Main extends App {
override def main(args: Array[String]): Unit = {
val x = Test(5);
println("this is the main method");
println(x);
}
}
In the JVM world, the main method in the entry point to an application.
In general, the main method is where you start your various components, the threads/executors that run them etc.

Scala object struggles with Java Class.newInstance()

UPDATE:
I have somewhat resolved the issue. Just in case if anyone runs in the same problem, here is the simplest solution: Looking at the MTApplcation source code, I have discovered that the initialize() method can be overloaded, taking a String parameter for the name of the class to instantiate. So if I create a separate class that extends MTApplication and pass it's name there, everything works correctly.
END OF UPDATE
I have a situation in Scala while trying to use a java library (MT4j, which is based on Processing). The library wants to instantiate the main class of the app (the caller-class):
Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(name);
applet = (PApplet) c.newInstance();
So as to refer it later in it's works.
However, it fails because, I guess, the main Scala class is not a class, but an object and due to library structure, it is necessary to call a static method initialize() of the main library class MTApplication. In Java static fields are located in classes, but in Scala - in objects. So it is impossible to instantiate an object and the library fails. In contrast to MT4j, Processing itself makes no calls to static methods on startup and successfully passes that phase.
If I just create a companion class, everything works fine except that the companion class does not get its fields initialized because the static initialize() method is called in companion object, the class instance just gets dead-born and the library becomes unusable.
At least that is how I understand this problem.
I get this error:
Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalAccessException: Class processing.core.PApplet can not access a member of class main.Main$ with modifiers "private"
at processing.core.PApplet.runSketch(PApplet.java:9103)
at processing.core.PApplet.main(PApplet.java:9292)
at org.mt4j.MTApplication.initialize(MTApplication.java:311)
at org.mt4j.MTApplication.initialize(MTApplication.java:263)
at org.mt4j.MTApplication.initialize(MTApplication.java:254)
at main.Main$.main(Main.scala:26)
at main.Main.main(Main.scala)
It is hard for me to explain also because I do not fully understand what is going on here. But anyone who has these libs can reproduce the situation in a couple of minutes, trying to launch the main class.
The abstract startUp() method which should be implemented to start the app, makes everything look even more sad. It initializes the object, but what the library tries to work with is an instance of the companion class which does not get initialized because in Scala the method belongs to the object.
My code:
object Main extends MTApplication {
def main(args: Array[String]) {
MTApplication.initialize()
new Main().startUp()
}
//this method is abstarct so it MUST be implemented,
override def startUp(){
}
}
class Main extends MTApplication {
override def startUp(){
//startup here
}
}
I am sorry if my explanations are vague, I just do not get it all completely. Probably to understand it is easier to repeat the experiment with MT4j library with Processing source code instead of the pre-linked 'core.jar' there to see what is happening inside. Doeas anyone have ideas on any workaround here?
Problem solved. Here is the solution:
object Main {
var current: MainC = _
def main(args: Array[String]) {
MTApplication.initialize("org.mttablescreen.main.MainC")
}
}
class MainC extends MTApplication {
//cons
Main.current = this
//cons ends
override def startUp(){
prepare
}
def prepare () {...}
}

Eclipse: how to update a JUnit test file with newly added method in the source file?

Using Eclipse (Helios), I could create a JUnit test file ClassATest.java of the source file ClassA.java by using New -> JUnit Test Case -> Class under test..., then choose all the methods of ClassA to be tested.
If later we add some more methods to ClassA, how do we easily reflect this addition in ClassATest ? (No copy/paste plz).
One solution is to use MoreUnit
With MoreUnit installed to Eclipse, one can right click onto the newly added method (and not yet unit tested), and choose "Generate Test"
Of course, if one always follows the writing-test-before-writing-method style, then this solution is not needed. However in reality sometimes you don't have a clear idea of what you would want to do, in that case you would have to code up some method, play with it, then rethink and code again until you are satisfied with the code and want to make it stable by adding unit test.
You should look into creating a JUnit test suite which will execute all tests within the classes you specify. Thus, adding new test cases is as simple as creating a new class and adding it to the #Suite.SuiteClasses list (as seen below).
Here's an example.
Example JUnit Test Suite Class:
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestClassFoo.class
})
public class ExampleTestSuite {}
Example Test Case class:
public class TestClassFoo {
#Test
public void testFirstTestCase() {
// code up test case
}
}