use of org.hibernate.bytecode.enhance.spi.EnhancementException in project hibernate-orm by hibernate.
the class FieldWriter method addWithModifiers.
private static void addWithModifiers(CtClass target, CtClass type, String name, int modifiers, Class<?>... annotations) {
try {
final CtField f = new CtField(type, name, target);
f.setModifiers(f.getModifiers() | modifiers);
addAnnotations(f.getFieldInfo(), annotations);
target.addField(f);
} catch (CannotCompileException cce) {
final String msg = String.format("Could not enhance class [%s] to add field [%s]", target.getName(), name);
throw new EnhancementException(msg, cce);
}
}
use of org.hibernate.bytecode.enhance.spi.EnhancementException in project hibernate-orm by hibernate.
the class MethodWriter method addSetter.
public static CtMethod addSetter(CtClass target, String field, String name) {
CtField actualField = null;
try {
actualField = target.getField(field);
log.debugf("Writing setter method [%s] into [%s] for field [%s]", name, target.getName(), field);
CtMethod method = CtNewMethod.setter(name, actualField);
target.addMethod(method);
return method;
} catch (CannotCompileException cce) {
try {
// Fall back to create a getter from delegation.
CtMethod method = CtNewMethod.delegator(CtNewMethod.setter(name, actualField), target);
target.addMethod(method);
return method;
} catch (CannotCompileException ignored) {
String msg = String.format("Could not enhance class [%s] to add method [%s] for field [%s]", target.getName(), name, field);
throw new EnhancementException(msg, cce);
}
} catch (NotFoundException nfe) {
String msg = String.format("Could not enhance class [%s] to add method [%s] for field [%s]", target.getName(), name, field);
throw new EnhancementException(msg, nfe);
}
}
use of org.hibernate.bytecode.enhance.spi.EnhancementException in project hibernate-orm by hibernate.
the class PersistentAttributesEnhancer method enhanceAttributesAccess.
protected void enhanceAttributesAccess(CtClass managedCtClass, IdentityHashMap<String, PersistentAttributeAccessMethods> attributeDescriptorMap) {
final ConstPool constPool = managedCtClass.getClassFile().getConstPool();
final ClassPool classPool = managedCtClass.getClassPool();
for (Object oMethod : managedCtClass.getClassFile().getMethods()) {
final MethodInfo methodInfo = (MethodInfo) oMethod;
final String methodName = methodInfo.getName();
// skip methods added by enhancement and abstract methods (methods without any code)
if (methodName.startsWith("$$_hibernate_") || methodInfo.getCodeAttribute() == null) {
continue;
}
try {
final CodeIterator itr = methodInfo.getCodeAttribute().iterator();
while (itr.hasNext()) {
final int index = itr.next();
final int op = itr.byteAt(index);
if (op != Opcode.PUTFIELD && op != Opcode.GETFIELD) {
continue;
}
// only transform access to fields of the entity being enhanced
if (!managedCtClass.getName().equals(constPool.getFieldrefClassName(itr.u16bitAt(index + 1)))) {
continue;
}
final String fieldName = constPool.getFieldrefName(itr.u16bitAt(index + 1));
final PersistentAttributeAccessMethods attributeMethods = attributeDescriptorMap.get(fieldName);
// its not a field we have enhanced for interception, so skip it
if (attributeMethods == null) {
continue;
}
//System.out.printf( "Transforming access to field [%s] from method [%s]%n", fieldName, methodName );
log.debugf("Transforming access to field [%s] from method [%s]", fieldName, methodName);
if (op == Opcode.GETFIELD) {
final int methodIndex = MethodWriter.addMethod(constPool, attributeMethods.getReader());
itr.writeByte(Opcode.INVOKEVIRTUAL, index);
itr.write16bit(methodIndex, index + 1);
} else {
final int methodIndex = MethodWriter.addMethod(constPool, attributeMethods.getWriter());
itr.writeByte(Opcode.INVOKEVIRTUAL, index);
itr.write16bit(methodIndex, index + 1);
}
}
methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo));
} catch (BadBytecode bb) {
final String msg = String.format("Unable to perform field access transformation in method [%s]", methodName);
throw new EnhancementException(msg, bb);
}
}
}
use of org.hibernate.bytecode.enhance.spi.EnhancementException in project hibernate-orm by hibernate.
the class PersistentAttributesEnhancer method extendedEnhancement.
// --- //
/**
* Replace access to fields of entities (for example, entity.field) with a call to the enhanced getter / setter
* (in this example, entity.$$_hibernate_read_field()). It's assumed that the target entity is enhanced as well.
*
* @param aCtClass Class to enhance (not an entity class).
*/
public void extendedEnhancement(CtClass aCtClass) {
final ConstPool constPool = aCtClass.getClassFile().getConstPool();
final ClassPool classPool = aCtClass.getClassPool();
for (Object oMethod : aCtClass.getClassFile().getMethods()) {
final MethodInfo methodInfo = (MethodInfo) oMethod;
final String methodName = methodInfo.getName();
// skip methods added by enhancement and abstract methods (methods without any code)
if (methodName.startsWith("$$_hibernate_") || methodInfo.getCodeAttribute() == null) {
continue;
}
try {
final CodeIterator itr = methodInfo.getCodeAttribute().iterator();
while (itr.hasNext()) {
int index = itr.next();
int op = itr.byteAt(index);
if (op != Opcode.PUTFIELD && op != Opcode.GETFIELD) {
continue;
}
String fieldName = constPool.getFieldrefName(itr.u16bitAt(index + 1));
String fieldClassName = constPool.getClassInfo(constPool.getFieldrefClass(itr.u16bitAt(index + 1)));
CtClass targetCtClass = classPool.getCtClass(fieldClassName);
if (!enhancementContext.isEntityClass(targetCtClass) && !enhancementContext.isCompositeClass(targetCtClass)) {
continue;
}
if (targetCtClass == aCtClass || !enhancementContext.isPersistentField(targetCtClass.getField(fieldName)) || PersistentAttributesHelper.hasAnnotation(targetCtClass, fieldName, Id.class) || "this$0".equals(fieldName)) {
continue;
}
log.debugf("Extended enhancement: Transforming access to field [%s.%s] from method [%s#%s]", fieldClassName, fieldName, aCtClass.getName(), methodName);
if (op == Opcode.GETFIELD) {
int fieldReaderMethodIndex = constPool.addMethodrefInfo(constPool.addClassInfo(fieldClassName), EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + fieldName, "()" + constPool.getFieldrefType(itr.u16bitAt(index + 1)));
itr.writeByte(Opcode.INVOKEVIRTUAL, index);
itr.write16bit(fieldReaderMethodIndex, index + 1);
} else {
int fieldWriterMethodIndex = constPool.addMethodrefInfo(constPool.addClassInfo(fieldClassName), EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + fieldName, "(" + constPool.getFieldrefType(itr.u16bitAt(index + 1)) + ")V");
itr.writeByte(Opcode.INVOKEVIRTUAL, index);
itr.write16bit(fieldWriterMethodIndex, index + 1);
}
}
methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo));
} catch (BadBytecode bb) {
final String msg = String.format("Unable to perform extended enhancement in method [%s]", methodName);
throw new EnhancementException(msg, bb);
} catch (NotFoundException nfe) {
final String msg = String.format("Unable to perform extended enhancement in method [%s]", methodName);
throw new EnhancementException(msg, nfe);
}
}
}
use of org.hibernate.bytecode.enhance.spi.EnhancementException in project hibernate-orm by hibernate.
the class EnhancerImpl method loadCtClassFromClass.
protected CtClass loadCtClassFromClass(Class<?> aClass) {
String resourceName = aClass.getName().replace('.', '/') + ".class";
InputStream resourceAsStream = aClass.getClassLoader().getResourceAsStream(resourceName);
if (resourceAsStream == null) {
throw new UncheckedIOException(new FileNotFoundException("Not found: " + resourceName));
}
try {
return classPool.makeClass(resourceAsStream);
} catch (IOException e) {
throw new EnhancementException("Could not prepare Javassist ClassPool", e);
} finally {
try {
resourceAsStream.close();
} catch (IOException ioe) {
log.debugf("An error occurs closing InputStream for class [%s]", aClass.getName());
}
}
}
Aggregations