Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Better Taste, Less Filling: JS in your JVM with Hegemon

Better Taste, Less Filling: JS in your JVM with Hegemon

Video at: http://www.youtube.com/watch?v=YwnOst7Fplc

Abstract:

JVM developers need not be held hostage by the Java language. JavaScript for the JVM is available, but making it a first class member of your application can be tricky.

This talk will focus on libraries, tools, and techniques that the team at Cue (cueup.com) uses to make JavaScript in Java fun, easy, and efficient.

You’ll learn how to use JS 1.8 in your runtime, update applications without recompiling, run JUnit backed JS tests with just a browser reload, and provide an interactive console in your application.

Kevin Clark

October 26, 2012
Tweet

Other Decks in Programming

Transcript

  1. Better Taste, Less Filling: JS in your JVM with Hegemon

    github.com/Cue/hegemon Monday, January 14, 13
  2. public class FooResponse { final List<String> bars; @JsonCreator FooCommand(@JsonProperty("bars") List<String>

    bars) { this.bars = bars; } public List<String> getBars() { return this.bars; } } Monday, January 14, 13
  3. Running JavaScript Script script = new Script("function foo() { return

    3 + 4; }", LoadPath.defaultPath()); script.run("foo"); // returns 7 Monday, January 14, 13
  4. Running JavaScript Script script = new Script("function foo() { return

    3 + 4; }", LoadPath.defaultPath()); script.run("foo"); // returns 7 Monday, January 14, 13
  5. Running JavaScript Script script = new Script("function foo() { return

    3 + 4; }", LoadPath.defaultPath()); script.run("foo"); Monday, January 14, 13
  6. Loading Files new Script("function foo() { return definedInUtil(); }", LoadPath.defaultPath(),

    "util"); new Script(" load('util'); function foo() { return definedInUtil(); }", LoadPath.defaultPath(), 'hegemon/core'); Monday, January 14, 13
  7. Loading Files new Script("function foo() { return definedInUtil(); }", LoadPath.defaultPath(),

    "util"); new Script(" load('util'); function foo() { return definedInUtil(); }", LoadPath.defaultPath(), 'hegemon/core'); Monday, January 14, 13
  8. Loading Files new Script("function foo() { return definedInUtil(); }", LoadPath.defaultPath(),

    "util"); new Script(" load('util'); function foo() { return definedInUtil(); }", LoadPath.defaultPath(), 'hegemon/core'); Monday, January 14, 13
  9. Loading Files new Script("function foo() { return definedInUtil(); }", LoadPath.defaultPath(),

    "util"); new Script(" load('util'); function foo() { return definedInUtil(); }", LoadPath.defaultPath(), 'hegemon/core'); Monday, January 14, 13
  10. Caching Loads ScriptCache cache = new ScriptCache(LoadPath.defaultPath()); Script script =

    cache.get("myScript"); script.run("foo"); Monday, January 14, 13
  11. Caching Loads ScriptCache cache = new ScriptCache(LoadPath.defaultPath()); Script script =

    cache.get("myScript", true); script.run("foo"); Monday, January 14, 13
  12. @Path("/script/{name}") @Produces(MediaType.APPLICATION_JSON) public class ScriptResource { private static ScriptCache scriptCache

    = new ScriptCache(LoadPath.defaultPath()); @GET public Object post(@PathParam("name") String name, @Context UriInfo uriInfo) throws IOException, LoadError, ScriptException { Map<String, List<String>> params = uriInfo.getQueryParameters(); final Script script = scriptCache.get("script/" + name + ".js"); script.load("common"); Object paramsObject = script.run("getParamsAsObject", params); return script.run("GET", paramsObject); } } Monday, January 14, 13
  13. @GET public Object get(@PathParam("name") String name, @Context UriInfo uriInfo) throws

    ... { Map<String, List<String>> params = uriInfo.getQueryParameters(); Monday, January 14, 13
  14. final Script script = scriptCache.get("script/" + name + ".js"); script.load("common");

    Object paramsObject = script.run("getParamsAsObject", params); return script.run("GET", paramsObject); Monday, January 14, 13
  15. @Path("/eval") @Produces(MediaType.APPLICATION_JSON) public class EvalResource { @POST public Object post(String

    postBody) throws IOException, LoadError { final Script compiled = new Script("function run() { " + postBody + " }", LoadPath.defaultPath(), "hegemon/core"); return compiled.run("run"); } } Monday, January 14, 13
  16. load('script/example'); function testThatGETShouldReturnParams() { let params = {'foo': 'bar'}; let

    result = GET(params); Assert.assertEquals("GET", result.method); Assert.assertEquals(params, result.params); } Monday, January 14, 13
  17. public class ExampleJsTestServer extends HegemonTestServer { private static List<ScriptLocator> locatorsFromDirs(String

    ... sourceDirs) { List<ScriptLocator> dirs = Lists.newLinkedList(); for (String dir : sourceDirs) { dirs.add(new ExternalFromResourceScriptLocator(ExampleJsTestServer.class, dir)); } return dirs; } ExampleJsTestServer(String ... sourceDirs) { super(LoadPath.customPath(locatorsFromDirs(sourceDirs), Collections.<ScriptLocator>emptyList())); } public static void main(String[] args) throws Exception { HegemonTestServer.run( new ExampleJsTestServer( "../../src/main/resources/javascript", "../../src/test/resources/javascript"), 7070); } } Monday, January 14, 13
  18. public static void main(String[] args) throws Exception { HegemonTestServer.run( new

    ExampleJsTestServer( "../../src/main/resources/javascript", "../../src/test/resources/javascript"), 7070); } Monday, January 14, 13