diff options
author | michelou <michelou@epfl.ch> | 2010-11-17 12:26:13 +0000 |
---|---|---|
committer | michelou <michelou@epfl.ch> | 2010-11-17 12:26:13 +0000 |
commit | c09f6173e96ec741c9b38edfee969ae8c6b74d4e (patch) | |
tree | 1f06579f72afa12092acd0b5bbb7c678291cf619 /test/files/detach-run/actor | |
parent | 363a1456f671323b35dcacf2c8b8eb39180b8a53 (diff) | |
download | scala-c09f6173e96ec741c9b38edfee969ae8c6b74d4e.tar.gz scala-c09f6173e96ec741c9b38edfee969ae8c6b74d4e.tar.bz2 scala-c09f6173e96ec741c9b38edfee969ae8c6b74d4e.zip |
updates Scala examples, added detach plugin
Diffstat (limited to 'test/files/detach-run/actor')
-rw-r--r-- | test/files/detach-run/actor/Client.scala | 50 | ||||
-rw-r--r-- | test/files/detach-run/actor/Server.scala | 24 | ||||
-rw-r--r-- | test/files/detach-run/actor/ServerClassLoader.scala | 154 | ||||
-rw-r--r-- | test/files/detach-run/actor/ServerConsole.scala | 71 | ||||
-rw-r--r-- | test/files/detach-run/actor/actor.flags | 1 | ||||
-rw-r--r-- | test/files/detach-run/actor/actor.scala | 140 | ||||
-rw-r--r-- | test/files/detach-run/actor/java.policy | 25 |
7 files changed, 465 insertions, 0 deletions
diff --git a/test/files/detach-run/actor/Client.scala b/test/files/detach-run/actor/Client.scala new file mode 100644 index 0000000000..af1c26ee1b --- /dev/null +++ b/test/files/detach-run/actor/Client.scala @@ -0,0 +1,50 @@ +import scala.actors.Actor._, ClientHelper._ +import scala.actors.remote._, RemoteActor._ +import scala.remoting._, Debug._ + +object Foo { + def trace(msg: String) { info("[Foo.trace] "+msg)} +} +object Client { + val yInstVal: Int = 10 + var yInstVar: Int = 99 + object Bar { + def trace(msg: String) { info("[Bar.trace] "+msg) } + } + def main(args: Array[String]) { + init(args) + actor { + val server = select(Node(host, port), 'Server) + val zLocVal: Int = 1000 + var zLocVar: Int = 9998 + server ! detach( + (x: Int) => { + println("yInstVal = "+yInstVal) + this.trace("yInstVar = "+yInstVar) + Bar.trace("zLocVal = "+zLocVal) + Foo.trace("zLocVar = "+zLocVar) + zLocVar += 2 + System.out.println("zLocVal = "+zLocVal) + Debug.info("zLocVar = "+zLocVar) + x + yInstVal + yInstVar + zLocVal + zLocVar + }) + react { + case result: Int => + println("result received: " + result) + Predef.exit(0) + } + } + } + private def trace(msg: String) { info("[Client.trace] "+msg) } +} + +object ClientHelper { + private var _host = "127.0.0.1" + private var _port = 8888 + def host = _host + def port = _port + def init(args: Array[String]) { + try { _host = args(0) } catch { case _ => } + try { _port = args(1).toInt } catch { case _ => } + } +} diff --git a/test/files/detach-run/actor/Server.scala b/test/files/detach-run/actor/Server.scala new file mode 100644 index 0000000000..84df6f5d81 --- /dev/null +++ b/test/files/detach-run/actor/Server.scala @@ -0,0 +1,24 @@ +import scala.actors._, Actor._ +import scala.actors.remote._, RemoteActor._ +import scala.reflect.Manifest + +object Server extends ServerConsole { + private def computation(f: Int => Int): Int = { + //some time-consuming task + f(2) + } + def main(args: Array[String]) { + actor { + classLoader = serverClassLoader + alive(args(0).toInt) + register('Server, self) + loopWhile(isRunning) { + react { + case f: (Int => Int) => + val result = computation(f) + sender ! result + } + } + } + } +} diff --git a/test/files/detach-run/actor/ServerClassLoader.scala b/test/files/detach-run/actor/ServerClassLoader.scala new file mode 100644 index 0000000000..3f5d96a1a1 --- /dev/null +++ b/test/files/detach-run/actor/ServerClassLoader.scala @@ -0,0 +1,154 @@ +import java.io._ +import java.net.{JarURLConnection, URL, URLClassLoader} + +import scala.remoting.Debug + + private class ServerObjectInputStream(in: InputStream, cl: ClassLoader) + extends ObjectInputStream(in) { + override def resolveClass(cd: ObjectStreamClass): Class[_] = { + println("[ServerObjectInputStream] resolveClass "+cd.getName) + try { + Debug.info("load class "+cd.getName+" from "+cl) + val c = cl.loadClass(cd.getName) + Debug.info("loaded class "+c.getName) + c + } catch { + case cnf: ClassNotFoundException => + Debug.info("resolve class (this) "+cd.getName) + val c = super.resolveClass(cd) + Debug.info("resolve class (super) "+c.getName) + c + } + } + override def resolveProxyClass(interfaces: Array[String]): Class[_] = { + println("[ServerObjectInputStream] resolveProxyClass "+interfaces.toList) + try { + val c = cl.loadClass(interfaces.last) + Debug.info("loaded class "+c.getName) + c + } catch { + case cnf: ClassNotFoundException => + Debug.info("resolve proxy class (this) "+interfaces.last) + val c = super.resolveProxyClass(interfaces) + Debug.info("resolve proxy class (super) "+c.getName) + c + } + } + } +/* + // VARIANT 1 + class ServerClassLoader extends URLClassLoader(urls) { + import scala.reflect.Manifest + def load[A](a: Array[Byte])(implicit expected: Manifest[A]): A = { + val in = new ServerObjectInputStream(new ByteArrayInputStream(a), this) + val found = in.readObject.asInstanceOf[Manifest[_]] + if (! (found <:< expected)) + throw new ClassCastException("type mismatch;"+ + "\n found : "+found+ + "\n required: "+expected) + val o = in.readObject.asInstanceOf[A] + in.close() + o + } + override def findClass(name: String): Class[_] = { + println("[ServerClassLoader] findClass "+name) + val b = loadClassData(name) + if (b != null) defineClass(name, b, 0, b.length) + else super.findClass(name) + } + private def loadClassData(name: String): Array[Byte] = { + println("[ServerClassLoader] loadClassData "+name) + null + } + } + val serverClassLoader = new ServerClassLoader +*/ + +/* + class ServerClassLoader(parent: ClassLoader) extends URLClassLoader(urls, parent) { + import scala.reflect.Manifest + def load[A](a: Array[Byte])(implicit expected: Manifest[A]): A = { + val in = new ServerObjectInputStream(new ByteArrayInputStream(a), this) + val found = in.readObject.asInstanceOf[Manifest[_]] + if (! (found <:< expected)) + throw new ClassCastException("type mismatch;"+ + "\n found : "+found+ + "\n required: "+expected) + val o = in.readObject.asInstanceOf[A] + in.close() + o + } + override def findClass(name: String): Class[_] = { + println("[ServerClassLoader] findClass "+name) + val b = loadClassData(name) + if (b != null) defineClass(name, b, 0, b.length) + else super.findClass(name) + } + private def loadClassData(name: String): Array[Byte] = { + println("[ServerClassLoader] loadClassData "+name) + null + } + } +*/ +class ServerClassLoader(urls: Array[URL], parent: ClassLoader) +extends URLClassLoader(urls, parent) { + + private val cache = new collection.mutable.HashMap[String, Class[_]] + + for (url <- urls) { + val jarurl = new URL("jar:"+url+"!/") + val con = jarurl.openConnection().asInstanceOf[JarURLConnection] + val jar = con.getJarFile + val e = jar.entries + while (e.hasMoreElements) { + val ze = e.nextElement + val path = ze.getName + if (path endsWith ".class") { + val size = ze.getSize + val name = path.replace("/", ".").substring(0, path.length - 6) + cache += name -> this.loadClass(name) + println("[ServerClassLoader] added "+name+" ("+size+")") + } + };
//jar.close() + } + + override def findClass(name: String): Class[_] = { + println("[ServerClassLoader] findClass: name="+name) + cache get name match { + case Some(cl) => + println(name+" cached"); cl + case None => + println(name+" not cached"); super.findClass(name) + } + } + +} + +/* +try { + JarFile jarFile = new JarFile(srcPath); + Enumeration<JarEntry> entries = jarFile.entries(); + String url = "file:" + srcPath; + System.out.println(url); + URLClassLoader classLoader = new URLClassLoader( + new URL[] { new URL(url) }); + while (entries.hasMoreElements()) { + JarEntry jarEntry = (JarEntry) entries + .nextElement(); + String classPath = jarEntry.getName(); + if (classPath.endsWith(".class")) { + String className = classPath.replace("/", ".") + .substring(0, classPath.length() - 6); + try { + Class clazz = classLoader + .loadClass(className); + //Et là, tu fais ce que tu vexu avec la classe + } catch (ClassNotFoundException e1) { + e1.printStackTrace(); + } + } + } +} catch (IOException e1) { + e1.printStackTrace(); +} +*/ diff --git a/test/files/detach-run/actor/ServerConsole.scala b/test/files/detach-run/actor/ServerConsole.scala new file mode 100644 index 0000000000..f68274e927 --- /dev/null +++ b/test/files/detach-run/actor/ServerConsole.scala @@ -0,0 +1,71 @@ +import java.io._ + +import scala.compat.Platform.currentTime +import scala.remoting.Debug, Debug._ + +trait ServerConsole extends Thread { + private val startTime = currentTime + actors.Debug.level = // e.g. 3 // info+warning+error + try { System.getProperty("scala.actors.logLevel", "0").toInt } + catch { case e => 0 } + + start() + + val serverClassLoader = { + import java.rmi.server.RMIClassLoader + val codebase = System.getProperty("java.rmi.server.codebase") + info("[ServerConsole] codebase="+codebase) + RMIClassLoader.getClassLoader(codebase) + } + + private var isTerminated = false + + def terminate() { isTerminated = false } + + def isRunning = !isTerminated + + override def run() { + val in = new BufferedReader(new InputStreamReader(System.in)) + var quit = false + while (!quit) { + val args = getArgs(in) + if (args contains "quit") + quit = true + if (args contains "cls") { + println(ERASE_SCREEN) + println(CURSOR_HOME) + } + if (args contains "warning") + Debug.level = Level.WARNING + if (args contains "info") + Debug.level = Level.INFO + if (args contains "silent") + Debug.level = Level.SILENT + } + terminate() + println("Server exited ("+mkTimeString(currentTime - startTime)+")") + exit(0) + } + + protected def trace(msg: String) { + Debug.info("[ServerConsole.trace] "+msg) + } + + private def getArgs(in: BufferedReader): List[String] = { + val input = try { in.readLine() } catch { case _ => null } + if (input != null) (input.trim split "\\s+").toList else Nil + } + + private def mkTimeString(time: Long): String = { + def twoDigits(i: Long) = (if (i < 10) "0" else "")+i + val sec = time / 1000 + val min = sec / 60 + val h = min / 60 + twoDigits(h) +":"+ + twoDigits(min - h * 60)+":"+ + twoDigits(sec - min * 60) + } + + private val ERASE_SCREEN = "\033[2J" + private val CURSOR_HOME = "\033[H" +} diff --git a/test/files/detach-run/actor/actor.flags b/test/files/detach-run/actor/actor.flags new file mode 100644 index 0000000000..55eed8bbcd --- /dev/null +++ b/test/files/detach-run/actor/actor.flags @@ -0,0 +1 @@ +-Xpluginsdir ../../../../build/pack/misc/scala-devel/plugins -Xplugin-require:detach -P:detach:enable diff --git a/test/files/detach-run/actor/actor.scala b/test/files/detach-run/actor/actor.scala new file mode 100644 index 0000000000..0cf55462f6 --- /dev/null +++ b/test/files/detach-run/actor/actor.scala @@ -0,0 +1,140 @@ +object Test { + + val actors_logLevel = "0" + // = "3" // info+warning+error + val logLevel = "silent" + // = "info" // debug user code only + // = "info,lib" // debug user & library code + + // we assume an Apache server is running locally for deployment + private val sep = java.io.File.separator + val docPath = System.getProperty("user.home")+sep+"public_html" + val docRoot = "http://127.0.0.1/~"+System.getProperty("user.name") + + val host = "127.0.0.1" + val port = 8889 + + def main(args: Array[String]) { + setenv() + println("Server.main "+port) + Server.main(Array(port.toString)) + println("Client.main "+host+" "+port) + Client.main(Array(host, port.toString)) + Server.terminate() + } + + private def setenv() { + import java.io._, java.util.jar._ + + val policyTmpl = + System.getProperty("partest.cwd")+sep+"actor"+sep+"java.policy" + val outPath = System.getProperty("partest.output") + val libPath = System.getProperty("partest.lib") + val policyFile = outPath+sep+"java.policy" + val codebaseDir = outPath+sep+"-" + + assert((new java.io.File(docPath)).isDirectory, + "Root directory \""+docPath+"\" not found") + val deployJar = docPath+sep+"actor_deploy.jar" + val deployUrl = docRoot+"/actor_deploy.jar" + + // Java properties for server & client + System.setProperty("scala.actors.logLevel", actors_logLevel) + System.setProperty("scala.remoting.logLevel", logLevel) + System.setProperty("java.security.manager", "") + System.setProperty("java.security.policy", policyFile) + // Java properties for server only + System.setProperty("java.rmi.server.codebase", deployUrl) + System.setProperty("java.rmi.server.hostname", host) + System.setProperty("java.rmi.server.useCodebaseOnly", "true") + + val classNames = List( + "$anonfun$main$1$proxy", + "$anonfun$main$1$proxyImpl_Stub", + "Bar$proxy", + "Bar$proxyImpl_Stub", + "Client$$anonfun$main$1$$anonfun$apply$1$detach", + "Client$proxy", + "Client$proxyImpl_Stub", + "Foo$proxy", + "Foo$proxyImpl_Stub") + + val proxyImplNames = + for (n <- classNames; i = n lastIndexOf "_Stub"; if i > 0) + yield n.substring(0, i) + + generatePolicyFile() + generateRmiStubs(proxyImplNames) + generateJarFile(classNames) + + def generatePolicyFile() { + val in = new BufferedReader(new FileReader(policyTmpl)) + val out = new PrintWriter(new BufferedWriter(new FileWriter(policyFile))) + var line = in.readLine() + while (line != null) { + val line1 = line.replaceAll("@PROJECT_LIB_BASE@", codebaseDir) + out.println(line1) + line = in.readLine() + } + in.close() + out.close() + } + def exec(command: String) { + val proc = Runtime.getRuntime exec command + proc.waitFor() + val out = new BufferedReader(new InputStreamReader(proc.getInputStream)) + var line = out.readLine() + while (line != null) { + println(line) + line = out.readLine() + } + out.close() + val err = new BufferedReader(new InputStreamReader(proc.getErrorStream)) + line = err.readLine() + while (line != null) { + println(line) + line = err.readLine() + } + err.close() + } + + def ls(path: String) { exec("ls -al "+path) } + def rmic(options: List[String], classNames: List[String]) { + val javaHome = scala.util.Properties.javaHome + val jdkHome = + if (javaHome endsWith "jre") javaHome.substring(0, javaHome.length-4) + else javaHome + val rmicExt = if (scala.util.Properties.isWin) ".exe" else "" + val rmicCmd = jdkHome+sep+"bin"+sep+"rmic"+rmicExt + val cmdLine = rmicCmd+options.mkString(" ", " ", "")+ + classNames.mkString(" "," ","") + // println(cmdLine) + exec(cmdLine) + } + def generateRmiStubs(classNames: List[String]) { + val options = List( + "-v1.2", + "-classpath "+libPath+File.pathSeparator+outPath, + "-d "+outPath) + rmic(options, classNames) + //ls(outPath) + } + def generateJarFile(classNames: List[String]) { + val out = new JarOutputStream(new FileOutputStream(deployJar)) + classNames foreach (name => { + val className = name+".class" + out putNextEntry new JarEntry(className) + val in = new FileInputStream(outPath+sep+className) + val buf = new Array[Byte](256) + var len = in read buf + while (len != -1) { + out.write(buf, 0, len) + len = in read buf + } + in.close() + }) + out.close() + } + } +} + diff --git a/test/files/detach-run/actor/java.policy b/test/files/detach-run/actor/java.policy new file mode 100644 index 0000000000..4beb2ca26b --- /dev/null +++ b/test/files/detach-run/actor/java.policy @@ -0,0 +1,25 @@ +// See http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html +// See http://mindprod.com/jgloss/policyfile.html +// The policy expands ${/} to the correct path or folder delimiter on your host platform. + +// Actions available with SocketPermission: accept, connect, listen, resolve +// 1) The "resolve" action is implied when any of the other actions are present. +// 2) The "listen" action is only meaningful when used with "localhost". + +grant { + permission java.net.SocketPermission "*:80", "connect,accept,listen"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "scala.remoting.logLevel", "read"; + permission java.util.PropertyPermission "scala.remoting.port", "read"; +}; + +grant codeBase "@PROJECT_LIB_BASE@" { + permission java.lang.RuntimePermission "getClassLoader"; + permission java.util.PropertyPermission "java.rmi.server.codebase", "read"; + permission java.util.PropertyPermission "java.rmi.server.hostname", "read"; + permission java.util.PropertyPermission "sun.rmi.dgc.server.gcInterval", "read,write"; +}; +
+//grant { +// permission java.security.AllPermission; +//}; |