Package org.teavm.jso

Annotation Type JSBody


@Retention(RUNTIME) @Target(METHOD) public @interface JSBody

Indicates that method is to have native JavaScript implementation. Method only can take and return primitive values and JSObjects. Note that unless method is static, it must belong to class that implements JSObject. If applied to non-native method, original Java body will be overwritten by JavaScript.

Example:

    @JSBody(params = { "message" }, script = "window.alert(message);")
    public static native void alert(String message);
 

The motivation for params field is the following: Java can avoid inclusion of parameter names into bytecode (for example, you can compile with no debug information). In order the JSO implementation with no access to original source code could work properly, JSO forces developer to specify parameter names explicitly.

Type conversion

A method marked with JSBody annotation is restricted to take parameters of allowed types. A type is allowed if it is either:

  • a primitive Java type, i.e. boolean, byte, short, char, int, long, float or double;
  • is java.lang.String class;
  • an overlay type, see JSObject;
  • an array of allowed type.

Java primitives are converted to corresponding JavaScript primitives, except for char, which does not have corresponding JavaScript representation. JSO implementation converts Java chars to JavaScript numbers, and expects a JavaScript number when converting to a Java character.

Java arrays are converted to JavaScript arrays and vice versa. Arrays are passed by copy.

java.lang.String objects are converted to JavaScript string.

Overlay types are passed as is.

Passing functions

Sometimes JavaScript functions expect you to pass a function as a parameter value. JSO allows you to pass special form of overlay objects as functions. These overlay objects must be interfaces with exactly one parameter and marked with JSFunctor annotation. Example:

    @JSFunctor
    interface TimerHandler extends JSObject {
        void onTimer();
    }

    @JSBody(params = { "handler", "delay" }, script = "return window.setTimeout(handler, delay);")
    public static native int setTimeout(TimerHandler handler, int delay);
 

Calling Java methods from JSBody

You can call Java methods from JSBody script. You should use the following notation:

javaMethods.get('method reference').invoke([instance, ] param1 [, param2 ...]);

The method reference has the following format:

 (PackageName .)* ClassName . MethodName MethodDescriptor
 

where

 PackageName = Identifier
 ClassName = Identifier
 MethodName = Identifier
 MethodDescriptor = ( TypeDescriptor ) V)
                         | ( TypeDescriptor ) TypeDescriptor
 TypeDescriptor = Z | B | C | S | I | J | F | D
                | L QualifiedClassName ; | [ TypeDescriptor.
 

that is similar to method descriptors augmented with class and method names.

For example,

    @JSBody(params = { "message" }, script = "javaMethods.get('org.teavm.jso.browser.Window"
            + ".alert(Ljava/lang/String;)V').invoke(message);")
    public static native void alertCaller(String message);
 

Note that get method must take string constant. Dynamic resolution of Java methods may not work on some platforms.

Author:
Alexey Andreev
See Also:
JSObject
  • Required Element Summary

    Required Elements
    Modifier and Type
    Required Element
    Description
    JavaScript code.
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    How method parameters are named inside JavaScript implementation.
  • Element Details

    • script

      String script

      JavaScript code.

    • params

      String[] params

      How method parameters are named inside JavaScript implementation.

      Default:
      {}