Coder Social home page Coder Social logo

quack's Introduction

Quack

Quack provides Java (Android and desktop) bindings to JavaScript engines.

Runtimes

Quack supports both the Duktape and QuickJS runtimes.

Features

  • Share objects between runtimes seamlessly.
  • Javascript Debugging support
  • Invocations can be intercepted and coerced both in and out of the JavaScript runtime.

Examples

Evaluating JavaScript

JavaScript

'hello'

Java:

Calling QuackContext.evaluate will return a Java Object with the evaluation result.

QuackContext quack = QuackContext.create();
Object result = quack.evaluate(javascriptString);
System.out.println(result);
// prints "hello"

Evaluating and Calling JavaScript Functions

JavaScript

(function () {
  return 'hello';
})

Java

QuackContext quack = QuackContext.create();
JavaScriptObject result = quack.evaluateForJavaScriptObject(javascriptString);
System.out.println(result.call());
// prints "hello"

Passing Data to JavaScript

JavaScript

(function (str) {
  return str + ' world';
})

Java

QuackContext quack = QuackContext.create();
JavaScriptObject result = quack.evaluateForJavaScriptObject(javascriptString);
System.out.println(result.call("hello"));
// prints "hello world"

Setting and using Global Properties

JavaScript

System.out.println('hello world');

Java

QuackContext quack = QuackContext.create();
quack.getGlobalObject().set("System", System.class);
quack.evaluate(javascriptString);
// prints "hello world"

Passing Objects to JavaScript

JavaScript

(function(obj) {
  obj.hello();
})

Java

class Foo {
  public void hello() {
    System.out.println("hello");
  }
}

QuackContext quack = QuackContext.create();
JavaScriptObject result = quack.evaluateForJavaScriptObject(javascriptString);
quack.call(new Foo());
// prints "hello world"

Passing Interfaces to JavaScript

JavaScript

(function(func) {
  // notice that it is not func.run()
  // single method interfaces (lambdas) are automatically coerced into functions!
  func();
})

Java

Runnable runnable = () -> {
  System.out.println("hello world");
}

QuackContext quack = QuackContext.create();
JavaScriptObject result = quack.evaluateForJavaScriptObject(javascriptString);
result.call(runnable);
// prints "hello world"

Passing Interfaces back to Java

JavaScript

return {
  hello: function(printer) {
    printer('hello world');
  }
}

Java

interface Foo {
  void hello(Printer printer);
}

interface Printer {
  print(String str);
}

QuackContext quack = QuackContext.create();
Foo result = quack.evaluate(javascriptString, Foo.class);  
result.hello(str -> System.out.println(str));
// prints "hello world"

Creating Java Objects in JavaScript

JavaScript

var foo = new Foo();
foo.hello('hello world');

Java

class Foo {
  public void hello(String str) {
    System.out.println(str);
  }
}

QuackContext quack = QuackContext.create();
quack.getGlobalObject().set("Foo", Foo.class);
quack.evaluate(javascriptString);
// prints "hello world"

Creating Java Objects in JavaScript (simplified)

JavaScript

var Foo = JavaClass.forName("com.whatever.Foo");
var foo = new Foo();
foo.hello('hello world');

Java

class Foo {
  public void hello(String str) {
    System.out.println(str);
  }
}

QuackContext quack = QuackContext.create();
quack.getGlobalObject().set("JavaClass", Class.class);
quack.evaluate(javascriptString);
// prints "hello world"

Marshalling

Types need to be marshalled when passing between the runtimes. The class specifier and parameter types are used to determine the behavior when being marshalled. The following builtin types are marshalled as follows:

JavaScript (Input) Java (Output)
number Number (Integer or Double)
Uint8Array ByteBuffer (direct, deep copy)
undefined null
Java (Input) JavaScript (Output)
long string (otherwise precision is lost)
ByteBuffer (direct or byte array backed) Uint8Array (deep copy)
byte, short, int, float, double number
null null

Coercions

Types and methods can be coerced between runtimes.

Java to JavaScript Type Coercion

JavaScript

(function(data) {
  return data;
})

Java

class Foo {}

QuackContext quack = QuackContext.create();
// all instances of Foo sent to JavaScript get coerced into the String "hello world"
quack.putJavaToJavaScriptCoercion(Foo.class, (clazz, o) -> "hello world");
System.out.println(quack.evaluateForJavaScriptObject.call(new Foo()));
// prints "hello world"

Concurrency

JavaScript runtimes are single threaded. All execution in the JavaScript runtime is gauranteed thread safe, by way of Java synchronization.

Garbage Collection

When a Java object is passed to the JavaScript runtime, a hard reference is held by the JavaScript proxy counterpart. This reference is removed when the JavaScriptObject is finalized. And same for when a Java object is passed to the JavaScript runtime. JavaScriptObjects sent to the Java runtime will be deduped, so the same proxy instance is always used. JavaObjects sent to JavaScript will marshall a new Proxy object every time.

Debugging

Install the appropriate QuickJS Debugger or Duktape Debugger for VS Code. QuickJS is the default runtime used by Quack.

JavaScript

System.out.println('set a breakpoint here!');

Java

QuackContext quack = QuackContext.create();
quack.getGlobalObject().set("System", System.class);
quack.waitForDebugger("0.0.0.0:9091")
// attach using VS Code
quack.evaluate(javascriptString);

Square Duktape-Android

Quack was initially forked from Square's Duktape Android library. But it has been totally rewritten to suit different needs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.