Last active
August 29, 2015 14:05
-
-
Save mpkocher/fd1bc03328bd0ac2dab3 to your computer and use it in GitHub Desktop.
Nashorn Experiments Scala + JS (Requires Oracle JDK1.8 )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function test(){ | |
/** Task Authors should write unittest-esque tests to validate | |
* the tasks are well-formed | |
* | |
*/ | |
return(true); | |
} | |
function exampleTask(taskId) { | |
var taskClass = Java.type("com.github.mpkocher.Task"); | |
var t = new taskClass(taskId, "Task Description"); | |
return(t); | |
} | |
function toCmd(inputFiles, outputFiles, specials, opts, nproc) { | |
/** | |
* This is just to experiment with passing java objects to js | |
* | |
* In the real system, a Task would implement the abstract toCmd method | |
* which has the signature (inputFiles, outputFiles, specials, opts, nproc) | |
* | |
* Adds two numbers | |
* @param {Array} inputFiles | |
* @param {Array} outputFiles | |
* @param {Array} specials (e.g, $tmpdir, $tmpfile | |
* @param {Object} opts (HashMap of k->v of resolved option values) | |
* @param {Number} nproc the number of processors/slots to allocate | |
* @return {String} cmd | |
*/ | |
print("Paths in javascript:"); | |
print(inputFiles); | |
print(Object.prototype.toString.call(inputFiles)); | |
print(inputFiles.getClass()); | |
print(opts); | |
var cmd = "my_exe"; | |
cmd += " --optionA=12 --optionB=stuff "; | |
cmd += " --tmpdir=" + specials['1'] + "--tmpfile=" + specials['0']; | |
cmd += " --output=" + outputFiles['1'] + " " + outputFiles['0']; | |
cmd += " " + inputFiles['0'] + ' --reference=' + inputFiles['1']; | |
print(cmd); | |
return(cmd); | |
} | |
function registeredTasks() { | |
/* | |
These are the main public methods/funcs that are core the API | |
The task author should also implement a 'test' function | |
The scala code or the javascript UI code expects these funcs to be implemented. | |
*/ | |
var taskClass = Java.type("com.github.mpkocher.Task"); | |
var t1 = new taskClass("task1", "task one description"); | |
var t2 = new taskClass('task2', "task two description"); | |
return([t1, t2]); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> run | |
[info] Running com.github.mpkocher.Program | |
Number of factory | |
3 | |
Oracle Nashorn | |
ECMAScript | |
Scala Interpreter | |
Scala | |
AppleScriptEngine | |
AppleScript | |
jdk.nashorn.api.scripting.NashornScriptEngine@208180ea | |
Hello Hello From Javascript | |
12 | |
Paths in javascript: | |
[/path/to/input.fofn, /path/to/reference.fasta] | |
[object java.util.ArrayList] | |
class java.util.ArrayList | |
{task_option_id2=value2, task_option_id1=value1} | |
my_exe --optionA=12 --optionB=stuff --tmpdir=/path/to/tmpdir1--tmpfile=/path/to/tmp.file.txt --output=/path/to/file2.fasta /path/to/file.fofn /path/to/input.fofn --reference=/path/to/reference.fasta | |
Command | |
my_exe --optionA=12 --optionB=stuff --tmpdir=/path/to/tmpdir1--tmpfile=/path/to/tmp.file.txt --output=/path/to/file2.fasta /path/to/file.fofn /path/to/input.fofn --reference=/path/to/reference.fasta | |
Task id: taskId.1234 | |
description: Task Description | |
Load tests | |
true | |
[object Array] | |
Task id: taskId1 | |
description: My Task 1 description | |
Exiting main. | |
[success] Total time: 0 s, completed Sep 1, 2014 9:23:57 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.mpkocher | |
import java.io.IOException | |
import java.nio.charset.Charset | |
import java.nio.file.Files | |
import java.nio.file.Paths | |
import java.util | |
import java.util.List | |
import java.util.ArrayList | |
import javax.script.ScriptEngineFactory | |
import javax.script.ScriptEngineManager | |
import javax.script.ScriptEngine | |
import javax.script.ScriptException | |
import java.io.FileReader | |
import com.github.mpkocher.Task | |
object Program extends App { | |
override def main(args: Array[String]): Unit = { | |
// create ScriptEngineManager | |
// http://stackoverflow.com/questions/23567500/how-to-use-scriptengine-in-scalatest/23575337#23575337 | |
// sbt has an odd value for the class path | |
val manager: ScriptEngineManager = new ScriptEngineManager(getClass.getClassLoader) | |
// Print all the scriptengines that installed | |
val factoryList: util.List[ScriptEngineFactory] = manager.getEngineFactories | |
println("Number of factory") | |
println(factoryList.size()) | |
// This automatically converts types for java types | |
import scala.collection.JavaConversions._ | |
for (factory <- factoryList) { | |
println(factory.getEngineName) | |
println(factory.getLanguageName) | |
} | |
val engine = manager.getEngineByName("nashorn") | |
println(engine) | |
engine.eval(new FileReader("/Users/mkocher/scratch/js-scriptengine-example/src/main/resources/example_tasks.js")) | |
val invocable = engine.asInstanceOf[javax.script.Invocable] | |
// val outputFiles = Seq("/path/to/file.fofn", "/path/to/file2.fasta") | |
// Not sure why this doesn't work | |
// Have to use direct java objects to get objects to get passed directly | |
// otherwise a [object scala.collection.immutable.$colon$colon] | |
// class scala.collection.immutable.$colon$colon | |
// is passed to the js function | |
var inputFiles = new java.util.ArrayList[String]() | |
inputFiles.append("/path/to/input.fofn") | |
inputFiles.append("/path/to/reference.fasta") | |
var outputFiles = new java.util.ArrayList[String]() | |
outputFiles.append("/path/to/file.fofn") | |
outputFiles.append("/path/to/file2.fasta") | |
// These should be the resolved options | |
var opts = new java.util.HashMap[String, String] | |
opts.put("task_option_id1", "value1") | |
opts.put("task_option_id2", "value2") | |
// Assume DI specials is ['$tmpfile', '$tmpdir'] | |
var specials = new java.util.ArrayList[String]() | |
specials.append("/path/to/tmp.file.txt") | |
specials.append("/path/to/tmpdir1") | |
val nproc = java.lang.Integer.parseInt("12") | |
println(nproc) | |
// This is the fundamental signature of calling a task.toCmd func | |
// Passing nproc as an int won't automatically get converted for some reason. | |
val cmd = invocable.invokeFunction("toCmd", inputFiles, outputFiles, specials, opts, "12") | |
println("Command") | |
println(cmd) | |
// Raw Java task creation | |
val t = new Task("taskId1", "My Task 1 description") | |
// Access an instance of java class defined in javascript | |
val jsTask = invocable.invokeFunction("exampleTask", "taskId.1234") | |
println(jsTask) | |
// Call test Method. The task author should implement a unittest-esque method in javascript to make sure | |
// their tasks are well defined | |
val runTests = invocable.invokeFunction("test", Nil) | |
val isValid = runTests.asInstanceOf[Boolean] | |
println("Load tests ") | |
println(isValid) | |
// Load all registered tasks. This should return a list of Task instances | |
val ts = invocable.invokeFunction("registeredTasks", Nil) | |
println(ts) | |
// Not sure why this doesn't work. | |
//val tasks = ts.asInstanceOf[Seq[Task]] | |
//println(tasks) | |
println(t) | |
println("Exiting main.") | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.mpkocher; | |
import java.util.ArrayList; | |
public class Task { | |
// Making this as minimal as possible to get the point across. | |
public String taskId; | |
public String description; | |
public Task(String ataskId, String adescription) { | |
taskId = ataskId; | |
description = adescription; | |
} | |
@Override | |
public String toString() { | |
return "Task id: " + taskId+ " \ndescription: " + description + "\n\n"; | |
} | |
// Need an abstract method for the toCmd(ArrayList<String>) -> String | |
public String toCmd(ArrayList<String> paths) { | |
return "my exe.sh"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment