DATACMNS-1602 - Avoid attempts to recreate the same property accessor class.
PropertyAccessorClassGenerator now tries to look up the class to be generated first to potentially reuse an already existing one and avoid the recreation and registration of a same class which would trigger a Linkage error as a classloader cannot hold two classes with the same name. The root of the problem is in the fact that the accessor instances are held in per instance caches in EntityInstantiators, so that multiple of those might try to create the same accessor class for a given domain type.
This commit is contained in:
@@ -317,13 +317,26 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
|
||||
static Class<?> generateCustomAccessorClass(PersistentEntity<?, ?> entity) {
|
||||
|
||||
String className = generateClassName(entity);
|
||||
byte[] bytecode = generateBytecode(className.replace('.', '/'), entity);
|
||||
Class<?> type = entity.getType();
|
||||
ClassLoader classLoader = type.getClassLoader();
|
||||
|
||||
if (ClassUtils.isPresent(className, classLoader)) {
|
||||
|
||||
try {
|
||||
return ClassUtils.forName(className, classLoader);
|
||||
} catch (Exception o_O) {
|
||||
throw new IllegalStateException(o_O);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] bytecode = generateBytecode(className.replace('.', '/'), entity);
|
||||
|
||||
try {
|
||||
return ReflectUtils.defineClass(className, bytecode, type.getClassLoader(), type.getProtectionDomain(), type);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
|
||||
return ReflectUtils.defineClass(className, bytecode, classLoader, type.getProtectionDomain(), type);
|
||||
|
||||
} catch (Exception o_O) {
|
||||
throw new IllegalStateException(o_O);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user