OpenJDK / jigsaw / jake / jdk
changeset 14167:4b16ae395bbe
Expand GetModuleTest to VM anonymous classes
author | alanb |
---|---|
date | Thu, 01 Oct 2015 11:16:01 +0100 |
parents | 8d3fcb58b82c |
children | 2b6cb5de27d5 |
files | src/java.base/share/classes/jdk/internal/misc/BuiltinClassLoader.java test/java/lang/Class/GetModuleTest.java |
diffstat | 2 files changed, 93 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/jdk/internal/misc/BuiltinClassLoader.java Thu Oct 01 08:59:23 2015 +0100 +++ b/src/java.base/share/classes/jdk/internal/misc/BuiltinClassLoader.java Thu Oct 01 11:16:01 2015 +0100 @@ -561,21 +561,27 @@ * @param c a Class defined by this class loader */ Package definePackage(Class<?> c) { - Module m = c.getModule(); - String cn = c.getName(); - int pos = cn.lastIndexOf('.'); - if (pos < 0 && m.isNamed()) { - throw new InternalError("unnamed package in named module " - + m.getName()); + String pn; + if (c.isPrimitive()) { + pn = ""; + } else { + Module m = c.getModule(); + String cn = c.getName(); + int pos = cn.lastIndexOf('.'); + if (pos < 0 && m.isNamed()) { + throw new InternalError("unnamed package in named module " + + m.getName()); + } + pn = (pos != -1) ? cn.substring(0, pos) : ""; } - String pn = (pos != -1) ? cn.substring(0, pos) : ""; + Package p = getDefinedPackage(pn); - if (p == null) { URL url = null; // The given class may be dynamically generated and // its package is not in packageToModule map. + Module m = c.getModule(); if (m.isNamed()) { ModuleReference mref = nameToModule.get(m.getName()); if (mref != null) {
--- a/test/java/lang/Class/GetModuleTest.java Thu Oct 01 08:59:23 2015 +0100 +++ b/test/java/lang/Class/GetModuleTest.java Thu Oct 01 11:16:01 2015 +0100 @@ -24,23 +24,40 @@ /* * @test * @summary Exercise Class#getModule + * @modules java.base/jdk.internal.org.objectweb.asm * @run testng GetModuleTest */ import java.awt.Component; +import java.lang.reflect.Field; import java.lang.reflect.Module; +import jdk.internal.org.objectweb.asm.ClassWriter; +import static jdk.internal.org.objectweb.asm.Opcodes.*; +import sun.misc.Unsafe; + import org.testng.annotations.DataProvider; import org.testng.annotations.Test; - import static org.testng.Assert.*; public class GetModuleTest { + static final Unsafe U; + static { + try { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + U = (Unsafe) theUnsafe.get(null); + } catch (Exception e) { + throw new AssertionError(e); + } + } + private static final Module TEST_MODULE = GetModuleTest.class.getModule(); - @DataProvider(name = "samples") - public Object[][] sampleData() { + + @DataProvider(name = "testclasses") + public Object[][] testClasses() { return new Object[][] { // unnamed module @@ -55,6 +72,7 @@ { int[].class, "java.base" }, { int[][].class, "java.base" }, { void.class, "java.base" }, + { Object.class, "java.base" }, { Object[].class, "java.base" }, { Object[][].class, "java.base" }, @@ -64,7 +82,7 @@ }; } - @Test(dataProvider = "samples") + @Test(dataProvider = "testClasses") public void testGetModule(Class<?> type, String expected) { Module m = type.getModule(); assertNotNull(m); @@ -74,4 +92,61 @@ assertEquals(m.getName(), expected); } } + + + @DataProvider(name = "hostclasses") + public Object[][] hostClasses() { + return new Object[][] { + + { GetModuleTest.class, null }, + { GetModuleTest[].class, null }, + { Object.class, null }, + { Object[].class, null }, + { Component.class, null }, + { Component[].class, null }, + + }; + } + + /** + * Exercise Class::getModule on VM anonymous classes + */ + @Test(dataProvider = "hostclasses") + public void testGetModuleOnVMAnonymousClass(Class<?> hostClass, String ignore) { + + // choose a class name in the same package as the host class + String prefix = packageName(hostClass); + if (prefix.length() > 0) + prefix = prefix.replace('.', '/') + "/"; + String className = prefix + "Anon"; + + // create the class + String superName = "java/lang/Object"; + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + + ClassWriter.COMPUTE_FRAMES); + cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, + className, null, superName, null); + byte[] classBytes = cw.toByteArray(); + int cpPoolSize = constantPoolSize(classBytes); + Class<?> anonClass + = U.defineAnonymousClass(hostClass, classBytes, new Object[cpPoolSize]); + + assertTrue(anonClass.getModule() == hostClass.getModule()); + } + + private static String packageName(Class<?> c) { + if (c.isArray()) { + return packageName(c.getComponentType()); + } else { + String name = c.getName(); + int dot = name.lastIndexOf('.'); + if (dot == -1) return ""; + return name.substring(0, dot); + } + } + + private static int constantPoolSize(byte[] classFile) { + return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF); + } + }