Search in sources :

Example 6 with ClassFile

use of javassist.bytecode.ClassFile in project audit4j-core by audit4j.

the class AnnotationDB method scanClass.

/**
 * Parse a .class file for annotations
 *
 * @param bits
 *            input stream pointing to .class file bits
 * @throws IOException
 */
public void scanClass(InputStream bits) throws IOException {
    DataInputStream dstream = new DataInputStream(new BufferedInputStream(bits));
    ClassFile cf = null;
    try {
        cf = new ClassFile(dstream);
        classIndex.put(cf.getName(), new HashSet<String>());
        if (scanClassAnnotations)
            scanClass(cf);
        if (scanMethodAnnotations || scanParameterAnnotations)
            scanMethods(cf);
        if (scanFieldAnnotations)
            scanFields(cf);
        // create an index of interfaces the class implements
        if (cf.getInterfaces() != null) {
            Set<String> intfs = new HashSet<String>();
            for (String intf : cf.getInterfaces()) intfs.add(intf);
            implementsIndex.put(cf.getName(), intfs);
        }
    } finally {
        dstream.close();
        bits.close();
    }
}
Also used : ClassFile(javassist.bytecode.ClassFile) BufferedInputStream(java.io.BufferedInputStream) DataInputStream(java.io.DataInputStream) HashSet(java.util.HashSet)

Example 7 with ClassFile

use of javassist.bytecode.ClassFile in project latke by b3log.

the class Discoverer method discover.

/**
 * Scans classpath to discover bean classes.
 *
 * @param scanPath the paths to scan, using ',' as the separator. There are two types of the scanPath:
 * <ul>
 *   <li>package: org.b3log.process</li>
 *   <li>ant-style classpath: org/b3log/** /*process.class</li>
 * </ul>
 * @return discovered classes
 * @throws Exception exception
 */
public static Collection<Class<?>> discover(final String scanPath) throws Exception {
    if (Strings.isEmptyOrNull(scanPath)) {
        throw new IllegalStateException("Please specify the [scanPath]");
    }
    LOGGER.debug("scanPath[" + scanPath + "]");
    // See issue #17 (https://github.com/b3log/latke/issues/17) for more details
    final Collection<Class<?>> ret = new HashSet<Class<?>>();
    final String[] splitPaths = scanPath.split(",");
    // Adds some built-in components
    final String[] paths = ArrayUtils.concatenate(splitPaths, BUILT_IN_COMPONENT_PKGS);
    final Set<URL> urls = new LinkedHashSet<URL>();
    for (String path : paths) {
        /*
             * the being two types of the scanPath.
             *  1 package: org.b3log.process
             *  2 ant-style classpath: org/b3log/** /*process.class
             */
        if (!AntPathMatcher.isPattern(path)) {
            path = path.replaceAll("\\.", "/") + "/**/*.class";
        }
        urls.addAll(ClassPathResolver.getResources(path));
    }
    for (URL url : urls) {
        final DataInputStream classInputStream = new DataInputStream(url.openStream());
        final ClassFile classFile = new ClassFile(classInputStream);
        final String className = classFile.getName();
        final AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) classFile.getAttribute(AnnotationsAttribute.visibleTag);
        if (null == annotationsAttribute) {
            LOGGER.log(Level.TRACE, "The class[name={0}] is not a bean", className);
            continue;
        }
        final ConstPool constPool = classFile.getConstPool();
        final Annotation[] annotations = annotationsAttribute.getAnnotations();
        boolean maybeBeanClass = false;
        for (final Annotation annotation : annotations) {
            if (annotation.getTypeName().equals(RequestProcessor.class.getName())) {
                // Request Processor is singleton scoped
                final Annotation singletonAnnotation = new Annotation("javax.inject.Singleton", constPool);
                annotationsAttribute.addAnnotation(singletonAnnotation);
                classFile.addAttribute(annotationsAttribute);
                classFile.setVersionToJava5();
                maybeBeanClass = true;
                break;
            }
            if (annotation.getTypeName().equals(Service.class.getName()) || (annotation.getTypeName()).equals(Repository.class.getName())) {
                // Service and Repository is singleton scoped by default
                maybeBeanClass = true;
                break;
            }
            if (annotation.getTypeName().equals(Named.class.getName())) {
                // Annoatated with Named maybe a bean class
                maybeBeanClass = true;
                break;
            }
        // Others will not load
        }
        if (maybeBeanClass) {
            Class<?> clz = null;
            try {
                clz = Thread.currentThread().getContextClassLoader().loadClass(className);
            } catch (final ClassNotFoundException e) {
                LOGGER.log(Level.ERROR, "some error to load the class[" + className + "]", e);
            }
            ret.add(clz);
        }
    }
    return ret;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ConstPool(javassist.bytecode.ConstPool) Named(org.b3log.latke.ioc.inject.Named) ClassFile(javassist.bytecode.ClassFile) AnnotationsAttribute(javassist.bytecode.AnnotationsAttribute) DataInputStream(java.io.DataInputStream) URL(java.net.URL) Annotation(javassist.bytecode.annotation.Annotation) RequestProcessor(org.b3log.latke.servlet.annotation.RequestProcessor) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 8 with ClassFile

use of javassist.bytecode.ClassFile in project libSBOLj by SynBioDex.

the class OBOTermCreator method createTerm.

// /**
// * Dynamically generates a Class file, for an interface that represents an OBO term with the given fields.
// *
// * The OBO term is uniquely identified by the id, and if a term with this id has been converted into a Class
// * file already, then that Class file (cached within the OBOTermCreator object) will be returned immediately.
// *
// * @param id
// * @param name
// * @param def
// * @param comments
// * @param is_a
// * @param relTypes
// * @param relTypedefs
// * @return term
// * @throws CannotCompileException
// */
public Class createTerm(String id, String name, String def, String[] comments, Class[] is_a, Class[] relTypes, String[] relTypedefs) throws CannotCompileException {
    String ccClassName = unmangleName(name);
    if (created.containsKey(id)) {
        return created.get(id);
    }
    if (created.containsKey(ccClassName)) {
        return created.get(ccClassName);
    }
    OBOAnnotationParser obo = new OBOAnnotationParser();
    ClassPool cp = ClassPool.getDefault();
    CtClass stringClass = null, stringArrayClass = null;
    try {
        stringClass = cp.get("java.lang.String");
        stringArrayClass = cp.get("java.lang.String[]");
    } catch (NotFoundException e) {
        throw new IllegalStateException(e);
    }
    CtClass cc = cp.makeInterface(ccClassName);
    cc.setModifiers(javassist.Modifier.INTERFACE | javassist.Modifier.PUBLIC);
    ClassFile ccFile = cc.getClassFile();
    ConstPool constpool = ccFile.getConstPool();
    Annotation termAnnotation = new Annotation("org.sc.obo.annotations.Term", constpool);
    CtField idField = new CtField(stringClass, "id", cc);
    idField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
    CtField nameField = new CtField(stringClass, "name", cc);
    nameField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
    CtField defField = new CtField(stringClass, "def", cc);
    defField.setModifiers(javassist.Modifier.PUBLIC | javassist.Modifier.STATIC | javassist.Modifier.FINAL);
    cc.addField(idField, CtField.Initializer.constant(removeSlashes(id)));
    cc.addField(nameField, CtField.Initializer.constant(removeSlashes(name)));
    cc.addField(defField, CtField.Initializer.constant(removeSlashes(def)));
    if (is_a != null) {
        for (Class superClass : is_a) {
            if (!obo.isTerm(superClass)) {
                throw new IllegalArgumentException(superClass.getCanonicalName());
            }
            try {
                CtClass superCtClass = cp.get(superClass.getCanonicalName());
                cc.addInterface(superCtClass);
            } catch (NotFoundException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }
    /*
		 * Finally, we convert all the relTypes/relTypedefs into methods.
		 *
		 * The main trick here is to do this in a way that the method names don't clash!
		 *
		 * We want to rename each method to a form that's unique to this class as well -- the reason is that
		 * Class A and Class B can have incompatible methods with the same name, which is fine since neither of
		 * them is a superclass (super-interface, whatevs) of the other.
		 *
		 * However, as soon as we define a Class C that extends both interfaces A & B, we have a problem -- suddenly
		 * we inherit both methods, but with incompatible types.
		 *
		 * So we need to mangle the names of A and B's classes, so that they are (a) descriptive, but (b) don't
		 * clash with other class's method names.  This leads to ugly code generation, but ... it works.
		 */
    if (relTypes != null && relTypedefs != null) {
        if (relTypes.length != relTypedefs.length) {
            throw new IllegalArgumentException();
        }
        String[] nonDups = renameDuplicates(relTypedefs);
        for (int i = 0; i < relTypes.length; i++) {
            try {
                if (relTypes[i] == null) {
                    throw new IllegalArgumentException(id + " " + Arrays.asList(relTypes));
                }
                Class arrayType = relTypes[i].isArray() ? relTypes[i] : getArrayType(relTypes[i]);
                String typeName = arrayType.getCanonicalName();
                String methodName = findNonConflictingName(ccClassName, arrayType, nonDups[i], null, is_a);
                CtClass relTypeClass = cp.get(typeName);
                CtMethod relMethod = new CtMethod(relTypeClass, methodName, new CtClass[] {}, cc);
                relMethod.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT);
                // We need to create this with the *original* typedef name,
                // not the new (non-clashing) method name.  That way, we can recover the original
                // name of the property from the (mangled) method name.
                Annotation relAnnotation = new Annotation("org.sc.obo.annotations.Relates", constpool);
                relAnnotation.addMemberValue("value", new StringMemberValue(relTypedefs[i], ccFile.getConstPool()));
                AnnotationsAttribute annotations = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
                annotations.addAnnotation(relAnnotation);
                relMethod.getMethodInfo().addAttribute(annotations);
                cc.addMethod(relMethod);
            } catch (NotFoundException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }
    AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
    attr.addAnnotation(termAnnotation);
    ccFile.addAttribute(attr);
    Class c = cc.toClass();
    created.put(id, c);
    created.put(ccClassName, c);
    return c;
}
Also used : ConstPool(javassist.bytecode.ConstPool) ClassFile(javassist.bytecode.ClassFile) StringMemberValue(javassist.bytecode.annotation.StringMemberValue) AnnotationsAttribute(javassist.bytecode.AnnotationsAttribute) ClassPool(javassist.ClassPool) NotFoundException(javassist.NotFoundException) Annotation(javassist.bytecode.annotation.Annotation) CtClass(javassist.CtClass) CtField(javassist.CtField) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod)

Example 9 with ClassFile

use of javassist.bytecode.ClassFile in project fakereplace by fakereplace.

the class FieldReplacementTransformer method addField.

/**
 * This will create a proxy with a non static field. This field does not
 * store anything, it merely provides a Field object for reflection. Attempts
 * to change and read it's value are redirected to the actual array based
 * store
 */
private static int addField(ClassLoader loader, FieldInfo m, Set<FieldProxyInfo> builder, Class<?> oldClass) {
    int fieldNo = FieldReferenceDataStore.instance().getFieldNo(m.getName(), m.getDescriptor());
    String proxyName = ProxyDefinitionStore.getProxyName();
    ClassFile proxy = new ClassFile(false, proxyName, "java.lang.Object");
    ClassDataStore.instance().registerProxyName(oldClass, proxyName);
    FieldAccessor accessor = new FieldAccessor(oldClass, fieldNo, (m.getAccessFlags() & AccessFlag.STATIC) != 0);
    ClassDataStore.instance().registerFieldAccessor(proxyName, accessor);
    proxy.setAccessFlags(AccessFlag.PUBLIC);
    FieldInfo newField = new FieldInfo(proxy.getConstPool(), m.getName(), m.getDescriptor());
    newField.setAccessFlags(m.getAccessFlags());
    copyFieldAttributes(m, newField);
    try {
        proxy.addField(newField);
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bytes);
        try {
            proxy.write(dos);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        ProxyDefinitionStore.saveProxyDefinition(loader, proxyName, bytes.toByteArray());
        builder.add(new FieldProxyInfo(newField, proxyName, m.getAccessFlags()));
    } catch (DuplicateMemberException e) {
    // can't happen
    }
    return fieldNo;
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) ClassFile(javassist.bytecode.ClassFile) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) FieldAccessor(org.fakereplace.reflection.FieldAccessor) FieldInfo(javassist.bytecode.FieldInfo)

Example 10 with ClassFile

use of javassist.bytecode.ClassFile in project fakereplace by fakereplace.

the class MethodReplacementTransformer method generateFakeConstructorBytecode.

/**
 * creates a class with a fake constructor that can be used by the reflection
 * api
 * <p>
 * Constructors are not invoked through the proxy class, instead we have to
 * do a lot more bytecode re-writing at the actual invocation sites
 */
private static String generateFakeConstructorBytecode(MethodInfo mInfo, ClassLoader loader) throws BadBytecode {
    String proxyName = ProxyDefinitionStore.getProxyName();
    ClassFile proxy = new ClassFile(false, proxyName, "java.lang.Object");
    proxy.setVersionToJava5();
    proxy.setAccessFlags(AccessFlag.PUBLIC);
    // add our new annotations directly onto the new proxy method. This way
    // they will just work without registering them with the
    // AnnotationDataStore
    String[] types = DescriptorUtils.descriptorStringToParameterArray(mInfo.getDescriptor());
    // as this method is never called the bytecode just returns
    Bytecode b = new Bytecode(proxy.getConstPool());
    b.add(Opcode.ALOAD_0);
    b.addInvokespecial("java.lang.Object", "<init>", "()V");
    b.add(Opcode.RETURN);
    MethodInfo method = new MethodInfo(proxy.getConstPool(), mInfo.getName(), mInfo.getDescriptor());
    method.setAccessFlags(mInfo.getAccessFlags());
    method.setCodeAttribute(b.toCodeAttribute());
    method.getCodeAttribute().computeMaxStack();
    method.getCodeAttribute().setMaxLocals(types.length + 1);
    copyMethodAttributes(mInfo, method);
    try {
        proxy.addMethod(method);
    } catch (DuplicateMemberException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bytes);
        proxy.write(dos);
        ProxyDefinitionStore.saveProxyDefinition(loader, proxyName, bytes.toByteArray());
        return proxyName;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) ClassFile(javassist.bytecode.ClassFile) DataOutputStream(java.io.DataOutputStream) BadBytecode(javassist.bytecode.BadBytecode) Bytecode(javassist.bytecode.Bytecode) MethodInfo(javassist.bytecode.MethodInfo) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException)

Aggregations

ClassFile (javassist.bytecode.ClassFile)51 DataInputStream (java.io.DataInputStream)15 ClassPool (javassist.ClassPool)15 DataOutputStream (java.io.DataOutputStream)14 CtClass (javassist.CtClass)14 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)14 ConstPool (javassist.bytecode.ConstPool)13 ByteArrayOutputStream (java.io.ByteArrayOutputStream)12 ByteArrayInputStream (java.io.ByteArrayInputStream)11 IOException (java.io.IOException)11 MethodInfo (javassist.bytecode.MethodInfo)11 CtField (javassist.CtField)10 NotFoundException (javassist.NotFoundException)9 Annotation (javassist.bytecode.annotation.Annotation)9 Test (org.junit.Test)9 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)8 HashSet (java.util.HashSet)7 CtMethod (javassist.CtMethod)7 FieldInfo (javassist.bytecode.FieldInfo)7 Bytecode (javassist.bytecode.Bytecode)5