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 /* @test
25 * @modules java.base/java.lang:open
26 * @run testng/othervm test.DefineClassTest
27 * @summary Basic test for java.lang.invoke.MethodHandles.Lookup.defineClass
28 */
29
30 package test;
31
32 import java.lang.classfile.ClassFile;
33 import java.lang.constant.ClassDesc;
34 import java.lang.invoke.MethodHandles.Lookup;
35 import java.lang.reflect.AccessFlag;
36 import java.net.URL;
37 import java.net.URLClassLoader;
38 import java.nio.file.Files;
39 import java.nio.file.Path;
40 import java.nio.file.Paths;
41 import org.testng.annotations.Test;
42
43 import static java.lang.classfile.ClassFile.ACC_PUBLIC;
44 import static java.lang.classfile.ClassFile.ACC_STATIC;
241 @Test(expectedExceptions = { NullPointerException.class })
242 public void testNull() throws Exception {
243 lookup().defineClass(null);
244 }
245
246 @Test(expectedExceptions = { NoClassDefFoundError.class })
247 public void testLinking() throws Exception {
248 lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass"));
249 }
250
251 @Test(expectedExceptions = { IllegalArgumentException.class })
252 public void testModuleInfo() throws Exception {
253 lookup().defineClass(generateModuleInfo());
254 }
255
256 /**
257 * Generates a class file with the given class name
258 */
259 byte[] generateClass(String className) {
260 return ClassFile.of().build(ClassDesc.of(className), clb -> {
261 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
262 clb.withSuperclass(CD_Object);
263 clb.withMethodBody(INIT_NAME, MTD_void, PUBLIC, cob -> {
264 cob.aload(0);
265 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
266 cob.return_();
267 });
268 });
269 }
270
271 /**
272 * Generate a class file with the given class name. The class implements Runnable
273 * with a run method to invokestatic the given targetClass/targetMethod.
274 */
275 byte[] generateRunner(String className,
276 String targetClass,
277 String targetMethod) throws Exception {
278
279 return ClassFile.of().build(ClassDesc.of(className), clb -> {
280 clb.withSuperclass(CD_Object);
281 clb.withInterfaceSymbols(CD_Runnable);
283 cob.aload(0);
284 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
285 cob.return_();
286 });
287 clb.withMethodBody("run", MTD_void, PUBLIC, cob -> {
288 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
289 cob.return_();
290 });
291 });
292 }
293
294 /**
295 * Generate a class file with the given class name. The class will initializer
296 * to invokestatic the given targetClass/targetMethod.
297 */
298 byte[] generateClassWithInitializer(String className,
299 String targetClass,
300 String targetMethod) throws Exception {
301
302 return ClassFile.of().build(ClassDesc.of(className), clb -> {
303 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
304 clb.withSuperclass(CD_Object);
305 clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
306 cob.aload(0);
307 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
308 cob.return_();
309 });
310 clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
311 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
312 cob.return_();
313 });
314 });
315 }
316
317 /**
318 * Generates a non-linkable class file with the given class name
319 */
320 byte[] generateNonLinkableClass(String className) {
321 return ClassFile.of().build(ClassDesc.of(className), clb -> {
322 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
323 clb.withSuperclass(CD_MissingSuperClass);
324 clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
325 cob.aload(0);
326 cob.invokespecial(CD_MissingSuperClass, INIT_NAME, MTD_void);
327 cob.return_();
328 });
329 });
330 }
331
332 /**
333 * Generates a class file with the given class name
334 */
335 byte[] generateModuleInfo() {
336 return ClassFile.of().build(ClassDesc.of("module-info"), cb -> cb.withFlags(AccessFlag.MODULE));
337 }
338
339 private int nextNumber() {
340 return ++nextNumber;
341 }
342
|
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 /* @test
25 * @enablePreview
26 * @modules java.base/java.lang:open
27 * @run testng/othervm test.DefineClassTest
28 * @summary Basic test for java.lang.invoke.MethodHandles.Lookup.defineClass
29 */
30
31 package test;
32
33 import java.lang.classfile.ClassFile;
34 import java.lang.constant.ClassDesc;
35 import java.lang.invoke.MethodHandles.Lookup;
36 import java.lang.reflect.AccessFlag;
37 import java.net.URL;
38 import java.net.URLClassLoader;
39 import java.nio.file.Files;
40 import java.nio.file.Path;
41 import java.nio.file.Paths;
42 import org.testng.annotations.Test;
43
44 import static java.lang.classfile.ClassFile.ACC_PUBLIC;
45 import static java.lang.classfile.ClassFile.ACC_STATIC;
242 @Test(expectedExceptions = { NullPointerException.class })
243 public void testNull() throws Exception {
244 lookup().defineClass(null);
245 }
246
247 @Test(expectedExceptions = { NoClassDefFoundError.class })
248 public void testLinking() throws Exception {
249 lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass"));
250 }
251
252 @Test(expectedExceptions = { IllegalArgumentException.class })
253 public void testModuleInfo() throws Exception {
254 lookup().defineClass(generateModuleInfo());
255 }
256
257 /**
258 * Generates a class file with the given class name
259 */
260 byte[] generateClass(String className) {
261 return ClassFile.of().build(ClassDesc.of(className), clb -> {
262 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
263 clb.withSuperclass(CD_Object);
264 clb.withMethodBody(INIT_NAME, MTD_void, PUBLIC, cob -> {
265 cob.aload(0);
266 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
267 cob.return_();
268 });
269 });
270 }
271
272 /**
273 * Generate a class file with the given class name. The class implements Runnable
274 * with a run method to invokestatic the given targetClass/targetMethod.
275 */
276 byte[] generateRunner(String className,
277 String targetClass,
278 String targetMethod) throws Exception {
279
280 return ClassFile.of().build(ClassDesc.of(className), clb -> {
281 clb.withSuperclass(CD_Object);
282 clb.withInterfaceSymbols(CD_Runnable);
284 cob.aload(0);
285 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
286 cob.return_();
287 });
288 clb.withMethodBody("run", MTD_void, PUBLIC, cob -> {
289 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
290 cob.return_();
291 });
292 });
293 }
294
295 /**
296 * Generate a class file with the given class name. The class will initializer
297 * to invokestatic the given targetClass/targetMethod.
298 */
299 byte[] generateClassWithInitializer(String className,
300 String targetClass,
301 String targetMethod) throws Exception {
302
303 return ClassFile.of().build(ClassDesc.of(className), clb -> {
304 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
305 clb.withSuperclass(CD_Object);
306 clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
307 cob.aload(0);
308 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
309 cob.return_();
310 });
311 clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
312 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
313 cob.return_();
314 });
315 });
316 }
317
318 /**
319 * Generates a non-linkable class file with the given class name
320 */
321 byte[] generateNonLinkableClass(String className) {
322 return ClassFile.of().build(ClassDesc.of(className), clb -> {
323 clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
324 clb.withSuperclass(CD_MissingSuperClass);
325 clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
326 cob.aload(0);
327 cob.invokespecial(CD_MissingSuperClass, INIT_NAME, MTD_void);
328 cob.return_();
329 });
330 });
331 }
332
333 /**
334 * Generates a class file with the given class name
335 */
336 byte[] generateModuleInfo() {
337 return ClassFile.of().build(ClassDesc.of("module-info"), cb -> cb.withFlags(AccessFlag.MODULE));
338 }
339
340 private int nextNumber() {
341 return ++nextNumber;
342 }
343
|