从字节code编译后去除注释 [英] post-compilation removal of annotations from byte code

查看:311
本文介绍了从字节code编译后去除注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用的是包含被注解为JAXB标注豆库。没有在我们使用这些类的方法取决于JAXB。换句话说,我们不需要JAXB和不依赖于注释

we are using a library that contains beans that are annotated with JAXB annotations. nothing in the way we use these classes depends on JAXB. in other words, we don't need JAXB and do not depend on the annotations.

不过,因为注解存在,他们最终由处理注释的其它类被引用。这需要我在我们的应用程序,这是不允许的捆绑JAXB,因为JAXB是在的javax。* 包(安卓不允许核心库是包括在应用程序)。

however, because the annotations exist, they end up being referenced by other classes that process annotations. this requires me to bundle JAXB in our application, which isn't allowed, because JAXB is in the javax.* package (android doesn't allow "core libraries" to be included in your application).

因此​​,考虑到这一点,我正在寻找一种方式来从编译后的字节code删除注释。我知道有一些工具是操作字节code,但是这是一个相当新的给我。任何帮助入门为实现这一目标将是AP preciated。

so, with this in mind, i'm looking for a way to remove the annotations from the compiled byte code. i know there are utilities for manipulating byte code, but this is quite new to me. any help getting started toward this end would be appreciated.

推荐答案

我建议BCEL 6.您还可以使用ASM,但我听说BCEL更容易使用。这里是一个快速测试方法制作场决赛:

I recommend BCEL 6. You can also use ASM, but I hear BCEL is easier to use. Here is a quick test method for making a field final:

public static void main(String[] args) throws Exception {
    System.out.println(F.class.getField("a").getModifiers());
    JavaClass aClass = Repository.lookupClass(F.class);
    ClassGen aGen = new ClassGen(aClass);
    for (Field field : aGen.getFields()) {
        if (field.getName().equals("a")) {
            int mods = field.getModifiers();
            field.setModifiers(mods | Modifier.FINAL);
        }
    }
    final byte[] classBytes = aGen.getJavaClass().getBytes();
    ClassLoader cl = new ClassLoader(null) {
        @Override
        protected synchronized Class<?> findClass(String name) throws ClassNotFoundException {
            return defineClass("F", classBytes, 0, classBytes.length);
        }
    };
    Class<?> fWithoutDeprecated = cl.loadClass("F");
    System.out.println(fWithoutDeprecated.getField("a").getModifiers());
}

当然,你实际上写你的班列到磁盘文件,然后罐子起来,但是这是比较容易尝试的事情了。我没有BCEL 6得心应手,所以我不能修改这个例子删除注释,但我想在code会是这样的:

Of course, you would actually write your classes out to disk as files and then jar them up but this is easier for trying things out. I don't have BCEL 6 handy, so I can't modify this example to remove annotations, but I imagine the code would be something like:

public static void main(String[] args) throws Exception {
    ...
    ClassGen aGen = new ClassGen(aClass);
    aGen.setAttributes(cleanupAttributes(aGen.getAttributes()));
    aGen.getFields();
    for (Field field : aGen.getFields()) {
        field.setAttributes(cleanupAttributes(field.getAttributes()));
    }
    for (Method method : aGen.getMethods()) {
        method.setAttributes(cleanupAttributes(method.getAttributes()));
    }
    ...
}

private Attribute[] cleanupAttributes(Attribute[] attributes) {
    for (Attribute attribute : attributes) {
        if (attribute instanceof Annotations) {
            Annotations annotations = (Annotations) attribute;
            if (annotations.isRuntimeVisible()) {
                AnnotationEntry[] entries = annotations.getAnnotationEntries();
                List<AnnotationEntry> newEntries = new ArrayList<AnnotationEntry>();
                for (AnnotationEntry entry : entries) {
                    if (!entry.getAnnotationType().startsWith("javax")) {
                        newEntries.add(entry);
                    }
                }
                annotations.setAnnotationTable(newEntries);
            }
        }
    }
    return attributes;
}

这篇关于从字节code编译后去除注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆