gpt4 book ai didi

java - 编译后从字节码中删除注释

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:55:10 25 4
gpt4 key购买 nike

我们使用的库包含使用 JAXB 注释进行注释的 bean。我们使用这些类的方式完全不依赖于 JAXB。换句话说,我们不需要 JAXB,也不依赖于注解。

但是,由于注解存在,它们最终会被其他处理注解的类引用。这要求我在我们的应用程序中 bundle JAXB,这是不允许的,因为 JAXB 在 javax.* 包中(Android 不允许“核心库”包含在您的应用程序中)。

因此,考虑到这一点,我正在寻找一种方法来从编译的字节代码中删除注释。我知道有一些实用程序可以处理字节码,但这对我来说还是很陌生。我该如何开始?

最佳答案

我推荐 BCEL 6。您也可以使用 ASM,但我听说 BCEL 更易于使用。这是使字段成为最终字段的快速测试方法:

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,所以我无法修改此示例以删除注释,但我想代码应该是这样的:

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;
}

关于java - 编译后从字节码中删除注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11092573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com