Executing Scala objects in Eclipse without a main method - eclipse

I have an assignment to code several methods in Scala. The methods will be encapsulated in an object that has no main method. The professor gave us a JAR file that contains an interface (my object implements this interface) as well as a sort of pseudo test object that performs various assert statements against each of my functions. This object also does not contain a main method.
Now in Intellij I simply had to declare the dependency on the JAR in the classpath, and it runs fine. Eclipse is giving me trouble though because when I go to define a Scala application run configuration it specifically asks me to name the class that contains a main method, and there is no main method.
I am assuming that I might be choosing the wrong project type for this type of set up, but I am inexperienced with this and I would appreciate any advice you might have for running something like this in eclipse.
Thanks.

I would either:
just write an object with a main method which calls the test object, or
start a Scala interpreter in your project (from context menu, under Scala).
Preferring the first approach, because it's faster to repeat tests after a modification.

Related

Scala project-wide static instructions

I'm using a Java lib within my Scala project. I want to call a specific static method adjustLib of that lib as early as possible and for every possible starting point of an execution (e.g. before runing the "main" App and before executing tests) to achieve the desired behaviour.
One solution would be to place this statement at the very top of each class, that might be executed (applies for all classes extending App and for all tests).
However, if someone implements a new, executable class but forgets adjustLib, things might get weird.
Is there any chance to define an object or something similar, that executes this adjustLib statement in a "static" manner every time anything in the given project is executed?

scala object extends app does not print anything

I am learning Scala and as part of the journey I had come across two different ways to write your scala class - one with a main method and other without the main method but by extending App (earlier Application is deprecated due to concurrency issues).
I am executing the scripts in Command Line via scala executable as scala <nameOfScript>.scala. I run Scala 2.11.7 in Windows.
I have no issues when running a scala script/class with a main method.
object ObjectWithMainMethod {
def main(args:Array[String]) = {
println("Object with a main() method executed..")
}
}
It produces the following output.
Object with a main() method executed..
But, I don't get the output with its counterpart, which is extending App trait but without the main method.
object AppWithoutMainMethod extends App {
println("AppWithout main() method executed")
}
When I run this scala script, it does not print anything. However, when I looked at the complied .class files via javap utility, I could see the PSVM (public static void main() method) inside.
Am I missing something? Any help on this will be highly appreciated.
If you run scala -help you'll see this comment:
A file argument will be run as a scala script unless it contains only
self-contained compilation units (classes and objects) and exactly one
runnable main method. In that case the file will be compiled and the
main method invoked. This provides a bridge between scripts and standard
scala source.
This explains exactly what you're seeing - the scala command is primarily meant to execute "scripts", or a series of expressions - for quick, interactive evaluation of code snippets. It only runs "applications" (i.e. objects with main method) as a "special case", because it makes sense users will try to use it this way. So:
When you run scala ObjectWithMainMethod.scala, the main method is identified and the command enters this "special case", figuring out that you probably meant for it to work that way
When you run scala AppwithoutMainMethod.scala, even though App has a main method, this isn't identified as the "special case" but just as a series of expressions, so the main method isn't invoked.
If you compile your classes into .class files and run them via java -cp <classpath> <class-name> command, the two will produce identical results.
The same thing works if I run the file without the .scala extension. I am not sure the reason behind this.
scala AppWithoutMainMethod
It produces the following output
AppWithout main() method executed

How to create a scala class based on user input?

I have a use case where I need to create a class based on user input.
For example, the user input could be : "(Int,fieldname1) : (String,fieldname2) : .. etc"
Then a class has to be created as follows at runtime
Class Some
{
Int fieldname1
String fieldname2
..so..on..
}
Is this something that Scala supports? Any help is really appreciated.
Your scenario doesn't seem to make sense. It's not so much an issue of runtime instantiation (the JVM can certainly do this with reflection). Really, what you're asking is to dynamically generate a class, which is only useful if your code makes use of it later on. But how can your code make use of it later on if you don't know what it looks like? For example, how would your later code know which fields it could reference?
No, not really.
The idea of a class is to define a type that can be checked at compile time. You see, creating it at runtime would somewhat contradict that.
You might want to store the user input in a different way, e.g. a map.
What are you trying to achieve by creating a class at runtime?
I think this makes sense, as long as you are using your "data model" in a generic manner.
Will this approach work here? Depends.
If your data coming from a file that is read at runtime but available at compile time, then you're in luck and type-safety will be maintained. In fact, you will have two options.
Split your project into two:
In the first run, read the file and write the new source
programmatically (as Strings, or better, with Treehugger).
In the second run, compile your generated class with the rest of your project and use it normally.
If #1 is too "manual", then use Macro Annotations. The idea here is that the main sub-project's compile time follows the macro sub-project's runtime. Therefore, if we provide the main sub-project with an "empty" class, members can be added to it dynamically at compile time using data that the macro sees at runtime. - To get started, Modify the macro to read from a file in this example
Else, if you're data are truly only knowable at runtime, then #Rob Starling's suggestion may work for you as it did me. I'll share my attempt if you want to be a guinea pig. For debugging, I've got an App.scala in there that shows how to pass strings to a runtime class generator and access it at runtime with Java reflection, even define a Scala type alias with it. So the question is, will your new dynamic class serve as a type-parameter in Slick, or fail to, as it sometimes does with other libraries?

create a Scala script file in Eclipse

I am playing with Scala. What I need is just a brunch of function definitions, but in Eclipse I can only create .scala files for which a function def must be inside an object or class.
But I see a Scala script online, here, which does not use an object to wrap all the functions.
It is of course ok for me to use an object to wrap all my functions, but I am just wondering whether it is required. Thanks!
But I see a Scala script online, here, which does not use an object to wrap all the functions.
Note that in this case, the functions can't be called from other files (they are wrapped in an object with compiler-generated name when run). If you "need just a brunch of function definitions", this is likely not what you want :) AFAIK, Scala IDE doesn't support script files at the moment, but you could log a feature request here.
Yes, in Eclipse you need to wrap everything in an object or a class.
You can edit Scala scripts in Eclipse as long as you wrap the code in an object and avoid the Shebang. Just run the script with scala -i scriptName.scala -e "Main.main(args)" (providing you have the "bin" folder of scala distribution on your path).
foo.scala:
object Main extends App {
println ("foo")
}
To run it:
scala -i foo.scala -e "Main.main(args)"
To my knowledge it isn't possible to write functions or variables completely outside of scope. That said it is possible to write them outside of class/object definitions. You just have to wrap them in a package object. What's happening is basically that instead of tying the function/variable to a given class or object, you tie it to a package. Example:
package test
package object inside {
def hello = println("Hello from outer space!")
class Foo {
hello // call the function from the package
}
}
Now, when you construct Foo, you should get printed "Hello from outer space!".
Without knowing completely what I'm talking about, I could imagine that the script version you mentioned above works, because the script is being run in some kind of an environment. So imagine some class loading the script, then wrapping it into an object and the running it. That would imply a situation somewhat like the one above: the functions still "belong" to somewhere.

Error with Groovy AST transformations when cleaning project in Eclipse

I'm trying to work through groovy's Implementing Local AST Transformations tutorial, but whenever I clean my project I get this error in each file that has the #WithLogging annotation in it:
Groovy:Could not find class for Transformation Processor AC.LoggingASTTransformation declared by AC.WithLogging
So you have a package named "AC" that contains both "WithLogging.groovy" and "LoggingASTTransformation.groovy" classes? Does it also contain any classes that implement the "WithLogging" interface?
If so, I'd suggest you move the class(es) that use your annotation to a location outside of the annotation defining package (the default will suffice, for diagnostic purposes) - Order of compilation matters with transformations. See this post on the groovy users mailing list for more on that.
Also try changing the annotation from #WithLogging to #AC.WithLogging.
As far as cleaning with Eclipse is concerned, I had a similar issue and found that I had to make a trivial modification after a clean to any file that contained my annotation. IE, add a space somewhere. Then save the file. This should rebuild everything properly.