-
Bug
-
Resolution: Fixed
-
P3
-
8u25
-
b43
-
x86_64
-
windows_7
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085566 | emb-9 | Hannes Wallnoefer | P3 | Resolved | Fixed | team |
JDK-8068131 | 8u45 | Hannes Wallnoefer | P3 | Resolved | Fixed | b02 |
JDK-8067228 | 8u40 | Hannes Wallnoefer | P3 | Resolved | Fixed | b19 |
JDK-8070542 | emb-8u47 | Hannes Wallnoefer | P3 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
If __noSuchMethod__ is used on a Prototype, it seems that the ScriptEngine executes the function with the first Object the script was called (ScriptEngien.eval). The second call to the ScriptEngine with invokeFunction the JavaScript object behaves like a singleton. I tested this with a JDK7 (Rhino) successfully, but on a JDK8 it did'nt work like expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute TestCase with JDK7, look for output
2. Execute TestCase with JDK8 compare outputs
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
868385821 == 868385821
675655832 == 675655832
2001526735 == 2001526735
1475988537 == 1475988537
1355734862 == 1355734862
ACTUAL -
1073533248 == 1073533248
576936864 != 1073533248
1653844940 != 1073533248
260840925 != 1073533248
1891502635 != 1073533248
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class PrototypeTest {
private static final String TEST_SCRIPT =
"function proxyCall(realObj, mthName, args) {\r\n" +
" var funcMap = {\r\n" +
" 'arg0': function (obj, id, arg) {\r\n" +
" return obj[id]();\r\n" +
" }\r\n" +
" };\r\n" +
" var argType = 'arg' + args.length;\r\n" +
" if (!(argType in funcMap)) {\r\n" +
" var funcStr = 'function(obj, id, arg){return obj[id](';\r\n" +
" for (var i = 0, len = args.length; i < len; i++) {\r\n" +
" funcStr += 'arg[' + i + ']';\r\n" +
" if ((i + 1) < len) {\r\n" +
" funcStr += ',';\r\n" +
" }\r\n" +
" }\r\n" +
" funcStr += ');}';\r\n" +
" funcMap[argType] = eval(funcStr);\r\n" +
" }\r\n" +
" return funcMap[argType](realObj, mthName, args);\r\n" +
"}\r\n" +
"function Dummy(obj) {\r\n" +
" this.myObj = obj;\r\n" +
"}\r\n" +
"Dummy.prototype.hashCodeFunc = function () {\r\n" +
" return this.myObj.hashCode();\r\n" +
"};\r\n" +
"Dummy.prototype.__noSuchMethod__ = function (name, args) {\r\n" +
" var callArgs;\r\n" +
" if (arguments.length == 2 && Array.isArray(args)) {\r\n" +
" callArgs = args;\r\n" +
" } else {\r\n" +
" callArgs = Array.prototype.slice.call(arguments, 1);\r\n" +
" }\r\n" +
" return proxyCall(this.myObj, name, callArgs);\r\n" +
"};\r\n" +
"function handle(obj) {\r\n" +
" var dum = new Dummy(obj);\r\n" +
" var hc1 = dum.hashCodeFunc();\r\n" +
" var hc2 = dum.hashCode();\r\n" +
" print(hc1 + (hc1 == hc2 ? ' == ' : ' != ') + hc2 + '\\r\\n');\r\n" +
"}\r\n";
public static void main(String[] args) {
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
try {
se.eval(TEST_SCRIPT);
for(int i=0; i<5; i++) {
((Invocable)se).invokeFunction("handle", new Object());
}
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
If __noSuchMethod__ is used on a Prototype, it seems that the ScriptEngine executes the function with the first Object the script was called (ScriptEngien.eval). The second call to the ScriptEngine with invokeFunction the JavaScript object behaves like a singleton. I tested this with a JDK7 (Rhino) successfully, but on a JDK8 it did'nt work like expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Execute TestCase with JDK7, look for output
2. Execute TestCase with JDK8 compare outputs
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
868385821 == 868385821
675655832 == 675655832
2001526735 == 2001526735
1475988537 == 1475988537
1355734862 == 1355734862
ACTUAL -
1073533248 == 1073533248
576936864 != 1073533248
1653844940 != 1073533248
260840925 != 1073533248
1891502635 != 1073533248
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class PrototypeTest {
private static final String TEST_SCRIPT =
"function proxyCall(realObj, mthName, args) {\r\n" +
" var funcMap = {\r\n" +
" 'arg0': function (obj, id, arg) {\r\n" +
" return obj[id]();\r\n" +
" }\r\n" +
" };\r\n" +
" var argType = 'arg' + args.length;\r\n" +
" if (!(argType in funcMap)) {\r\n" +
" var funcStr = 'function(obj, id, arg){return obj[id](';\r\n" +
" for (var i = 0, len = args.length; i < len; i++) {\r\n" +
" funcStr += 'arg[' + i + ']';\r\n" +
" if ((i + 1) < len) {\r\n" +
" funcStr += ',';\r\n" +
" }\r\n" +
" }\r\n" +
" funcStr += ');}';\r\n" +
" funcMap[argType] = eval(funcStr);\r\n" +
" }\r\n" +
" return funcMap[argType](realObj, mthName, args);\r\n" +
"}\r\n" +
"function Dummy(obj) {\r\n" +
" this.myObj = obj;\r\n" +
"}\r\n" +
"Dummy.prototype.hashCodeFunc = function () {\r\n" +
" return this.myObj.hashCode();\r\n" +
"};\r\n" +
"Dummy.prototype.__noSuchMethod__ = function (name, args) {\r\n" +
" var callArgs;\r\n" +
" if (arguments.length == 2 && Array.isArray(args)) {\r\n" +
" callArgs = args;\r\n" +
" } else {\r\n" +
" callArgs = Array.prototype.slice.call(arguments, 1);\r\n" +
" }\r\n" +
" return proxyCall(this.myObj, name, callArgs);\r\n" +
"};\r\n" +
"function handle(obj) {\r\n" +
" var dum = new Dummy(obj);\r\n" +
" var hc1 = dum.hashCodeFunc();\r\n" +
" var hc2 = dum.hashCode();\r\n" +
" print(hc1 + (hc1 == hc2 ? ' == ' : ' != ') + hc2 + '\\r\\n');\r\n" +
"}\r\n";
public static void main(String[] args) {
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
try {
se.eval(TEST_SCRIPT);
for(int i=0; i<5; i++) {
((Invocable)se).invokeFunction("handle", new Object());
}
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8067228 __noSuchMethod__ binds to this-object without proper guard
- Resolved
-
JDK-8068131 __noSuchMethod__ binds to this-object without proper guard
- Resolved
-
JDK-8070542 __noSuchMethod__ binds to this-object without proper guard
- Resolved
-
JDK-8085566 __noSuchMethod__ binds to this-object without proper guard
- Resolved