Not getting a result from SBTCookbook code from Play Framework - scala

Play Framework has, as part of their guides, this bit: https://www.playframework.com/documentation/2.5.x/SBTCookbook#Hooking-into-Plays-dev-mode
It describes the creation of a .scala file in the project/ folder, which allows you to execute some processes before starting the application in DEV mode.
So, I thought I'd try something simple like this:
import play.sbt.PlayRunHook
import sbt._
object Hello {
def apply(base: File): PlayRunHook = {
object HelloThere extends PlayRunHook {
override def beforeStarted(): Unit = {
Process("echo hello", base).run
}
}
HelloThere
}
}
File is saved as Hello.scala
But I'm not seeing anything in the console after running activator run. Am I doing something wrong? I did go to the localhost:9000 url in the browser to see if that caused the compilation of anything more, but no results from that either.
Using Play 2.5.8
I have no experience in Scala, only Java. Though there doesn't seem anything wrong with the code. It's just a copy paste with the object name replaced and the process text replaced.

Related

Is there a way to run a single benchmark with sbt-jmh?

I am working on a big sbt project and there is some functionality that I want to benchmark. I decided that I will be using jmh, thus I enabled the sbt-jmh plugin.
I wrote an initial test benchmark that looks like this:
import org.openjdk.jmh.annotations.Benchmark
class TestBenchmark {
#Benchmark
def functionToBenchMark = {
5 + 5
}
}
However, when I try to run it with jmh:run -i 20 -wi 10 -f1 -t1 .*TestBenchmark.* I get java.lang.InternalError: Malformed class name. I have freshly rebuilt the project and everything compiles and runs just fine.
The first printed message says
Processing 6718 classes from /path-to-repo/target/scala-2.11/classes
with "reflection" generator
I find it weird that the plugin tries to reflect the whole project (I guess including classes within the standard library). Before rebuilding I was getting NoClassDefFoundError, although the project was otherwise working well.
Since there are plenty of classes within the project and I cannot make sure that every little bit conforms to jmh's requirements, I was wondering if there's a way to overcome this issue and focus and reflect only the relevant classes that are annotated with #Benchmark?
My sbt version is 0.13.6 and the sbt-jmh version is 0.2.25.
So this is an issue with Scala and Class.getSimpleClassName.
Its not abonormal in Scala to have types like this:
object Outer {
sealed trait Inner
object Inner {
case object Inner1 extends
case object Inner2 extends Inner
}
}
With the above calling Outer.Inner.Inner1.getClass().getSimpleName() will throw the exception your seeing.
I don't think it uses the full project, but only for things that are directly referred to in the State or Benchmark.
Once I had my bench file written that way it worked.

Scala packages and importing

I have my very first scala program HelloWorld.scala which is located in ~/home/Jacobian/Projects/core/scala/ folder. Now I want to test the concept of packages and see how they can be imported/used. This is the code I have:
package Projects.core.scala
class HelloWorld{
private[scala] var greeting: String = "Hello from package"
}
That is. As you can see, I call my package Projects.core.scala just to reflect that I'm somewhere in /...very_long_path/Projects/core/scala/. I'm not sure what I'm doing wrong, but the problem is, when I compile my program with $ scalac HelloWorld.scala I get an error message:
error: '{' expected but ';' found
It's a funny error message, because I have no ';' in my code. If someone can show what I'm doing wrong, that would be great. But it would be even more useful, if someone could also share how this class HelloWorld wrapped in some arbitrary package (not necessary compatible with folders structure) can be imported. (PS. I'm reading Horstman book on Scala, but I can not figure out what can I do when it comes to a real world program and not to abstract concepts that are quite easy to understand)
FULL ERROR MESSAGE:
HelloWorld.scala:9: error: '{' expected but ';' found
class HelloWorld{
^ one error found
This error message pops up, when there are no parantheses and if I add
package Projects.core.scala {
class HelloWorld { ...
then the error goes away.
Importing issue
Now that I've wrapped class HelloWorld with parantheses and compiled the program, I see that there appeared some folder structure. So, it seems like now it should be quite easy to import the class and this is how I try to do that:
import Projects.core.scala.HelloWorld
object Test{
def main(args: Array[String]){
println("Hello from Test")
}
}
Test.scala is located right in the same folder where HelloWorld.scala and in this very folder I see Projects/core/scala/HelloWorld.class and other compiled files. However, when I try to compile now Test.scala, I get another error message:
Test.scala:3:error not found: object Projects
It is again very interesting - why it is trying to find an object, when I want it to import a class? And why does not it import this class? What other woodoo magic should take place?
File tree structure
HelloWorld.scala
Test.scala
Projects/core/scala/HelloWorld.class
And this is how Test.scala looks like:
import Projects.core.scala.HelloWorld._
object Test{
def main(args: Array[String]){
println("Hello from test")
}
}
I also tried import Projects.core.scala.HelloWorld and import Projects.core.scala._, but none of them work. I always get an error message:
error: not found: object Projects
EDIT
I added full path to Projects/core/scala/ to the CLASSPATH, but it does not help. Still, compiler is unable to import my custom class. I find it really frustrating, cos in Python or other languages that I know, it will take me a couple of second to do the trick, here I have to spend hours on such a miserable task - just importing a class. Gosh!

Run/Debug Config on IDEA 13 for Scala Application

complete stranger/newbie question, sorry to bother you:
I want to run a scala project in IDEA 13 (on Mac OSX), there is no run/debug configuration. I tried some options, however I don't know what to choose (and what should happen, then).
I tried:
Scala Console
Scala Script
Scala Test
Specs2
Choosing Scala Console: something happens, but I get no message box from my showMessage(message = "Hello World") messagebox. (It did work in Eclipse, so far).
Scala Script: I suppose this is meant for single lines of code, not an app, is that?
Specs2: Error in options-dialog: Specs2 is not specified. What is spec2? What should I enter and where? Error while debugging: no main class detected. OK, there is none, I can see that.
Any other option I should use, or normally is used?
Would any help appreciate very much!
This is my (very simple) scala app. Somehow, I'd expect to get an message box while running from IDEA.
import swing._
import swing.Dialog._
import scala.swing.event.ButtonClicked
object HW {
def main(args: Array[String]): Unit = {}
showMessage(message = "Hello World")
}
by the way: the closest tread I've found was this, but it didn't really help, looked too different:
How to run scala code on Intellij Idea 11?
Just use "Application". You have to select a main class and a module.
In terms of your example, I recommend not mixing a def main with a "free" standing constructor body. Also, Swing code should be called only from the event dispatch thread (Swing.onEDT). The easiest for desktop applications is to extend trait SwingApplication which handles that for you:
import swing._
import swing.Dialog._
object HW extends SwingApplication {
def startup(args: Array[String]): Unit =
showMessage(message = "Hello World")
}

eclipse does not treat a scalatest flatspec as junit test

here is my test case , while i right click the file eclipse doest not show any run as junit test option. I try to manual create run configuration but does not take any sense.
scala version:2.8.1 scalatest:1.3 eclipse:3.6.2
package org.jilen.cache.segment
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
#RunWith(classOf[JUnitRunner])
class RandomSegmentSpec extends FlatSpec with ShouldMatchers {
val option = SegmentOptions()
"A Simple Segment" should "contains (douglas,lea) after put into" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment("douglas") should be("lea")
}
it should "return null after (douglas,lea) is remove" in {
val segment = RandomSegment.newSegment(option)
segment.put("douglas", "lea")
segment -= ("douglas")
segment("douglas") should equal(null)
}
it should "contains nothing after clear" in {
val segment = RandomSegment.newSegment(option)
segment.put("jilen", "zhang")
segment.put(10, "ten")
segment += ("douglas" -> "lea")
segment += ("20" -> 20)
segment.clear()
segment.isEmpty should be(true)
}
}
I've encountered this seemingly randomly, and I think I've finally figured out why.
Unfortunately the plugin doesn't yet change package declarations when you move files, nor the class names when you rename files. (Given you can put multiple classes in one file, the latter will likely never be done.) If you are used to the renamings being done automagically in Eclipse, like I am, you're bound to get caught on this.
So... check carefully the following:
the package declaration in your Scala file matches the Eclipse package name
the name of the test class in the Scala file matches the name of the Scala file
I just ran into this, fixed both, and now my test runs!
This is a known problem with the Eclipse IDE for Scala. I'm currently working on the plugin for this. Watch this space.
I found Scalatest to be very bad at integrating with Eclipse (running the tests from eclipse showed that it ran them - but they would not pass or fail, but simply show up as passive blank boxes).
For some reason I could NOT get it to work after 3 hours of trying things!
Finally I tried specs2 - and it worked (Scala 2.9, Junit4 and Eclipse 3.6)!
They have a great doc here:
http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html#Runners+guide
Since I don't care which testing framework to use, I will try Specs2 purely from the convenience point of view.

How to reload a class or package in Scala REPL?

I almost always have a Scala REPL session or two open, which makes it very easy to give Java or Scala classes a quick test. But if I change a class and recompile it, the REPL continues with the old one loaded. Is there a way to get it to reload the class, rather than having to restart the REPL?
Just to give a concrete example, suppose we have the file Test.scala:
object Test { def hello = "Hello World" }
We compile it and start the REPL:
~/pkg/scala-2.8.0.Beta1-prerelease$ bin/scala
Welcome to Scala version 2.8.0.Beta1-prerelease
(Java HotSpot(TM) Server VM, Java 1.6.0_16).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Test.hello
res0: java.lang.String = Hello World
Then we change the source file to
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
but we can't use it:
scala> Test.goodbye
<console>:5: error: value goodbye is not a member of object Test
Test.goodbye
^
scala> import Test;
<console>:1: error: '.' expected but ';' found.
import Test;
There is an alternative to reloading the class if the goal is to not have to repeat previous commands. The REPL has the command
:replay
which restarts the REPL environment and plays back all previous valid commands. (The invalid ones are skipped, so if it was wrong before, it won't suddenly work.) When the REPL is reset, it does reload classes, so new commands can use the contents of recompiled classes (in fact, the old commands will also use those recompiled classes).
This is not a general solution, but is a useful shortcut to extend an individual session with re-computable state.
Note: this applies to the bare Scala REPL. If you run it from SBT or some other environment, it may or may not work depending on how SBT or the other environment packages up classes--if you don't update what is on the actual classpath being used, of course it won't work!
Class reloading is not an easy problem. In fact, it's something that the JVM makes very difficult. You do have a couple options though:
Start the Scala REPL in debug mode. The JVM debugger has some built-in reloading which works on the method level. It won't help you with the case you gave, but it would handle something simple like changing a method implementation.
Use JRebel (http://www.zeroturnaround.com/jrebel). JRebel is basically a super-charged class reloading solution for the
JVM. It can handle
member addition/removal, new/removed classes, definition changes, etc. Just about the only thing it can't handle is changes in class hierarchy (adding a super-interface, for
example). It's not a free tool, but they do offer a complementary license which is limited to Scala compilation units.
Unfortunately, both of these are limited by the Scala REPL's implementation details. I use JRebel, and it usually does the trick, but there are still cases where the REPL will not reflect the reloaded class(es). Still, it's better than nothing.
There is an command meet you requirement
:load path/to/file.scala
which will reload the scala source file and recompiled to classes , then you can replay you code
This works for me....
If your new source file Test.scala looks something like this...
package com.tests
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
You first have to load the new changes into Scala console (REPL).
:load src/main/scala/com/tests/examples/Test.scala
Then re-import the package so you can reference the new code in Scala console.
import com.tests.Test
Now enjoy your new code without restarting your session :)
scala> Test.goodbye
res0: String = Goodbye, Cruel World
If the .scala file is in the directory where you start the REPL you can ommit the full path, just put :load myfile.scala, and then import.