DATACMNS-1401 - Provide context class on runtime class definition.

We now provide the context class for private MethodHandle lookup in the context of the actual entity class to properly use MethodHandles.defineClass(…) and to avoid illegal access warnings caused by reflective access to the defineClass(…) method on class loaders.

Also, we now use the internal type name without adding the reference type decorator when casting the result of a wither invocation. CHECKCAST allowed on earlier Java runtimes (version 8 and earlier) to use the reference decorator (L…;) around the type name. Java 9 and newer reject this format with a ClassFormatError.

Original pull request: #318.
This commit is contained in:
Mark Paluch
2018-10-04 10:17:43 +02:00
committed by Oliver Gierke
parent dfd2781c76
commit 2c6831948f
2 changed files with 5 additions and 4 deletions

View File

@@ -326,7 +326,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
Class<?> type = entity.getType();
try {
return ReflectUtils.defineClass(className, bytecode, type.getClassLoader(), type.getProtectionDomain());
return ReflectUtils.defineClass(className, bytecode, type.getClassLoader(), type.getProtectionDomain(), type);
} catch (Exception e) {
throw new IllegalStateException(e);
}

View File

@@ -318,7 +318,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
Class<?> type = entity.getType();
try {
return ReflectUtils.defineClass(className, bytecode, type.getClassLoader(), type.getProtectionDomain());
return ReflectUtils.defineClass(className, bytecode, type.getClassLoader(), type.getProtectionDomain(), type);
} catch (Exception e) {
throw new IllegalStateException(e);
}
@@ -1037,8 +1037,9 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke", String.format("(%s%s)%s",
referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT), getAccessibleTypeReferenceName(entity)),
false);
mv.visitTypeInsn(CHECKCAST, getAccessibleTypeReferenceName(entity));
if (isAccessible(entity)) {
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(entity.getType()));
}
} else {
// this. <- for later PUTFIELD