Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Scala Actors: examples from books not "acting" at all

Tags:

scala

actor

I'm very new to Scala, and too rusty in Java to consider myself anything else than a complete newbie. So I'm taking easy steps to learn it.

When looking at actors, I tried a few things, but faced many NoClassDefFound errors. Ultimately, I decided to take a book example and build on top of it instead of debugging my first attempt. Surprise: the book examples don't work as expected!

Here's the example from O'Reilly's Programming Scala:

import scala.actors.Actor

class Redford extends Actor {
  def act() {
    println("A lot of what acting is, is paying attention.")
  }
}

val robert = new Redford
robert.start

It's supposed, when executed, to print the Redford quote. However when I launch it, nothing happens, I get back to command line:

D:\prog\scala-2.8.1.final\pierric>scala testactors.scala

D:\prog\scala-2.8.1.final\pierric>

Another example comes from Seven Programming Languages in Seven Weeks. It's like this (I only changed the strings out of laziness):

import scala.actors._
import scala.actors.Actor._

case object Poke;
case object Feed;

class Kid() extends Actor {
    def act() {
        loop {
            react {
                case Poke => {
                    println("Ow")
                    println("Quit it")
                }
                case Feed => {
                    println("gurgle")
                    println("burp")
                }
            }
        }
    }
}

var bart = new Kid().start
var lisa = new Kid().start
println("starting")
bart ! Poke
lisa ! Poke
bart ! Feed
lisa ! Feed

This time it's supposed to return a randomly ordered sequence of "ow quit it" and "gurgle burp". However, when I run it:

D:\prog\scala-2.8.1.final\pierric>scala testkids.scala
starting

D:\prog\scala-2.8.1.final\pierric>

Now, another amusing thing. If I add a simple println line at the beginning of my act method:

class Kid() extends Actor {
    def act() {
        println("Kid initializing")
        loop {
            react {
                ...

Then I get most of the times:

D:\prog\scala-2.8.1.final\pierric>scala testkids.scala
starting
Kid initializing
Kid initializing

D:\prog\scala-2.8.1.final\pierric>

But sometimes also:

starting
Kid initializing
Kid initializing
scala.actors.Actor$$anon$1@5a9de6: caught java.lang.NoClassDefFoundError: Main$$anon$1$Fee
    java.lang.NoClassDefFoundError: Main$$anon$1$Feed$
            at Main$$anon$1.Main$$anon$$Feed(testkids.scala:5)
            at Main$$anon$1$$anonfun$1.apply$mcV$sp(testkids.scala:31)
            at scala.actors.Actor$$anon$1.act(Actor.scala:135)
            at scala.actors.Reactor$$anonfun$dostart$1.apply(Reactor.scala:222)
            at scala.actors.Reactor$$anonfun$dostart$1.apply(Reactor.scala:222)
            at scala.actors.ReactorTask.run(ReactorTask.scala:36)
            at scala.concurrent.forkjoin.ForkJoinPool$AdaptedRunnable.exec(ForkJoinPool.java:6
            at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
            at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.ja
            at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:32
    Caused by: java.lang.ClassNotFoundException: Main$$anon$1$Feed$
            at java.net.URLClassLoader$1.run(Unknown Source)

So here I am, clueless... as those are examples "out of the book", actually out of 2 books! and don't seem to work. I've tried on 2 different machines, which in all likeliness have different JVM's. In both cases I've run scala 2.8.1.final. One machine runs Windows XP 32-bit, the other one Windows 7 64-bit. I didn't find anything related to this kind of issue by googling...

Thanks in advance to anyone who can shed a light on this!

Pierric.

like image 200
Pierric Avatar asked Feb 25 '23 12:02

Pierric


1 Answers

This is because scala script running exits hard as soon as they are finished in the main thread. That works very bad in a setting with multiple threads (see Can Actors in Scala fail to process messages? (example in O'Reilly's Programming Scala)). If instead you start scala and load the scripts like this:

# scala
scala> :load testactors.scala
Loading testactors.scala...
import scala.actors.Actor
defined class Redford
robert: Redford = Redford@29e07d3e
res0: scala.actors.Actor = Redford@29e07d3e

scala> A lot of what acting is, is paying attention.
like image 168
thoredge Avatar answered Mar 05 '23 01:03

thoredge