alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (InvocableTest.java)

This example Java source code file (InvocableTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

exception, hello, illegalargumentexception, invocable, nosuchmethodexception, object, runnable, scriptengine, scriptenginemanager, scriptexception, simplescriptcontext, test, throwable, util, world

The InvocableTest.java Java example source code

/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nashorn.api.scripting;

import java.util.Objects;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import org.testng.Assert;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import org.testng.annotations.Test;

/**
 * Tests for javax.script.Invocable implementation of nashorn.
 */
public class InvocableTest {

    private void log(String msg) {
        org.testng.Reporter.log(msg, true);
    }

    @Test
    public void invokeMethodTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();");
            final Object obj = e.get("myExample");
            final Object res = ((Invocable) e).invokeMethod(obj, "hello");
            assertEquals(res, "Hello World!");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
    }

    @Test
    /**
     * Check that we can call invokeMethod on an object that we got by
     * evaluating script with different Context set.
     */
    public void invokeMethodDifferentContextTest() {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");

        try {
            // define an object with method on it
            Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })");

            final ScriptContext ctxt = new SimpleScriptContext();
            ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
            e.setContext(ctxt);

            // invoke 'func' on obj - but with current script context changed
            final Object res = ((Invocable) e).invokeMethod(obj, "hello");
            assertEquals(res, "Hello World!");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
    }

    @Test
    /**
     * Check that invokeMethod throws NPE on null method name.
     */
    public void invokeMethodNullNameTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            final Object obj = e.eval("({})");
            final Object res = ((Invocable) e).invokeMethod(obj, null);
            fail("should have thrown NPE");
        } catch (final Exception exp) {
            if (!(exp instanceof NullPointerException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that invokeMethod throws NoSuchMethodException on missing method.
     */
    public void invokeMethodMissingTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            final Object obj = e.eval("({})");
            final Object res = ((Invocable) e).invokeMethod(obj, "nonExistentMethod");
            fail("should have thrown NoSuchMethodException");
        } catch (final Exception exp) {
            if (!(exp instanceof NoSuchMethodException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that calling method on non-script object 'thiz' results in
     * IllegalArgumentException.
     */
    public void invokeMethodNonScriptObjectThizTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            ((Invocable) e).invokeMethod(new Object(), "toString");
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that calling method on null 'thiz' results in
     * IllegalArgumentException.
     */
    public void invokeMethodNullThizTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            ((Invocable) e).invokeMethod(null, "toString");
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that calling method on mirror created by another engine results in
     * IllegalArgumentException.
     */
    public void invokeMethodMixEnginesTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine engine1 = m.getEngineByName("nashorn");
        final ScriptEngine engine2 = m.getEngineByName("nashorn");

        try {
            Object obj = engine1.eval("({ run: function() {} })");
            // pass object from engine1 to engine2 as 'thiz' for invokeMethod
            ((Invocable) engine2).invokeMethod(obj, "run");
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    public void getInterfaceTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");
        final Invocable inv = (Invocable) e;

        // try to get interface from global functions
        try {
            e.eval("function run() { print('run'); };");
            final Runnable runnable = inv.getInterface(Runnable.class);
            runnable.run();
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }

        // try interface on specific script object
        try {
            e.eval("var obj = { run: function() { print('run from obj'); } };");
            Object obj = e.get("obj");
            final Runnable runnable = inv.getInterface(obj, Runnable.class);
            runnable.run();
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
    }

    public interface Foo {

        public void bar();
    }

    public interface Foo2 extends Foo {

        public void bar2();
    }

    @Test
    public void getInterfaceMissingTest() {
        final ScriptEngineManager manager = new ScriptEngineManager();
        final ScriptEngine engine = manager.getEngineByName("nashorn");

        // don't define any function.
        try {
            engine.eval("");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }

        Runnable runnable = ((Invocable) engine).getInterface(Runnable.class);
        if (runnable != null) {
            fail("runnable is not null!");
        }

        // now define "run"
        try {
            engine.eval("function run() { print('this is run function'); }");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
        runnable = ((Invocable) engine).getInterface(Runnable.class);
        // should not return null now!
        runnable.run();

        // define only one method of "Foo2"
        try {
            engine.eval("function bar() { print('bar function'); }");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }

        Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class);
        if (foo2 != null) {
            throw new RuntimeException("foo2 is not null!");
        }

        // now define other method of "Foo2"
        try {
            engine.eval("function bar2() { print('bar2 function'); }");
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
        foo2 = ((Invocable) engine).getInterface(Foo2.class);
        foo2.bar();
        foo2.bar2();
    }

    @Test
    /**
     * Try passing non-interface Class object for interface implementation.
     */
    public void getNonInterfaceGetInterfaceTest() {
        final ScriptEngineManager manager = new ScriptEngineManager();
        final ScriptEngine engine = manager.getEngineByName("nashorn");
        try {
            log(Objects.toString(((Invocable) engine).getInterface(Object.class)));
            fail("Should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                fail("IllegalArgumentException expected, got " + exp);
            }
        }
    }

    @Test
    /**
     * Check that we can get interface out of a script object even after
     * switching to use different ScriptContext.
     */
    public void getInterfaceDifferentContext() {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");
        try {
            Object obj = e.eval("({ run: function() { } })");

            // change script context
            ScriptContext ctxt = new SimpleScriptContext();
            ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
            e.setContext(ctxt);

            Runnable r = ((Invocable) e).getInterface(obj, Runnable.class);
            r.run();
        } catch (final Exception exp) {
            exp.printStackTrace();
            fail(exp.getMessage());
        }
    }

    @Test
    /**
     * Check that getInterface on non-script object 'thiz' results in
     * IllegalArgumentException.
     */
    public void getInterfaceNonScriptObjectThizTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            ((Invocable) e).getInterface(new Object(), Runnable.class);
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that getInterface on null 'thiz' results in
     * IllegalArgumentException.
     */
    public void getInterfaceNullThizTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            ((Invocable) e).getInterface(null, Runnable.class);
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that calling getInterface on mirror created by another engine
     * results in IllegalArgumentException.
     */
    public void getInterfaceMixEnginesTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine engine1 = m.getEngineByName("nashorn");
        final ScriptEngine engine2 = m.getEngineByName("nashorn");

        try {
            Object obj = engine1.eval("({ run: function() {} })");
            // pass object from engine1 to engine2 as 'thiz' for getInterface
            ((Invocable) engine2).getInterface(obj, Runnable.class);
            fail("should have thrown IllegalArgumentException");
        } catch (final Exception exp) {
            if (!(exp instanceof IllegalArgumentException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * check that null function name results in NPE.
     */
    public void invokeFunctionNullNameTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            final Object res = ((Invocable) e).invokeFunction(null);
            fail("should have thrown NPE");
        } catch (final Exception exp) {
            if (!(exp instanceof NullPointerException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that attempt to call missing function results in
     * NoSuchMethodException.
     */
    public void invokeFunctionMissingTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");

        try {
            final Object res = ((Invocable) e).invokeFunction("NonExistentFunc");
            fail("should have thrown NoSuchMethodException");
        } catch (final Exception exp) {
            if (!(exp instanceof NoSuchMethodException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    /**
     * Check that invokeFunction calls functions only from current context's
     * Bindings.
     */
    public void invokeFunctionDifferentContextTest() {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");

        try {
            // define an object with method on it
            Object obj = e.eval("function hello() { return 'Hello World!'; }");
            final ScriptContext ctxt = new SimpleScriptContext();
            ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE);
            // change engine's current context
            e.setContext(ctxt);

            ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context!
            fail("should have thrown NoSuchMethodException");
        } catch (final Exception exp) {
            if (!(exp instanceof NoSuchMethodException)) {
                exp.printStackTrace();
                fail(exp.getMessage());
            }
        }
    }

    @Test
    public void invokeFunctionExceptionTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");
        try {
            e.eval("function func() { throw new TypeError(); }");
        } catch (final Throwable t) {
            t.printStackTrace();
            fail(t.getMessage());
        }

        try {
            ((Invocable) e).invokeFunction("func");
            fail("should have thrown exception");
        } catch (final ScriptException se) {
            // ECMA TypeError property wrapped as a ScriptException
            log("got " + se + " as expected");
        } catch (final Throwable t) {
            t.printStackTrace();
            fail(t.getMessage());
        }
    }

    @Test
    public void invokeMethodExceptionTest() {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");
        try {
            e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }");
        } catch (final Throwable t) {
            t.printStackTrace();
            fail(t.getMessage());
        }

        try {
            final Object sobj = e.get("sobj");
            ((Invocable) e).invokeMethod(sobj, "foo");
            fail("should have thrown exception");
        } catch (final ScriptException se) {
            // ECMA TypeError property wrapped as a ScriptException
            log("got " + se + " as expected");
        } catch (final Throwable t) {
            t.printStackTrace();
            fail(t.getMessage());
        }
    }

    @Test
    /**
     * Tests whether invocation of a JavaScript method through a variable arity
     * Java method will pass the vararg array. Both non-vararg and vararg
     * JavaScript methods are tested.
     *
     * @throws ScriptException
     */
    public void variableArityInterfaceTest() throws ScriptException {
        final ScriptEngineManager m = new ScriptEngineManager();
        final ScriptEngine e = m.getEngineByName("nashorn");
        e.eval(
                "function test1(i, strings) {"
                + "    return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)"
                + "}"
                + "function test2() {"
                + "    return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])"
                + "}");
        final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class);
        Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]");
        Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]");
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java InvocableTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.