1 /*
2 * Copyright (c) 2022, 2025, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @summary Test dynamic proxies with parameter types or return type of value class
27 * @enablePreview
28 * @run testng/othervm ProxyTest
29 */
30
31 import java.lang.reflect.*;
32 import java.util.Arrays;
33
34 import org.testng.annotations.Test;
35 import static org.testng.Assert.*;
36
37 public class ProxyTest {
38 static value class V {
39 int v;
40 V(int v) {
41 this.v = v;
42 }
43 }
44
45 static value class P {
46 int p;
47 P(int p) {
48 this.p = p;
49 }
50 }
51
52 interface I {
53 int getV(V v);
54 int getP(P p);
55 }
56
57 interface J {
58 int[] getV(V[] v);
59 }
60
61 @Test
62 public void testProxy() throws Exception {
63 InvocationHandler handler = new InvocationHandler() {
64 @Override
65 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
66 switch (method.getName()) {
67 case "getV":
68 V v = (V)args[0];
69 return v.v;
70 case "getP":
71 P p = (P)args[0];
72 return p.p;
73 default:
74 throw new UnsupportedOperationException(method.toString());
75 }
76 }
77 };
78
79 Class<?>[] intfs = new Class<?>[] { I.class };
80 I i = (I) Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), intfs, handler);
81
82 assertTrue(i.getV(new V(100)) == 100);
83 assertTrue(i.getP(new P(200)) == 200);
84 }
85
86 @Test
87 public void testValueArrayType() {
88 InvocationHandler handler = new InvocationHandler() {
89 @Override
90 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
91 switch (method.getName()) {
92 case "getV":
93 V[] vs = (V[])args[0];
94 return Arrays.stream(vs).mapToInt(v -> v.v).toArray();
95 default:
96 throw new UnsupportedOperationException(method.toString());
97 }
98 }
99 };
100
101 Class<?>[] intfs = new Class<?>[] { J.class };
102 J j = (J) Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), intfs, handler);
103
104 V[] array = new V[] { new V(10), new V(20), new V(30)};
105 assertEquals(j.getV(array), new int[] { 10, 20, 30});
106 }
107 }