From 2c6831948f4c7414f49a2bf218b58158eeb9a523 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 4 Oct 2018 10:17:43 +0200 Subject: [PATCH] DATACMNS-1401 - Provide context class on runtime class definition. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../data/convert/ClassGeneratingEntityInstantiator.java | 2 +- .../model/ClassGeneratingPropertyAccessorFactory.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java b/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java index 025ea6f91..23efffcd6 100644 --- a/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java +++ b/src/main/java/org/springframework/data/convert/ClassGeneratingEntityInstantiator.java @@ -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); } diff --git a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java index 9bf2c28ea..133f09983 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -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