Reputation: 11
I am trying to receive class field value via reflection. But when I call my code I receive exception: IllegalArgumentException: Can not set class field field to java.lang.Class. (I am calling from javaagent)
My code:
private static Class<?> GetInstance(Class<?> clz) throws NoSuchFieldException, IllegalAccessException {
Class<?> clazz1 = null;
Field f = clz.getDeclaredField("INSTANCE");
f.setAccessible(true);
clazz1 = f.get(clz).getClass();
return clazz1;
}
private static Class GetClassLoader(Class<?> clz) throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Field f = clz.getDeclaredField("classLoader");
f.setAccessible(true);
Class cls = f.get(clz).getClass();
return cls;
}
public static void agentmain(String agentArgs, Instrumentation inst){
try{
inst.addTransformer(new ClientTransfomer());
Class<?> FMLDeobfuscatingRemapper = null;
Class<?> InstanceClass;
Class<?>[] classes = inst.getAllLoadedClasses();
for(int i = 0;i < classes.length;i++){
if(classes[i].getName().contains("cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper")){
FMLDeobfuscatingRemapper = classes[i];
}
}
Class<?> instance = GetInstance(FMLDeobfuscatingRemapper);
Class cloader = GetClassLoader(instance);
Method m = cloader.getDeclaredMethod("findClass");
m.setAccessible(true);
m.invoke(null, "net.minecraft.client.entity.EntityClientPlayerMP");
}catch (Exception e){
}
Upvotes: 1
Views: 2555
Reputation: 1
Use getType() like below:
clz.getDeclaredField("fieldName").getType()
Upvotes: 0
Reputation: 311055
How to get class from field?
With fieldValue.getClass()
. Reflection not required.
Your code makes no sense.
GetInstance()
which returns a Class
, not an instance. You need to change the return value of this method to Object
and remove the getClass()
call inside it.You have a method called GetClassLoader()
which returns a Class
, not a ClassLoader
. You need to change the return type of this method to ClassLoader
, and remove the getClass()
call inside it.
You are then reflectively treating this object as though it was a ClassLoader
, which it isn't, and trying to call findClass()
on it.
But I can see no necessity for using a reflection at all here once you have the instance: you can just call getClass().getClassLoader().findClass()
directly.
Upvotes: 1
Reputation: 89
You mean something like that?
public class One {
public Two two = new Two();
}
public class Two {
public void hello(){
System.out.println("hello");
}
}
public static void main(String[] args) {
public static void main(String[] args) {
One one = new One();
Class<?> clazz = one.getClass();
try {
Field twoField = clazz.getField("two");
twoField.setAccessible(true);
Class<?> twoClazz =Class.forName(twoField.getType().getName());
Method method = twoClazz.getMethod("hello", null);
method.invoke(twoClazz.newInstance(), null);
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException | InstantiationException e) {
e.printStackTrace();
}
}
}
Upvotes: 0