Search in sources :

Example 6 with NotFoundException

use of javassist.NotFoundException in project ratpack by ratpack.

the class DescribingHandlers method describeTo.

public static void describeTo(Handler handler, StringBuilder stringBuilder) {
    Class<? extends Handler> clazz = handler.getClass();
    if (clazz.isAnonymousClass()) {
        ClassPool pool = ClassPool.getDefault();
        CtClass ctClass;
        try {
            ctClass = pool.get(clazz.getName());
            CtBehavior[] behaviors = ctClass.getDeclaredBehaviors();
            List<CtBehavior> withLineNumber = Arrays.asList(behaviors).stream().filter(input -> input.getMethodInfo().getLineNumber(0) > 0).sorted((o1, o2) -> Integer.valueOf(o1.getMethodInfo().getLineNumber(0)).compareTo(o2.getMethodInfo().getLineNumber(0))).collect(Collectors.toList());
            if (!withLineNumber.isEmpty()) {
                CtBehavior method = withLineNumber.get(0);
                int lineNumber = method.getMethodInfo().getLineNumber(0);
                ClassFile classFile = ctClass.getClassFile();
                String sourceFile = classFile.getSourceFile();
                if (lineNumber != -1 && sourceFile != null) {
                    stringBuilder.append("anonymous class ").append(clazz.getName()).append(" at approximately line ").append(lineNumber).append(" of ").append(sourceFile);
                    return;
                }
            }
        } catch (NotFoundException ignore) {
        // fall through
        }
    }
    stringBuilder.append(clazz.getName());
}
Also used : CtBehavior(javassist.CtBehavior) Arrays(java.util.Arrays) List(java.util.List) ClassFile(javassist.bytecode.ClassFile) Handler(ratpack.handling.Handler) NotFoundException(javassist.NotFoundException) CtBehavior(javassist.CtBehavior) CtClass(javassist.CtClass) Collectors(java.util.stream.Collectors) ClassPool(javassist.ClassPool) CtClass(javassist.CtClass) ClassFile(javassist.bytecode.ClassFile) ClassPool(javassist.ClassPool) NotFoundException(javassist.NotFoundException)

Example 7 with NotFoundException

use of javassist.NotFoundException 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);
    }
}
Also used : CtField(javassist.CtField) EnhancementException(org.hibernate.bytecode.enhance.spi.EnhancementException) NotFoundException(javassist.NotFoundException) CannotCompileException(javassist.CannotCompileException) CtMethod(javassist.CtMethod)

Example 8 with NotFoundException

use of javassist.NotFoundException in project hibernate-orm by hibernate.

the class PersistentAttributesEnhancer method handleBiDirectionalAssociation.

private void handleBiDirectionalAssociation(CtClass managedCtClass, CtField persistentField, CtMethod fieldWriter) throws NotFoundException, CannotCompileException {
    if (!PersistentAttributesHelper.isPossibleBiDirectionalAssociation(persistentField)) {
        return;
    }
    final CtClass targetEntity = PersistentAttributesHelper.getTargetEntityClass(managedCtClass, persistentField);
    if (targetEntity == null) {
        log.infof("Could not find type of bi-directional association for field [%s#%s]", managedCtClass.getName(), persistentField.getName());
        return;
    }
    final String mappedBy = PersistentAttributesHelper.getMappedBy(persistentField, targetEntity, enhancementContext);
    if (mappedBy == null || mappedBy.isEmpty()) {
        log.infof("Could not find bi-directional association for field [%s#%s]", managedCtClass.getName(), persistentField.getName());
        return;
    }
    // create a temporary getter and setter on the target entity to be able to compile our code
    final String mappedByGetterName = EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + mappedBy;
    final String mappedBySetterName = EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + mappedBy;
    CtMethod getter;
    CtMethod setter;
    boolean tmpTargetMethods = false;
    try {
        getter = targetEntity.getDeclaredMethod(mappedByGetterName);
        setter = targetEntity.getDeclaredMethod(mappedByGetterName);
    } catch (NotFoundException nfe) {
        getter = MethodWriter.addGetter(targetEntity, mappedBy, mappedByGetterName);
        setter = MethodWriter.addSetter(targetEntity, mappedBy, mappedBySetterName);
        tmpTargetMethods = true;
    }
    // code fragments to check loaded state. We don't want to trigger lazy loading in association management code
    String currentAssociationLoaded = String.format("%s.isPropertyInitialized(this.%s, \"%s\")", Hibernate.class.getName(), persistentField.getName(), mappedBy);
    String targetElementLoaded = String.format("%s.isPropertyInitialized(target, \"%s\")", Hibernate.class.getName(), mappedBy);
    String newAssociationLoaded = String.format("%s.isPropertyInitialized($1, \"%s\")", Hibernate.class.getName(), mappedBy);
    if (PersistentAttributesHelper.hasAnnotation(persistentField, OneToOne.class)) {
        // only unset when $1 != null to avoid recursion
        fieldWriter.insertBefore(String.format("  if (this.%1$s != null && %2$s && $1 != null) { this.%1$s.%3$s(null); }%n", persistentField.getName(), currentAssociationLoaded, mappedBySetterName));
        fieldWriter.insertAfter(String.format("  if ($1 != null && %s && $1.%s() != this) { $1.%s(this); }%n", newAssociationLoaded, mappedByGetterName, mappedBySetterName));
    }
    if (PersistentAttributesHelper.hasAnnotation(persistentField, OneToMany.class)) {
        boolean isMap = PersistentAttributesHelper.isAssignable(persistentField.getType(), Map.class.getName());
        String toArrayMethod = isMap ? "values().toArray()" : "toArray()";
        // only remove elements not in the new collection or else we would loose those elements
        // don't use iterator to avoid ConcurrentModException
        fieldWriter.insertBefore(String.format("  if (this.%3$s != null && %1$s) {%n" + "    Object[] array = this.%3$s.%2$s;%n" + "    for (int i = 0; i < array.length; i++) {%n" + "      %4$s target = (%4$s) array[i];%n" + "      if ($1 == null || !$1.contains(target)) { target.%5$s(null); }%n" + "    }%n" + "  }%n", currentAssociationLoaded, toArrayMethod, persistentField.getName(), targetEntity.getName(), mappedBySetterName));
        fieldWriter.insertAfter(String.format("  if ($1 != null && %1$s) {%n" + "    Object[] array = $1.%2$s;%n" + "    for (int i = 0; i < array.length; i++) {%n" + "      %4$s target = (%4$s) array[i];%n" + "      if (%3$s && target.%5$s() != this) { target.%6$s(this); }%n" + "    }%n" + "  }%n", newAssociationLoaded, toArrayMethod, targetElementLoaded, targetEntity.getName(), mappedByGetterName, mappedBySetterName));
    }
    if (PersistentAttributesHelper.hasAnnotation(persistentField, ManyToOne.class)) {
        fieldWriter.insertBefore(String.format("  if (this.%2$s != null && %1$s && this.%2$s.%3$s() != null) { this.%2$s.%3$s().remove(this); }%n", currentAssociationLoaded, persistentField.getName(), mappedByGetterName));
        // check .contains(this) to avoid double inserts (but preventing duplicates)
        fieldWriter.insertAfter(String.format("  if ($1 != null && %s) {%n" + "    java.util.Collection c = $1.%s();%n" + "    if (c != null && !c.contains(this)) { c.add(this); }%n" + "  }%n", newAssociationLoaded, mappedByGetterName));
    }
    if (PersistentAttributesHelper.hasAnnotation(persistentField, ManyToMany.class)) {
        if (PersistentAttributesHelper.isAssignable(persistentField.getType(), Map.class.getName()) || PersistentAttributesHelper.isAssignable(targetEntity.getField(mappedBy).getType(), Map.class.getName())) {
            log.infof("Bi-directional association for field [%s#%s] not managed: @ManyToMany in java.util.Map attribute not supported ", managedCtClass.getName(), persistentField.getName());
            return;
        }
        fieldWriter.insertBefore(String.format("  if (this.%2$s != null && %1$s) {%n" + "    Object[] array = this.%2$s.toArray();%n" + "    for (int i = 0; i < array.length; i++) {%n" + "      %3$s target = (%3$s) array[i];%n" + "      if ($1 == null || !$1.contains(target)) { target.%4$s().remove(this); }%n" + "    }%n" + "  }%n", currentAssociationLoaded, persistentField.getName(), targetEntity.getName(), mappedByGetterName));
        fieldWriter.insertAfter(String.format("  if ($1 != null && %s) {%n" + "    Object[] array = $1.toArray();%n" + "    for (int i = 0; i < array.length; i++) {%n" + "      %s target = (%s) array[i];%n" + "	   if (%s) {%n" + "        java.util.Collection c = target.%s();%n" + "        if (c != this && c != null) { c.add(this); }%n" + "      }%n" + "    }%n" + "  }%n", newAssociationLoaded, targetEntity.getName(), targetEntity.getName(), targetElementLoaded, mappedByGetterName));
    }
    if (tmpTargetMethods) {
        targetEntity.removeMethod(getter);
        targetEntity.removeMethod(setter);
    }
}
Also used : CtClass(javassist.CtClass) Hibernate(org.hibernate.Hibernate) NotFoundException(javassist.NotFoundException) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) CtMethod(javassist.CtMethod)

Example 9 with NotFoundException

use of javassist.NotFoundException 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);
        }
    }
}
Also used : ConstPool(javassist.bytecode.ConstPool) CtClass(javassist.CtClass) CodeIterator(javassist.bytecode.CodeIterator) ClassPool(javassist.ClassPool) EnhancementException(org.hibernate.bytecode.enhance.spi.EnhancementException) NotFoundException(javassist.NotFoundException) MethodInfo(javassist.bytecode.MethodInfo) BadBytecode(javassist.bytecode.BadBytecode)

Example 10 with NotFoundException

use of javassist.NotFoundException in project hibernate-orm by hibernate.

the class PersistentAttributesHelper method getterOrNull.

private static CtMethod getterOrNull(CtClass containerClass, String propertyName) {
    for (CtMethod method : containerClass.getDeclaredMethods()) {
        try {
            // if the method has parameters, skip it
            if (method.isEmpty() || method.getParameterTypes().length != 0) {
                continue;
            }
        } catch (NotFoundException e) {
            continue;
        }
        final String methodName = method.getName();
        // try "get"
        if (methodName.startsWith("get")) {
            String testStdMethod = Introspector.decapitalize(methodName.substring(3));
            String testOldMethod = methodName.substring(3);
            if (testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName)) {
                return method;
            }
        }
        // if not "get", then try "is"
        if (methodName.startsWith("is")) {
            String testStdMethod = Introspector.decapitalize(methodName.substring(2));
            String testOldMethod = methodName.substring(2);
            if (testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName)) {
                return method;
            }
        }
    }
    return null;
}
Also used : NotFoundException(javassist.NotFoundException) CtMethod(javassist.CtMethod)

Aggregations

NotFoundException (javassist.NotFoundException)35 CtClass (javassist.CtClass)26 CannotCompileException (javassist.CannotCompileException)19 CtMethod (javassist.CtMethod)15 ClassPool (javassist.ClassPool)12 IOException (java.io.IOException)5 CtField (javassist.CtField)5 EnhancementException (org.hibernate.bytecode.enhance.spi.EnhancementException)5 FileNotFoundException (java.io.FileNotFoundException)4 BadBytecode (javassist.bytecode.BadBytecode)4 CodeIterator (javassist.bytecode.CodeIterator)4 File (java.io.File)3 ArrayList (java.util.ArrayList)3 Bytecode (javassist.bytecode.Bytecode)3 CodeAttribute (javassist.bytecode.CodeAttribute)3 CompileError (javassist.compiler.CompileError)3 Javac (javassist.compiler.Javac)3 FileFilter (java.io.FileFilter)2 CtBehavior (javassist.CtBehavior)2 CtConstructor (javassist.CtConstructor)2