From 6112d098abee2cc72e846a5affd82b5fcf94ab0d Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 2 Jun 2017 08:32:05 +0200 Subject: [PATCH 1/3] DATACMNS-1079 - Prepare branch. --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 5a7ea733bc..5b341c9610 100644 --- a/pom.xml +++ b/pom.xml @@ -5,6 +5,7 @@ org.springframework.data spring-data-commons + 2.0.0.DATACMNS-1079-SNAPSHOT Spring Data Core From 49de635841ddbf5064edeaa99ec15b5804d1607e Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 2 Jun 2017 13:55:43 +0200 Subject: [PATCH 2/3] DATACMNS-1079 - Make ClassGenerationPropertyAccessorFactory Java 9 aware. ClassGenerationPropertyAccessFactory does not work with Java 9 (without --permit-illegal-access), because making ClassLoader.defineClass accessible fails. Therefore this change moves call to setAccessible to the check that ensures availability of the method. --- .../ClassGeneratingPropertyAccessorFactory.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) 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 863232b548..e5a9c8ae64 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -1463,7 +1463,6 @@ Class defineClass(String name, byte[] bytes, int offset, int len, PersistentE try { Method defineClass = getClassLoaderMethod(persistentEntity); - defineClass.setAccessible(true); return (Class) defineClass.invoke(classLoader, name, bytes, offset, len, persistentEntity.getClass().getProtectionDomain()); @@ -1478,8 +1477,19 @@ static Method getClassLoaderMethod(PersistentEntity entity) { ClassLoader classLoader = entity.getType().getClassLoader(); Class classLoaderClass = classLoader.getClass(); - return ReflectionUtils.findMethod(classLoaderClass, "defineClass", String.class, byte[].class, Integer.TYPE, - Integer.TYPE, ProtectionDomain.class); + Method defineClass = ReflectionUtils.findMethod( // + classLoaderClass, // + "defineClass", // + String.class, // + byte[].class, // + Integer.TYPE, // + Integer.TYPE, // + ProtectionDomain.class // + ); + + defineClass.setAccessible(true); + + return defineClass; } } } From bead2891b6f9fc2f82343e46701c78382870a370 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 2 Jun 2017 09:56:39 +0200 Subject: [PATCH 3/3] DATACMNS-1079 - Polishing. Refactored all the checks done to check if ClassGeneratingProperty works into separate methods, so the body of isSupported becomes nice and readable. --- ...lassGeneratingPropertyAccessorFactory.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) 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 e5a9c8ae64..33d59e83d7 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -101,15 +101,12 @@ public boolean isSupported(PersistentEntity entity) { Assert.notNull(entity, "PersistentEntity must not be null!"); - try { - Evil.getClassLoaderMethod(entity); - } catch (Exception o_O) { - return false; - } + return isClassLoaderDefineClassAccessible(entity) // + && isTypeInjectable(entity) // + && arePropertyHashCodesUnique(entity); + } - if (entity.getType().getClassLoader() == null || entity.getType().getPackage().getName().startsWith("java")) { - return false; - } + private boolean arePropertyHashCodesUnique(PersistentEntity entity) { final Set hashCodes = new HashSet<>(); final AtomicInteger propertyCount = new AtomicInteger(); @@ -132,6 +129,20 @@ public boolean isSupported(PersistentEntity entity) { return hashCodes.size() == propertyCount.get(); } + private static boolean isTypeInjectable(PersistentEntity entity) { + return entity.getType().getClassLoader() != null && !entity.getType().getPackage().getName().startsWith("java"); + } + + private static boolean isClassLoaderDefineClassAccessible(PersistentEntity entity) { + + try { + Evil.getClassLoaderMethod(entity); + } catch (Exception o_O) { + return false; + } + return true; + } + /** * @param entity must not be {@literal null}. * @return