Skip to content

Commit 679f30e

Browse files
committed
DATACMNS-1066 - ClassGeneratingPropertyAccessorFactory now opts out on failed access to ClassLoader.
We now eagerly check the accessibility of the defineClass(…) method on the class loader to be used for a PersistentEntity. This will then cause the clients to use a different PropertyAccessorFactory (as things stand today: the one using reflection) and not fail to create the class later on.
1 parent f558a6c commit 679f30e

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java

+20-8
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ public PersistentPropertyAccessor getPropertyAccessor(PersistentEntity<?, ?> ent
9191
* Checks whether an accessor class can be generated.
9292
*
9393
* @param entity
94-
* @return {@literal true} if the runtime is equal or greater to Java 1.7, property name hash codes are unique and the
95-
* type has a class loader we can use to re-inject types.
94+
* @return {@literal true} if the runtime is equal or greater to Java 1.7, we can access the ClassLoader, the property
95+
* name hash codes are unique and the type has a class loader we can use to re-inject types.
9696
* @see PersistentPropertyAccessorFactory#isSupported(PersistentEntity)
9797
*/
9898
@Override
@@ -104,6 +104,12 @@ public boolean isSupported(PersistentEntity<?, ?> entity) {
104104
return false;
105105
}
106106

107+
try {
108+
Evil.getClassLoaderMethod(entity);
109+
} catch (Exception o_O) {
110+
return false;
111+
}
112+
107113
if (entity.getType().getClassLoader() == null || entity.getType().getPackage().getName().startsWith("java")) {
108114
return false;
109115
}
@@ -1446,6 +1452,7 @@ public int compareTo(PropertyStackAddress o) {
14461452
* accessed from a class in the same class loader.
14471453
*
14481454
* @author Mark Paluch
1455+
* @author Oliver Gierke
14491456
*/
14501457
@UtilityClass
14511458
private static class Evil {
@@ -1460,25 +1467,30 @@ private static class Evil {
14601467
* @param persistentEntity
14611468
* @return
14621469
*/
1463-
@SuppressWarnings("rawtypes")
14641470
Class<?> defineClass(String name, byte[] bytes, int offset, int len, PersistentEntity<?, ?> persistentEntity) {
14651471

14661472
ClassLoader classLoader = persistentEntity.getType().getClassLoader();
1467-
Class<?> classLoaderClass = classLoader.getClass();
14681473

14691474
try {
14701475

1471-
Class<? extends PersistentEntity> persistentEntityClass = persistentEntity.getClass();
1472-
Method defineClass = ReflectionUtils.findMethod(classLoaderClass, "defineClass", String.class, byte[].class,
1473-
Integer.TYPE, Integer.TYPE, ProtectionDomain.class);
1476+
Method defineClass = getClassLoaderMethod(persistentEntity);
14741477
defineClass.setAccessible(true);
14751478

14761479
return (Class<?>) defineClass.invoke(classLoader, name, bytes, offset, len,
1477-
persistentEntityClass.getProtectionDomain());
1480+
persistentEntity.getClass().getProtectionDomain());
14781481

14791482
} catch (ReflectiveOperationException e) {
14801483
throw new IllegalStateException(e);
14811484
}
14821485
}
1486+
1487+
static Method getClassLoaderMethod(PersistentEntity<?, ?> entity) {
1488+
1489+
ClassLoader classLoader = entity.getType().getClassLoader();
1490+
Class<?> classLoaderClass = classLoader.getClass();
1491+
1492+
return ReflectionUtils.findMethod(classLoaderClass, "defineClass", String.class, byte[].class, Integer.TYPE,
1493+
Integer.TYPE, ProtectionDomain.class);
1494+
}
14831495
}
14841496
}

0 commit comments

Comments
 (0)