Search in sources :

Example 6 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project maven-plugins by apache.

the class DefaultShader method addRemappedClass.

private void addRemappedClass(RelocatorRemapper remapper, JarOutputStream jos, File jar, String name, InputStream is) throws IOException, MojoExecutionException {
    if (!remapper.hasRelocators()) {
        try {
            jos.putNextEntry(new JarEntry(name));
            IOUtil.copy(is, jos);
        } catch (ZipException e) {
            getLogger().debug("We have a duplicate " + name + " in " + jar);
        }
        return;
    }
    ClassReader cr = new ClassReader(is);
    // We don't pass the ClassReader here. This forces the ClassWriter to rebuild the constant pool.
    // Copying the original constant pool should be avoided because it would keep references
    // to the original class names. This is not a problem at runtime (because these entries in the
    // constant pool are never used), but confuses some tools such as Felix' maven-bundle-plugin
    // that use the constant pool to determine the dependencies of a class.
    ClassWriter cw = new ClassWriter(0);
    final String pkg = name.substring(0, name.lastIndexOf('/') + 1);
    ClassVisitor cv = new RemappingClassAdapter(cw, remapper) {

        @Override
        public void visitSource(final String source, final String debug) {
            if (source == null) {
                super.visitSource(source, debug);
            } else {
                final String fqSource = pkg + source;
                final String mappedSource = remapper.map(fqSource);
                final String filename = mappedSource.substring(mappedSource.lastIndexOf('/') + 1);
                super.visitSource(filename, debug);
            }
        }
    };
    try {
        cr.accept(cv, ClassReader.EXPAND_FRAMES);
    } catch (Throwable ise) {
        throw new MojoExecutionException("Error in ASM processing class " + name, ise);
    }
    byte[] renamedClass = cw.toByteArray();
    // Need to take the .class off for remapping evaluation
    String mappedName = remapper.map(name.substring(0, name.indexOf('.')));
    try {
        // Now we put it back on so the class file is written out with the right extension.
        jos.putNextEntry(new JarEntry(mappedName + ".class"));
        IOUtil.copy(renamedClass, jos);
    } catch (ZipException e) {
        getLogger().debug("We have a duplicate " + mappedName + " in " + jar);
    }
}
Also used : MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) ClassReader(org.objectweb.asm.ClassReader) ZipException(java.util.zip.ZipException) ClassVisitor(org.objectweb.asm.ClassVisitor) JarEntry(java.util.jar.JarEntry) ClassWriter(org.objectweb.asm.ClassWriter)

Example 7 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project atlas by alibaba.

the class DataBindingRenameTask method createAwbPackages.

/**
     * 生成so的目录
     */
@TaskAction
void createAwbPackages() throws ExecutionException, InterruptedException {
    AndroidDependencyTree androidDependencyTree = AtlasBuildContext.androidDependencyTrees.get(getVariantName());
    if (null == androidDependencyTree) {
        return;
    }
    ExecutorServicesHelper executorServicesHelper = new ExecutorServicesHelper(taskName, getLogger(), 0);
    List<Runnable> runnables = new ArrayList<>();
    for (final AwbBundle awbBundle : androidDependencyTree.getAwbBundles()) {
        runnables.add(new Runnable() {

            @Override
            public void run() {
                try {
                    File dataBindingClazzFolder = appVariantOutputContext.getVariantContext().getJAwbavaOutputDir(awbBundle);
                    String packageName = ManifestFileUtils.getPackage(awbBundle.getOrgManifestFile());
                    String appName = appVariantContext.getVariantConfiguration().getOriginalApplicationId();
                    //删除那些已经存在的类
                    File dataMapperClazz = new File(dataBindingClazzFolder, "android/databinding/DataBinderMapper.class");
                    if (!dataMapperClazz.exists()) {
                        throw new GradleException("missing datamapper class");
                    }
                    FileInputStream fileInputStream = new FileInputStream(dataMapperClazz);
                    ClassReader in1 = new ClassReader(fileInputStream);
                    ClassWriter cw = new ClassWriter(0);
                    Map<String, String> reMapping = new HashedMap();
                    reMapping.put(appName.replace(".", "/") + "/BR", packageName.replace(".", "/") + "/BR");
                    RemappingClassAdapter remappingClassAdapter = new RemappingClassAdapter(cw, new SimpleRemapper(reMapping));
                    in1.accept(remappingClassAdapter, 8);
                    ClassReader in2 = new ClassReader(cw.toByteArray());
                    ClassWriter cw2 = new ClassWriter(0);
                    Set<String> renames = new HashSet<String>();
                    renames.add("android/databinding/DataBinderMapper");
                    in2.accept(new ClassRenamer(cw2, renames, packageName.replace(".", "/") + "/DataBinderMapper"), 8);
                    File destClass = new File(dataBindingClazzFolder, packageName.replace(".", "/") + "/DataBinderMapper.class");
                    destClass.getParentFile().mkdirs();
                    FileOutputStream fileOutputStream = new FileOutputStream(destClass);
                    fileOutputStream.write(cw2.toByteArray());
                    IOUtils.closeQuietly(fileOutputStream);
                    IOUtils.closeQuietly(fileInputStream);
                    FileUtils.deleteDirectory(new File(dataBindingClazzFolder, "android/databinding"));
                    FileUtils.deleteDirectory(new File(dataBindingClazzFolder, "com/android/databinding"));
                    File appDir = new File(dataBindingClazzFolder, appName.replace(".", "/"));
                    if (appDir.exists()) {
                        File[] files = appDir.listFiles(new FileFilter() {

                            @Override
                            public boolean accept(File pathname) {
                                return pathname.isFile() && !pathname.isDirectory();
                            }
                        });
                        for (File tmp : files) {
                            FileUtils.forceDelete(tmp);
                        }
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                    throw new GradleException("package awb failed");
                }
            }
        });
    }
    executorServicesHelper.execute(runnables);
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) AndroidDependencyTree(com.taobao.android.builder.dependency.AndroidDependencyTree) FileInputStream(java.io.FileInputStream) ExecutorServicesHelper(com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper) SimpleRemapper(org.objectweb.asm.commons.SimpleRemapper) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) GradleException(org.gradle.api.GradleException) FileOutputStream(java.io.FileOutputStream) AwbBundle(com.taobao.android.builder.dependency.model.AwbBundle) HashedMap(org.apache.commons.collections.map.HashedMap) FileFilter(java.io.FileFilter) File(java.io.File) Map(java.util.Map) HashedMap(org.apache.commons.collections.map.HashedMap) MtlBaseTaskAction(com.taobao.android.builder.tasks.manager.MtlBaseTaskAction) TaskAction(org.gradle.api.tasks.TaskAction)

Example 8 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project drill by apache.

the class MergeAdapter method getMergedClass.

public static MergedClassResult getMergedClass(final ClassSet set, final byte[] precompiledClass, ClassNode generatedClass, final boolean scalarReplace) {
    if (verifyBytecode) {
        if (!AsmUtil.isClassBytesOk(logger, "precompiledClass", precompiledClass)) {
            throw new IllegalStateException("Problem found in precompiledClass");
        }
        if ((generatedClass != null) && !AsmUtil.isClassOk(logger, "generatedClass", generatedClass)) {
            throw new IllegalStateException("Problem found in generatedClass");
        }
    }
    /*
     * Setup adapters for merging, remapping class names and class writing. This is done in
     * reverse order of how they will be evaluated.
     */
    final RemapClasses re = new RemapClasses(set);
    try {
        if (scalarReplace && generatedClass != null) {
            if (logger.isDebugEnabled()) {
                AsmUtil.logClass(logger, "generated " + set.generated.dot, generatedClass);
            }
            final ClassNode generatedMerged = new ClassNode();
            ClassVisitor mergeGenerator = generatedMerged;
            if (verifyBytecode) {
                mergeGenerator = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, generatedMerged), true);
            }
            /*
         * Even though we're effectively transforming-creating a new class in mergeGenerator,
         * there's no way to pass in ClassWriter.COMPUTE_MAXS, which would save us from having
         * to figure out stack size increases on our own. That gets handled by the
         * InstructionModifier (from inside ValueHolderReplacement > ScalarReplacementNode).
         */
            generatedClass.accept(new ValueHolderReplacementVisitor(mergeGenerator, verifyBytecode));
            if (verifyBytecode) {
                if (!AsmUtil.isClassOk(logger, "generatedMerged", generatedMerged)) {
                    throw new IllegalStateException("Problem found with generatedMerged");
                }
            }
            generatedClass = generatedMerged;
        }
        final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        ClassVisitor writerVisitor = writer;
        if (verifyBytecode) {
            writerVisitor = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, writerVisitor), true);
        }
        ClassVisitor remappingAdapter = new RemappingClassAdapter(writerVisitor, re);
        if (verifyBytecode) {
            remappingAdapter = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, remappingAdapter), true);
        }
        ClassVisitor visitor = remappingAdapter;
        if (generatedClass != null) {
            visitor = new MergeAdapter(set, remappingAdapter, generatedClass);
        }
        ClassReader tReader = new ClassReader(precompiledClass);
        tReader.accept(visitor, ClassReader.SKIP_FRAMES);
        byte[] outputClass = writer.toByteArray();
        if (logger.isDebugEnabled()) {
            AsmUtil.logClassFromBytes(logger, "merged " + set.generated.dot, outputClass);
        }
        return new MergedClassResult(outputClass, re.getInnerClasses());
    } catch (Error | RuntimeException e) {
        logger.error("Failure while merging classes.", e);
        AsmUtil.logClass(logger, "generatedClass", generatedClass);
        throw e;
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassVisitor(org.objectweb.asm.ClassVisitor) ValueHolderReplacementVisitor(org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor) ClassWriter(org.objectweb.asm.ClassWriter) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) ClassReader(org.objectweb.asm.ClassReader)

Example 9 with RemappingClassAdapter

use of org.objectweb.asm.commons.RemappingClassAdapter in project cdap by caskdata.

the class LogPipelineCheckTest method renameClass.

/**
   * Generates the bytecode of a new class with the given name using the given class as the skeleton.
   */
private byte[] renameClass(final Class<?> cls, final String newClassName) throws IOException {
    ClassReader cr = new ClassReader(cls.getName());
    ClassWriter cw = new ClassWriter(0);
    final String oldTypeName = Type.getInternalName(cls);
    cr.accept(new RemappingClassAdapter(cw, new Remapper() {

        @Override
        public String mapType(String type) {
            return oldTypeName.equals(type) ? newClassName : type;
        }
    }), 0);
    return cw.toByteArray();
}
Also used : RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter) Remapper(org.objectweb.asm.commons.Remapper) ClassReader(org.objectweb.asm.ClassReader) ClassWriter(org.objectweb.asm.ClassWriter)

Aggregations

RemappingClassAdapter (org.objectweb.asm.commons.RemappingClassAdapter)9 ClassReader (org.objectweb.asm.ClassReader)7 ClassWriter (org.objectweb.asm.ClassWriter)7 ClassVisitor (org.objectweb.asm.ClassVisitor)3 JarEntry (java.util.jar.JarEntry)2 ZipException (java.util.zip.ZipException)2 Remapper (org.objectweb.asm.commons.Remapper)2 ClassNode (org.objectweb.asm.tree.ClassNode)2 AndroidDependencyTree (com.taobao.android.builder.dependency.AndroidDependencyTree)1 AwbBundle (com.taobao.android.builder.dependency.model.AwbBundle)1 MtlBaseTaskAction (com.taobao.android.builder.tasks.manager.MtlBaseTaskAction)1 ExecutorServicesHelper (com.taobao.android.builder.tools.concurrent.ExecutorServicesHelper)1 File (java.io.File)1 FileFilter (java.io.FileFilter)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1