我有麻烦获得一个对象的声明字段,是缺失的/不使用特定的依赖关系。
Field[] fields = OBJECT.getClass().getDeclaredFields();
抛出一个NoClassDefFoundError
,当该对象有对缺失类的导入时。
我想这样做的原因是一个Bukkit插件。我想得到一个插件实例的字段,有缺失的依赖关系(他们没有使用,但插件可以启动)。
在运行时,插件将检查所需的依赖项是否存在,并根据它将加载这些特定的字段。
我想到的可能的解决方案:
1)虚拟创建丢失的类+包,然后使用ASM再次尝试。但是我真的不知道该怎么做。
问候,马克西姆
当缺少依赖项时为什么要关心字段?
如果发生这种情况,类在运行时不应该有实例。我不认为JRE会允许创建一个对象的实例,它的字段缺少类。
如果你读了getDeclaredMethods,它可能意味着什么。
ASM/BCEL是一个很好的方向,但不能实际上创建丢失的类(因为您不知道它们是谁)。您使用它们来读取/解析"类文件"来解码它的签名(即getDeclaredFields而不使用classloader)。
首先,确保你的目标插件在你的插件之前被加载:你可以通过在插件中添加这一行来强制它在插件之前加载。yml文件:
...
softdepend: [plugin_name1]
...
其中plugin_name1
是您的反射目标插件。
其次,你应该只获得字段,你需要从这个插件,而不是列出每个字段,但如果你想获得它的所有字段,只需反编译它的代码和自定义字段getter方法:
public ArrayList<Field> getFields(Class cl, String... analyze) {
ArrayList<Field> fields = new ArrayList<Field>();
for (String f : analyze) {
try {
Field field = cl.getDeclaredField(f);
field.setAccessible(true);
fields.add(field);
} catch (Throwable err) {}
}
return fields;
}