Search in sources :

Example 1 with WeavingData

use of org.apache.aries.spifly.WeavingData in project aries by apache.

the class ClientWeavingHook method weave.

@Override
public void weave(WovenClass wovenClass) {
    Bundle consumerBundle = wovenClass.getBundleWiring().getBundle();
    Set<WeavingData> wd = activator.getWeavingData(consumerBundle);
    if (wd != null) {
        activator.log(Level.FINE, "Weaving class " + wovenClass.getClassName());
        ClassReader cr = new ClassReader(wovenClass.getBytes());
        ClassWriter cw = new OSGiFriendlyClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES, wovenClass.getBundleWiring().getClassLoader());
        TCCLSetterVisitor tsv = new TCCLSetterVisitor(cw, wovenClass.getClassName(), wd);
        cr.accept(tsv, ClassReader.SKIP_FRAMES);
        if (tsv.isWoven()) {
            wovenClass.setBytes(cw.toByteArray());
            if (tsv.additionalImportRequired())
                wovenClass.getDynamicImports().add(addedImport);
            if (activator.isLogEnabled(Level.FINEST)) {
                StringWriter stringWriter = new StringWriter();
                ClassReader reader = new ClassReader(wovenClass.getBytes());
                ClassVisitor tracer = new TraceClassVisitor(new PrintWriter(stringWriter));
                ClassVisitor checker = new CheckClassAdapter(tracer, true);
                reader.accept(checker, 0);
                activator.log(Level.FINEST, "Woven class bytecode: \n" + stringWriter.toString());
            }
        }
    }
}
Also used : WeavingData(org.apache.aries.spifly.WeavingData) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) StringWriter(java.io.StringWriter) Bundle(org.osgi.framework.Bundle) CheckClassAdapter(org.objectweb.asm.util.CheckClassAdapter) ClassReader(org.objectweb.asm.ClassReader) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter) TCCLSetterVisitor(org.apache.aries.spifly.weaver.TCCLSetterVisitor) PrintWriter(java.io.PrintWriter)

Example 2 with WeavingData

use of org.apache.aries.spifly.WeavingData in project aries by apache.

the class TCCLSetterVisitor method visitEnd.

@Override
public void visitEnd() {
    if (!woven) {
        // if this class wasn't woven, then don't add the synthesized method either.
        super.visitEnd();
        return;
    }
    // Add generated static method
    Set<String> methodNames = new HashSet<String>();
    for (WeavingData wd : weavingData) {
        String methodName = getGeneratedMethodName(wd);
        if (methodNames.contains(methodName))
            continue;
        methodNames.add(methodName);
        if (ServiceLoader.class.getName().equals(wd.getClassName())) {
            continue;
        }
        /* Equivalent to:
              * private static void $$FCCL$$<className>$<methodName>(Class<?> cls) {
              *   Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
              * }
              */
        Method method = new Method(methodName, Type.VOID_TYPE, new Type[] { CLASS_TYPE });
        GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor(), null, null), ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor());
        // Load the strings, method parameter and target
        mv.visitLdcInsn(wd.getClassName());
        mv.visitLdcInsn(wd.getMethodName());
        mv.loadArg(0);
        mv.visitLdcInsn(targetClass);
        // Change the class on the stack into a classloader
        mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, new Type[0]));
        // Call our util method
        mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE, new Type[] { String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE }));
        mv.returnValue();
        mv.endMethod();
    }
    super.visitEnd();
}
Also used : ServiceLoader(java.util.ServiceLoader) Type(org.objectweb.asm.Type) WeavingData(org.apache.aries.spifly.WeavingData) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) HashSet(java.util.HashSet)

Example 3 with WeavingData

use of org.apache.aries.spifly.WeavingData in project aries by apache.

the class Main method weaveDir.

private static void weaveDir(File dir, String consumerHeaderKey, String consumerHeaderValue, String bundleClassPath) throws Exception {
    Set<WeavingData> wd = ConsumerHeaderProcessor.processHeader(consumerHeaderKey, consumerHeaderValue);
    URLClassLoader cl = new URLClassLoader(new URL[] { dir.toURI().toURL() }, Main.class.getClassLoader());
    String dirName = dir.getAbsolutePath();
    DirTree dt = new DirTree(dir);
    for (File f : dt.getFiles()) {
        if (!f.getName().endsWith(".class"))
            continue;
        String className = f.getAbsolutePath().substring(dirName.length());
        if (className.startsWith(File.separator))
            className = className.substring(1);
        className = className.substring(0, className.length() - ".class".length());
        className = className.replace(File.separator, ".");
        InputStream is = new FileInputStream(f);
        byte[] b;
        try {
            ClassReader cr = new ClassReader(is);
            ClassWriter cw = new StaticToolClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES, cl);
            TCCLSetterVisitor cv = new TCCLSetterVisitor(cw, className, wd);
            cr.accept(cv, ClassReader.SKIP_FRAMES);
            if (cv.isWoven()) {
                b = cw.toByteArray();
            } else {
                // if not woven, store the original bytes
                b = Streams.suck(new FileInputStream(f));
            }
        } finally {
            is.close();
        }
        OutputStream os = new FileOutputStream(f);
        try {
            os.write(b);
        } finally {
            os.close();
        }
    }
    if (bundleClassPath != null) {
        for (String entry : bundleClassPath.split(",")) {
            File jarFile = new File(dir, entry.trim());
            if (jarFile.isFile()) {
                weaveBCPJar(jarFile, consumerHeaderKey, consumerHeaderValue);
            }
        }
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) JarInputStream(java.util.jar.JarInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) JarOutputStream(java.util.jar.JarOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) FileInputStream(java.io.FileInputStream) ClassWriter(org.objectweb.asm.ClassWriter) TCCLSetterVisitor(org.apache.aries.spifly.weaver.TCCLSetterVisitor) WeavingData(org.apache.aries.spifly.WeavingData) URLClassLoader(java.net.URLClassLoader) FileOutputStream(java.io.FileOutputStream) ClassReader(org.objectweb.asm.ClassReader) File(java.io.File)

Aggregations

WeavingData (org.apache.aries.spifly.WeavingData)3 TCCLSetterVisitor (org.apache.aries.spifly.weaver.TCCLSetterVisitor)2 ClassReader (org.objectweb.asm.ClassReader)2 ClassWriter (org.objectweb.asm.ClassWriter)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 URLClassLoader (java.net.URLClassLoader)1 HashSet (java.util.HashSet)1 ServiceLoader (java.util.ServiceLoader)1 JarInputStream (java.util.jar.JarInputStream)1 JarOutputStream (java.util.jar.JarOutputStream)1 ClassVisitor (org.objectweb.asm.ClassVisitor)1 Type (org.objectweb.asm.Type)1 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)1