NanoN
NanoN

Reputation: 11

How to get class from field?

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

Answers (3)

Bharat Singh
Bharat Singh

Reputation: 1

Use getType() like below:

clz.getDeclaredField("fieldName").getType()

Upvotes: 0

user207421
user207421

Reputation: 311055

How to get class from field?

With fieldValue.getClass(). Reflection not required.

Your code makes no sense.

  • You have a method called 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

BabyGluk
BabyGluk

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

Related Questions