8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
Reviewed-by: lagergren, jlaskey
This commit is contained in:
parent
5aea724d29
commit
c846064c8f
nashorn
bin
src/jdk/nashorn/api/scripting
test
@ -26,4 +26,4 @@
|
||||
|
||||
[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
|
||||
|
||||
$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
|
||||
$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $*
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
|
||||
|
||||
$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $*
|
||||
$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.security.properties=`dirname $0`/../make/java.security.override -Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $*
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
|
||||
|
||||
$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
|
||||
$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
|
||||
|
@ -26,4 +26,4 @@
|
||||
|
||||
[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1;
|
||||
|
||||
$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
|
||||
$JAVA_HOME/bin/jrunscript -J-Djava.security.properties=`dirname $0`/../make/java.security.override -J-Djava.security.manager -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=`dirname $0`/../dist:$JAVA_HOME/jre/lib/ext -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $*
|
||||
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
@ -179,14 +180,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
}
|
||||
|
||||
private <T> T getInterfaceInner(final Object self, final Class<T> clazz) {
|
||||
final Object realSelf;
|
||||
final ScriptObject realSelf;
|
||||
final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
|
||||
if(self == null) {
|
||||
realSelf = ctxtGlobal;
|
||||
} else if (!(self instanceof ScriptObject)) {
|
||||
realSelf = ScriptObjectMirror.unwrap(self, ctxtGlobal);
|
||||
realSelf = (ScriptObject)ScriptObjectMirror.unwrap(self, ctxtGlobal);
|
||||
} else {
|
||||
realSelf = self;
|
||||
realSelf = (ScriptObject)self;
|
||||
}
|
||||
try {
|
||||
final ScriptObject oldGlobal = getNashornGlobal();
|
||||
@ -194,6 +195,10 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
if(oldGlobal != ctxtGlobal) {
|
||||
setNashornGlobal(ctxtGlobal);
|
||||
}
|
||||
|
||||
if (! isInterfaceImplemented(clazz, realSelf)) {
|
||||
return null;
|
||||
}
|
||||
return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));
|
||||
} finally {
|
||||
if(oldGlobal != ctxtGlobal) {
|
||||
@ -463,6 +468,21 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInterfaceImplemented(final Class<?> iface, final ScriptObject sobj) {
|
||||
for (final Method method : iface.getMethods()) {
|
||||
// ignore methods of java.lang.Object class
|
||||
if (method.getDeclaringClass() == Object.class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Object obj = sobj.get(method.getName());
|
||||
if (! (obj instanceof ScriptFunction)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't make this public!!
|
||||
static ScriptObject getNashornGlobal() {
|
||||
return Context.getGlobal();
|
||||
|
51
nashorn/test/script/basic/JDK-8010199.js
Normal file
51
nashorn/test/script/basic/JDK-8010199.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK-8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var m = new javax.script.ScriptEngineManager();
|
||||
var e = m.getEngineByName("nashorn");
|
||||
|
||||
var iface = e.getInterface(java.lang.Runnable.class);
|
||||
|
||||
if (iface != null) {
|
||||
fail("Expected interface object to be null");
|
||||
}
|
||||
|
||||
e.eval("var runcalled = false; function run() { runcalled = true }");
|
||||
|
||||
iface = e.getInterface(java.lang.Runnable.class);
|
||||
if (iface == null) {
|
||||
fail("Expected interface object to be non-null");
|
||||
}
|
||||
|
||||
iface.run();
|
||||
|
||||
if (e.get("runcalled") != true) {
|
||||
fail("runcalled is not true");
|
||||
}
|
@ -283,6 +283,68 @@ public class ScriptEngineTest {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
public void accessGlobalTest() {
|
||||
final ScriptEngineManager m = new ScriptEngineManager();
|
||||
|
Loading…
x
Reference in New Issue
Block a user