< prev index next >

test/jdk/java/lang/invoke/DefineClassTest.java

Print this page

  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 
< prev index next >