1 /*
2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.nashorn.api.javaaccess.test;
27 
28 import static org.testng.AssertJUnit.assertEquals;
29 import static org.testng.AssertJUnit.assertTrue;
30 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
31 import java.util.Arrays;
32 import java.util.Calendar;
33 import java.util.Locale;
34 import javax.script.ScriptEngine;
35 import javax.script.ScriptEngineManager;
36 import javax.script.ScriptException;
37 import org.testng.TestNG;
38 import org.testng.annotations.AfterClass;
39 import org.testng.annotations.BeforeClass;
40 import org.testng.annotations.Test;
41 
42 /**
43  * @test
44  * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.MethodAccessTest
45  * @run testng/othervm jdk.nashorn.api.javaaccess.test.MethodAccessTest
46  */
47 @SuppressWarnings("javadoc")
48 public class MethodAccessTest {
49 
50     private static ScriptEngine e = null;
51     private static SharedObject o = null;
52 
main(final String[] args)53     public static void main(final String[] args) {
54         TestNG.main(args);
55     }
56 
57     @BeforeClass
setUpClass()58     public static void setUpClass() throws ScriptException {
59         final ScriptEngineManager m = new ScriptEngineManager();
60         e = m.getEngineByName("nashorn");
61         o = new SharedObject();
62         o.setEngine(e);
63         e.put("o", o);
64         e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;");
65         e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.test.Person;");
66     }
67 
68     @AfterClass
tearDownClass()69     public static void tearDownClass() {
70         e = null;
71         o = null;
72     }
73 
74     @Test
accessMethodthrowsCheckedException()75     public void accessMethodthrowsCheckedException() throws ScriptException {
76         e.eval("try {" +
77                 "    var a = java.lang.Long.parseLong('foo');" +
78                 "} catch(e) {" +
79                 "    var isThrown = true;" +
80                 "    var isNumberException = e instanceof java.lang.NumberFormatException;" +
81                 "} finally {" +
82                 "    var isFinalized = true;" +
83                 "}");
84         assertEquals("Exception thrown", true, e.get("isThrown"));
85         assertEquals("Finally called", true, e.get("isFinalized"));
86         assertEquals("Type is NumberFormatException", true, e.get("isNumberException"));
87     }
88 
89     @Test
accessMethodthrowsUnCheckedException()90     public void accessMethodthrowsUnCheckedException() throws ScriptException {
91         e.eval("try {" +
92                 "    var a = java.lang.String.valueOf(null);" +
93                 "} catch(e) {" +
94                 "    var isThrown = true;" +
95                 "    var isNumberException = e instanceof java.lang.NullPointerException;" +
96                 "} finally {" +
97                 "    var isFinalized = true;" +
98                 "}");
99         assertEquals(true, e.get("isThrown"));
100         assertEquals(true, e.get("isFinalized"));
101         assertEquals(true, e.get("isNumberException"));
102     }
103 
104     @Test
accessMethodStartsThread()105     public void accessMethodStartsThread() throws ScriptException {
106         e.eval("o.methodStartsThread();");
107         assertEquals(false, o.isFinished);
108     }
109 
110     @Test
accessStaticMethod()111     public void accessStaticMethod() throws ScriptException {
112         assertEquals(10, e.eval("java.lang.Math.abs(-10);"));
113     }
114 
115     @Test
accessSynchronousMethod()116     public void accessSynchronousMethod() throws ScriptException {
117         e.eval("var v = new java.util.Vector();" + "v.add(10);" + "v.add(20);" + "v.add(30);");
118         assertEquals(10, e.eval("v[0]"));
119         assertEquals(20, e.eval("v[1]"));
120         assertEquals(30, e.eval("v[2]"));
121         assertEquals(3, e.eval("v.size()"));
122     }
123 
124     @Test
accessStaticSynchronousMethod()125     public void accessStaticSynchronousMethod() throws ScriptException {
126         e.eval("var locales = java.util.Calendar.getAvailableLocales();");
127         final Locale[] locales = (Locale[])e.get("locales");
128         assertEquals(locales.length, Calendar.getAvailableLocales().length);
129     }
130 
131     @Test
accessNativeMethod()132     public void accessNativeMethod() throws ScriptException {
133         assertEquals(4.0, e.eval("java.lang.StrictMath.log10(10000);"));
134     }
135 
136     @Test
accessConstructorOfAbstractClass()137     public void accessConstructorOfAbstractClass() throws ScriptException {
138         e.eval("try {" +
139                 "    var a = new java.util.AbstractList();" +
140                 "    print('fail');" +
141                 "} catch(e) {" +
142                 "    var isThrown = true;" +
143                 "}");
144         assertEquals(true, e.get("isThrown"));
145     }
146 
147     @Test
accessMethodVoid()148     public void accessMethodVoid() throws ScriptException {
149         o.isAccessed = false;
150         e.eval("o.voidMethod();");
151         assertTrue(o.isAccessed);
152     }
153 
154     @Test
accessMethodBoolean()155     public void accessMethodBoolean() throws ScriptException {
156         assertEquals(true, e.eval("o.booleanMethod(false);"));
157         assertEquals(false, e.eval("o.booleanMethod(true);"));
158         assertEquals(false, e.eval("o.booleanMethod('false');"));
159         assertEquals(true, e.eval("o.booleanMethod('');"));
160         assertEquals(true, e.eval("o.booleanMethod(0);"));
161     }
162 
163     @Test
accessMethodInt()164     public void accessMethodInt() throws ScriptException {
165         assertEquals(0, e.eval("o.intMethod(0);"));
166         assertEquals(-200, e.eval("o.intMethod(-100);"));
167         assertEquals(0, e.eval("o.intMethod('0');"));
168         assertEquals(-200, e.eval("o.intMethod('-100');"));
169     }
170 
171     @Test
accessMethodLong()172     public void accessMethodLong() throws ScriptException {
173         assertEquals((long)0, e.eval("o.longMethod(0);"));
174         assertEquals((long)400, e.eval("o.longMethod(200);"));
175         assertEquals((long) 0, e.eval("o.longMethod('0');"));
176         assertEquals((long) 400, e.eval("o.longMethod('200');"));
177     }
178 
179     @Test
accessMethodByte()180     public void accessMethodByte() throws ScriptException {
181         assertEquals((byte) 0, e.eval("o.byteMethod(0);"));
182         assertEquals((byte) 10, e.eval("o.byteMethod(5);"));
183         assertEquals((byte) 0, e.eval("o.byteMethod('0');"));
184         assertEquals((byte) 10, e.eval("o.byteMethod('5');"));
185     }
186 
187     @Test
accessMethodShort()188     public void accessMethodShort() throws ScriptException {
189         assertEquals((short)0, e.eval("o.shortMethod(0);"));
190         assertEquals((short)8000, e.eval("o.shortMethod(4000);"));
191         assertEquals((short) 0, e.eval("o.shortMethod('0');"));
192         assertEquals((short) 8000, e.eval("o.shortMethod('4000');"));
193     }
194 
195     @Test
accessMethodChar()196     public void accessMethodChar() throws ScriptException {
197         assertEquals('A', e.eval("o.charMethod('a');"));
198         assertEquals('Z', e.eval("o.charMethod('z');"));
199         assertEquals(o.charMethod((char)0), e.eval("o.charMethod(0);"));
200         assertEquals(o.charMethod((char)3150), e.eval("o.charMethod(3150);"));
201     }
202 
203     @Test
accessMethodFloat()204     public void accessMethodFloat() throws ScriptException {
205         assertEquals(0.0f, e.eval("o.floatMethod(0.0);"));
206         assertEquals(4.2f, e.eval("o.floatMethod(2.1);"));
207         assertEquals(0.0f, e.eval("o.floatMethod('0.0');"));
208         assertEquals(4.2f, e.eval("o.floatMethod('2.1');"));
209     }
210 
211     @Test
accessMethodDouble()212     public void accessMethodDouble() throws ScriptException {
213         assertEquals(0.0, e.eval("o.doubleMethod(0.0);"));
214         assertEquals(14.0, e.eval("o.doubleMethod(7.0);"));
215         assertEquals(0.0, e.eval("o.doubleMethod('0.0');"));
216         assertEquals(14.0, e.eval("o.doubleMethod('7.0');"));
217     }
218 
219     @Test
accessMethodBooleanBoxing()220     public void accessMethodBooleanBoxing() throws ScriptException {
221         assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.FALSE);"));
222         assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.TRUE);"));
223         assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod('');"));
224         assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod('false');"));
225     }
226 
227     @Test
accessMethodIntBoxing()228     public void accessMethodIntBoxing() throws ScriptException {
229         assertEquals(0, e.eval("o.intBoxingMethod(0);"));
230         assertEquals(-200, e.eval("o.intBoxingMethod(-100);"));
231         assertTrue((int)e.eval("(new java.lang.Integer(2)).compareTo(10.0)") < 0);
232     }
233 
234     @Test
accessMethodLongBoxing()235     public void accessMethodLongBoxing() throws ScriptException {
236         assertEquals((long) 0, e.eval("o.longBoxingMethod(0);"));
237         assertEquals((long) 400, e.eval("o.longBoxingMethod(200);"));
238         assertTrue((int)e.eval("(new java.lang.Long(2)).compareTo(10.0)") < 0);
239     }
240 
241     @Test
accessMethodByteBoxing()242     public void accessMethodByteBoxing() throws ScriptException {
243         assertEquals((byte) 0, e.eval("o.byteBoxingMethod(0);"));
244         assertEquals((byte) 10, e.eval("o.byteBoxingMethod(5);"));
245         assertTrue((int)e.eval("(new java.lang.Byte(2)).compareTo(10.0)") < 0);
246     }
247 
248     @Test
accessMethodShortBoxing()249     public void accessMethodShortBoxing() throws ScriptException {
250         assertEquals((short) 0, e.eval("o.shortBoxingMethod(0);"));
251         assertEquals((short) 8000, e.eval("o.shortBoxingMethod(4000);"));
252         assertTrue((int)e.eval("(new java.lang.Short(2)).compareTo(10.0)") < 0);
253     }
254 
255     @Test
accessMethodCharBoxing()256     public void accessMethodCharBoxing() throws ScriptException {
257         assertEquals('A', e.eval("o.charBoxingMethod('a');"));
258         assertEquals('Z', e.eval("o.charBoxingMethod('z');"));
259         assertTrue((int)e.eval("(new java.lang.Character(2)).compareTo(10)") < 0);
260     }
261 
262     @Test
accessMethodFloatBoxing()263     public void accessMethodFloatBoxing() throws ScriptException {
264         assertEquals(0.0f, e.eval("o.floatBoxingMethod(0.0);"));
265         assertEquals(4.2f, e.eval("o.floatBoxingMethod(2.1);"));
266         assertTrue((int)e.eval("(new java.lang.Float(2.0)).compareTo(10.0)") < 0);
267     }
268 
269     @Test
accessMethodDoubleBoxing()270     public void accessMethodDoubleBoxing() throws ScriptException {
271         assertEquals(0.0, e.eval("o.doubleBoxingMethod(0.0);"));
272         assertEquals(14.0, e.eval("o.doubleBoxingMethod(7.0);"));
273         assertTrue((int)e.eval("(new java.lang.Double(2)).compareTo(10.0)") < 0);
274     }
275 
276     @Test
accessMethodString()277     public void accessMethodString() throws ScriptException {
278         assertEquals("", e.eval("o.stringMethod('');"));
279         assertEquals("abcabc", e.eval("o.stringMethod('abc');"));
280     }
281 
282     @Test
accessMethodObject()283     public void accessMethodObject() throws ScriptException {
284         e.put("so", new Person(5));
285         e.eval("var rso = o.objectMethod(so);");
286         assertEquals(new Person(10), e.get("rso"));
287     }
288 
289     @Test
accessMethodBooleanArray()290     public void accessMethodBooleanArray() throws ScriptException {
291         assertTrue(Arrays.equals(o.booleanArrayMethod(o.publicBooleanArray), (boolean[])e.eval("o.booleanArrayMethod(o.publicBooleanArray);")));
292     }
293 
294     @Test
accessMethodIntArray()295     public void accessMethodIntArray() throws ScriptException {
296         assertArrayEquals(o.intArrayMethod(o.publicIntArray), (int[])e.eval("o.intArrayMethod(o.publicIntArray);"));
297     }
298 
299     @Test
accessMethodLongArray()300     public void accessMethodLongArray() throws ScriptException {
301         assertArrayEquals(o.longArrayMethod(o.publicLongArray), (long[])e.eval("o.longArrayMethod(o.publicLongArray);"));
302     }
303 
304     @Test
accessMethodByteArray()305     public void accessMethodByteArray() throws ScriptException {
306         assertArrayEquals(o.byteArrayMethod(o.publicByteArray), (byte[])e.eval("o.byteArrayMethod(o.publicByteArray);"));
307     }
308 
309     @Test
accessMethodShortArray()310     public void accessMethodShortArray() throws ScriptException {
311         assertArrayEquals(o.shortArrayMethod(o.publicShortArray), (short[])e.eval("o.shortArrayMethod(o.publicShortArray);"));
312     }
313 
314     @Test
accessMethodCharArray()315     public void accessMethodCharArray() throws ScriptException {
316         assertArrayEquals(o.charArrayMethod(o.publicCharArray), (char[])e.eval("o.charArrayMethod(o.publicCharArray);"));
317     }
318 
319     @Test
accessMethodFloatArray()320     public void accessMethodFloatArray() throws ScriptException {
321         assertArrayEquals(o.floatArrayMethod(o.publicFloatArray), (float[])e.eval("o.floatArrayMethod(o.publicFloatArray);"), 1e-10f);
322     }
323 
324     @Test
accessMethodDoubleArray()325     public void accessMethodDoubleArray() throws ScriptException {
326         assertArrayEquals(o.doubleArrayMethod(o.publicDoubleArray), (double[])e.eval("o.doubleArrayMethod(o.publicDoubleArray);"), 1e-10);
327     }
328 
329     @Test
accessMethodStringArray()330     public void accessMethodStringArray() throws ScriptException {
331         assertArrayEquals(o.stringArrayMethod(o.publicStringArray), (String[])e.eval("o.stringArrayMethod(o.publicStringArray);"));
332     }
333 
334     @Test
accessMethodObjectArray()335     public void accessMethodObjectArray() throws ScriptException {
336         assertArrayEquals(o.objectArrayMethod(o.publicObjectArray), (Person[])e.eval("o.objectArrayMethod(o.publicObjectArray);"));
337     }
338 
339     @Test
accessDefaultConstructor()340     public void accessDefaultConstructor() throws ScriptException {
341         e.eval("var dc = new Packages.jdk.nashorn.api.javaaccess.test.Person()");
342         assertEquals(new Person(), e.get("dc"));
343     }
344 
345     @Test
accessCustomConstructor()346     public void accessCustomConstructor() throws ScriptException {
347         e.eval("var cc = new Packages.jdk.nashorn.api.javaaccess.test.Person(17)");
348         assertEquals(new Person(17), e.get("cc"));
349     }
350 
351     @Test
accessMethod2PrimitiveParams()352     public void accessMethod2PrimitiveParams() throws ScriptException {
353         assertEquals(o.twoParamMethod(50, 40.0), e.eval("o.twoParamMethod(50,40);"));
354     }
355 
356     @Test
accessMethod3PrimitiveParams()357     public void accessMethod3PrimitiveParams() throws ScriptException {
358         assertEquals(o.threeParamMethod((short)10, 20L, 'b'), e.eval("o.threeParamMethod(10,20,'b');"));
359     }
360 
361     @Test
accessMethod2ObjectParams()362     public void accessMethod2ObjectParams() throws ScriptException {
363         assertArrayEquals(new Person[] { new Person(200), new Person(300) }, (Person[])e.eval("o.twoObjectParamMethod(new Person(300),new Person(200));"));
364     }
365 
366     @Test
accessMethod3ObjectParams()367     public void accessMethod3ObjectParams() throws ScriptException {
368         assertArrayEquals(new Person[] { new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.threeObjectParamMethod(new Person(1),new Person(2),new Person(3));"));
369     }
370 
371     @Test
accessMethod8ObjectParams()372     public void accessMethod8ObjectParams() throws ScriptException {
373         assertArrayEquals(new Person[] { new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.eightObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6),new Person(7),new Person(8));"));
374     }
375 
376     @Test
accessMethod9ObjectParams()377     public void accessMethod9ObjectParams() throws ScriptException {
378         assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.nineObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));"));
379     }
380 
381     @Test
accessMethodObjectEllipsis()382     public void accessMethodObjectEllipsis() throws ScriptException {
383         assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));"));
384         assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodObjectEllipsis()"));
385         assertArrayEquals(new Person[] { new Person(9) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(9))"));
386     }
387 
388     @Test
accessMethodPrimitiveEllipsis()389     public void accessMethodPrimitiveEllipsis() throws ScriptException {
390         assertArrayEquals(new Person[] { new Person(1), new Person(3), new Person(2) }, (Person[])e.eval("o.methodPrimitiveEllipsis(1,3,2);"));
391         assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodPrimitiveEllipsis();"));
392         assertArrayEquals(o.methodPrimitiveEllipsis(9, 8, 7, 6, 5, 4, 3, 2, 1), (Person[])e.eval("o.methodPrimitiveEllipsis(9,8,7,6,5,4,3,2,1);"));
393     }
394 
395     @Test
accessMethodMixedEllipsis()396     public void accessMethodMixedEllipsis() throws ScriptException {
397         assertArrayEquals(new Object[] { new Person(1), 12, "hello", true }, (Object[])e.eval("o.methodMixedEllipsis(new Person(1),12,'hello',true);"));
398         assertArrayEquals(new Object[] {}, (Object[])e.eval("o.methodMixedEllipsis();"));
399     }
400 
401     @Test
accessMethodObjectWithEllipsis()402     public void accessMethodObjectWithEllipsis() throws ScriptException {
403         assertArrayEquals(new Object[] { "hello", 12, 15, 16 }, (Object[])e.eval("o.methodObjectWithEllipsis('hello',12,15,16);"));
404         assertArrayEquals(new Object[] { "hello" }, (Object[])e.eval("o.methodObjectWithEllipsis('hello');"));
405     }
406 
407     @Test
accessMethodPrimitiveWithEllipsis()408     public void accessMethodPrimitiveWithEllipsis() throws ScriptException {
409         assertArrayEquals(new Object[] { 14, 12L, 15L, 16L }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(14,12,15,16);"));
410         assertArrayEquals(new Object[] { 12 }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(12);"));
411     }
412 
413     @Test
accessMethodMixedWithEllipsis()414     public void accessMethodMixedWithEllipsis() throws ScriptException {
415         assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80d }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);"));
416         assertArrayEquals(new Object[] { "Nashorn", 15 }, (Object[])e.eval("o.methodMixedWithEllipsis('Nashorn',15);"));
417     }
418 
419     @Test
accessMethodOverloaded()420     public void accessMethodOverloaded() throws ScriptException {
421         assertEquals(0, e.eval("o.overloadedMethod(0);"));
422         assertEquals(2000, e.eval("o.overloadedMethod(1000);"));
423         assertEquals(2, e.eval("o.overloadedMethod('10');"));
424         assertEquals(7, e.eval("o.overloadedMethod('Nashorn');"));
425         assertEquals(4, e.eval("o.overloadedMethod('true');"));
426         assertEquals(1, e.eval("o.overloadedMethod(true);"));
427         assertEquals(0, e.eval("o.overloadedMethod(false);"));
428         assertEquals(44, e.eval("o.overloadedMethod(new Person(22));"));
429         assertEquals(0, e.eval("o.overloadedMethod(new Person());"));
430     }
431 
432     @Test
accessMethodDoubleVSintOverloaded()433     public void accessMethodDoubleVSintOverloaded() throws ScriptException {
434         assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.0);"));
435         assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(1000.0);"));
436         assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.01);"));
437         assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(100.02);"));
438         assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0);"));
439         assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000);"));
440     }
441 
442     @Test
accessJavaMethodIntFromJSFromJavaFromJS()443     public void accessJavaMethodIntFromJSFromJavaFromJS() throws ScriptException {
444         e.eval("function secondLevelMethodInt(a) {"
445                 + "return o.thirdLevelMethodInt(a);"
446                 + "}");
447         assertEquals(50, e.eval("o.firstLevelMethodInt(10);"));
448     }
449 
450     @Test
accessJavaMethodIntegerFromJSFromJavaFromJS()451     public void accessJavaMethodIntegerFromJSFromJavaFromJS() throws ScriptException {
452         e.eval("function secondLevelMethodInteger(a) {"
453                 + "return o.thirdLevelMethodInteger(a);"
454                 + "}");
455         assertEquals(100, e.eval("o.firstLevelMethodInteger(10);"));
456     }
457 
458     @Test
accessJavaMethodObjectFromJSFromJavaFromJS()459     public void accessJavaMethodObjectFromJSFromJavaFromJS() throws ScriptException {
460         e.eval("function secondLevelMethodObject(p) {"
461                 + "return o.thirdLevelMethodObject(p);"
462                 + "}");
463         assertEquals(new Person(100), e.eval("o.firstLevelMethodObject(new Person(10));"));
464     }
465 
466 }
467