< 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 junit/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 
 42 import static java.lang.classfile.ClassFile.ACC_PUBLIC;
 43 import static java.lang.classfile.ClassFile.ACC_STATIC;
 44 import static java.lang.constant.ConstantDescs.CD_Object;

232     @Test
233     public void testNull() throws Exception {
234         assertThrows(NullPointerException.class, () -> lookup().defineClass(null));
235     }
236 
237     @Test
238     public void testLinking() throws Exception {
239         assertThrows(NoClassDefFoundError.class, () -> lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass")));
240     }
241 
242     @Test
243     public void testModuleInfo() throws Exception {
244         assertThrows(IllegalArgumentException.class, () -> lookup().defineClass(generateModuleInfo()));
245     }
246 
247     /**
248      * Generates a class file with the given class name
249      */
250     byte[] generateClass(String className) {
251         return ClassFile.of().build(ClassDesc.of(className), clb -> {
252             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
253             clb.withSuperclass(CD_Object);
254             clb.withMethodBody(INIT_NAME, MTD_void, PUBLIC, cob -> {
255                 cob.aload(0);
256                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
257                 cob.return_();
258             });
259         });
260     }
261 
262     /**
263      * Generate a class file with the given class name. The class implements Runnable
264      * with a run method to invokestatic the given targetClass/targetMethod.
265      */
266     byte[] generateRunner(String className,
267                           String targetClass,
268                           String targetMethod) throws Exception {
269 
270         return ClassFile.of().build(ClassDesc.of(className), clb -> {
271             clb.withSuperclass(CD_Object);
272             clb.withInterfaceSymbols(CD_Runnable);

274                 cob.aload(0);
275                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
276                 cob.return_();
277             });
278             clb.withMethodBody("run", MTD_void, PUBLIC, cob -> {
279                 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
280                 cob.return_();
281             });
282         });
283     }
284 
285     /**
286      * Generate a class file with the given class name. The class will initializer
287      * to invokestatic the given targetClass/targetMethod.
288      */
289     byte[] generateClassWithInitializer(String className,
290                                         String targetClass,
291                                         String targetMethod) throws Exception {
292 
293         return ClassFile.of().build(ClassDesc.of(className), clb -> {
294             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
295             clb.withSuperclass(CD_Object);
296             clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
297                 cob.aload(0);
298                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
299                 cob.return_();
300             });
301             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
302                 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
303                 cob.return_();
304             });
305         });
306     }
307 
308     /**
309      * Generates a non-linkable class file with the given class name
310      */
311     byte[] generateNonLinkableClass(String className) {
312         return ClassFile.of().build(ClassDesc.of(className), clb -> {
313             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
314             clb.withSuperclass(CD_MissingSuperClass);
315             clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
316                 cob.aload(0);
317                 cob.invokespecial(CD_MissingSuperClass, INIT_NAME, MTD_void);
318                 cob.return_();
319             });
320         });
321     }
322 
323     /**
324      * Generates a class file with the given class name
325      */
326     byte[] generateModuleInfo() {
327         return ClassFile.of().build(ClassDesc.of("module-info"), cb -> cb.withFlags(AccessFlag.MODULE));
328     }
329 
330     private int nextNumber() {
331         return ++nextNumber;
332     }
333 

  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 junit/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 
 43 import static java.lang.classfile.ClassFile.ACC_PUBLIC;
 44 import static java.lang.classfile.ClassFile.ACC_STATIC;
 45 import static java.lang.constant.ConstantDescs.CD_Object;

233     @Test
234     public void testNull() throws Exception {
235         assertThrows(NullPointerException.class, () -> lookup().defineClass(null));
236     }
237 
238     @Test
239     public void testLinking() throws Exception {
240         assertThrows(NoClassDefFoundError.class, () -> lookup().defineClass(generateNonLinkableClass(THIS_PACKAGE + ".NonLinkableClass")));
241     }
242 
243     @Test
244     public void testModuleInfo() throws Exception {
245         assertThrows(IllegalArgumentException.class, () -> lookup().defineClass(generateModuleInfo()));
246     }
247 
248     /**
249      * Generates a class file with the given class name
250      */
251     byte[] generateClass(String className) {
252         return ClassFile.of().build(ClassDesc.of(className), clb -> {
253             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
254             clb.withSuperclass(CD_Object);
255             clb.withMethodBody(INIT_NAME, MTD_void, PUBLIC, cob -> {
256                 cob.aload(0);
257                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
258                 cob.return_();
259             });
260         });
261     }
262 
263     /**
264      * Generate a class file with the given class name. The class implements Runnable
265      * with a run method to invokestatic the given targetClass/targetMethod.
266      */
267     byte[] generateRunner(String className,
268                           String targetClass,
269                           String targetMethod) throws Exception {
270 
271         return ClassFile.of().build(ClassDesc.of(className), clb -> {
272             clb.withSuperclass(CD_Object);
273             clb.withInterfaceSymbols(CD_Runnable);

275                 cob.aload(0);
276                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
277                 cob.return_();
278             });
279             clb.withMethodBody("run", MTD_void, PUBLIC, cob -> {
280                 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
281                 cob.return_();
282             });
283         });
284     }
285 
286     /**
287      * Generate a class file with the given class name. The class will initializer
288      * to invokestatic the given targetClass/targetMethod.
289      */
290     byte[] generateClassWithInitializer(String className,
291                                         String targetClass,
292                                         String targetMethod) throws Exception {
293 
294         return ClassFile.of().build(ClassDesc.of(className), clb -> {
295             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
296             clb.withSuperclass(CD_Object);
297             clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
298                 cob.aload(0);
299                 cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
300                 cob.return_();
301             });
302             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
303                 cob.invokestatic(ClassDesc.of(targetClass), targetMethod, MTD_void);
304                 cob.return_();
305             });
306         });
307     }
308 
309     /**
310      * Generates a non-linkable class file with the given class name
311      */
312     byte[] generateNonLinkableClass(String className) {
313         return ClassFile.of().build(ClassDesc.of(className), clb -> {
314             clb.withFlags(AccessFlag.PUBLIC, AccessFlag.IDENTITY);
315             clb.withSuperclass(CD_MissingSuperClass);
316             clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
317                 cob.aload(0);
318                 cob.invokespecial(CD_MissingSuperClass, INIT_NAME, MTD_void);
319                 cob.return_();
320             });
321         });
322     }
323 
324     /**
325      * Generates a class file with the given class name
326      */
327     byte[] generateModuleInfo() {
328         return ClassFile.of().build(ClassDesc.of("module-info"), cb -> cb.withFlags(AccessFlag.MODULE));
329     }
330 
331     private int nextNumber() {
332         return ++nextNumber;
333     }
334 
< prev index next >