X

Sundararajan's Weblog

  • Java
    November 10, 2015

Dynamic linker API for the Java platform (JEP 276)

JEP 276 defines dynamic linker API for Java. This JEP provides "facility for linking high-level operations on objects such as "read a property", "write a property", "invoke a callable object", etc., expressed as names in INVOKEDYNAMIC call sites. Provide a default linker for the usual semantics of these operations on plain Java objects, as well as a facility for installing language-specific linkers.

Nashorn JavaScript engine already uses "dynalink" library for linking properties, indexed access, calls on it's (script) objects as well as "foreign"/"host" Java objects (POJOs). With JEP-276, dynalink is exposed as a public (JDK specific) API in the java9 module named "jdk.dynalink".

Right now, the source code for JEP-276 lives in "jdk9 sandbox" OpenJDK repository (http://hg.openjdk.java.net/jdk9/sandbox) in the branched named "JEP-276-branch". This will eventually go into jdk9 repository. If you want to play with "dynalink" API, you can check out this forest and build "JEP-276-branch"

To play with any Java API, these days I use "jshell" (jshell) tool. The following is a jshell repl sample to demonstrate dynalink API from Java code.


import java.lang.invoke.*
// dynalink API lives in these packages
import jdk.dynalink.*
import jdk.dynalink.support.*
// dynamic 'operation' for a callsite. 'length' property
Operation op = new NamedOperation(StandardOperation.GET_PROPERTY, "length")
// method type of operation to be linked - length is 'int' value
MethodType mt = MethodType.methodType(int.class, Object.class)
// callsite descriptor
CallSiteDescriptor desc = new CallSiteDescriptor(MethodHandles.publicLookup(),
op, mt)
// callsite
SimpleRelinkableCallSite cs = new SimpleRelinkableCallSite(desc)
// create a linker factory
DynamicLinkerFactory fac = new DynamicLinkerFactory()
// create dynalink linker
DynamicLinker linker = fac.createLinker()
// link the callsite
linker.link(cs)
// invoke it!
printf("array size %d\n", (int)cs.getTarget().invoke(new String[10]))
import java.util.ArrayList
// make a list and populate two elements
ArrayList<String> al = new ArrayList<>()
al.add("hello")
al.add("world")
// get 'length' of array list - which is nothing but size
printf("list size %d\n", (int)cs.getTarget().invoke(al))

The above repl prints "array size 10" and "list size 2" respectively. Note that "length" property is relinked automatically to be array length and then ArrayList size (when a different "this" object is passed). This linking (and relinking) of Java objects is handled by the "java beans linker" that comes with the dynalink implementation.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.