what am i missing here?
I get the exception: java.lang.IllegalArgumentException: object is not an instance of declaring class
public boolean onSave(Object entity,Serializable id,Object[] state, String[] propertyNames, Type[] types) {
Class<?> clazz=entity.getClass();
System.out.println(" Clazzz is:"+clazz);
Method[] methods = clazz.getMethods();
for(Method method : methods){
if(method.getName().startsWith("get") && String.class.equals(method.getReturnType())){
System.out.println("getter: " + method);
try {
String s=(String) method.invoke(clazz,(Object[]) null); //java.lang.IllegalArgumentException: object is not an instance of declaring class
System.out.println(" value in s is:"+s);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You need to write
String s=(String) method.invoke(entity, (Object[]) null);
The first parameter of Method.invoke is null for static methods or the object on which the method should be invoked.
Related
I want to invoke setApiHelper method in the below code using java reflection. How can I do so?
object PlayerUtils {
private var apiHelper: String? = null
fun setApiHelper(apiHelper: String) {
this.apiHelper = apiHelper
println(apiHelper)
}
fun getApiHelper(): String? {
return this.apiHelper
}
}
My Implementation
private static void testingPlayerUtils() {
try {
Class<?> cls = Class.forName("reflection.PlayerUtils");
cls.newInstance();
Method method = cls.getDeclaredMethod("setApiHelper");
method.invoke(cls.newInstance(), "TESTING");
} catch (ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
this gives an error
java.lang.IllegalAccessException: Class TestingReflection2 can not access a member of class reflection.PlayerUtils with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at TestingReflection2.testingPlayerUtils(TestingReflection2.java:20)
at TestingReflection2.main(TestingReflection2.java:14)
Usually when you want to access object declared in Kotlin using Java code, you can do like below code snippet:
PlayerUtils.INSTANCE.setApiHelper("");
//or
PlayerUtils.INSTANCE.getApiHelper();
Now that being said, in order to access methods of PlayerUtils in Java using reflection, you'll need to access it's static member called INSTANCE first.
And you can do that by using Field from Class declaration, something like below:
Class<?> cls = Class.forName("reflection.PlayerUtils");
Object instance = cls.getField("INSTANCE");
Method method = cls.getDeclaredMethod("setApiHelper");
method.invoke(instance, "TESTING");
Refer here for detailed info.
You need to set accessible true for the method as below -
Class<?> cls = Class.forName("reflection.PlayerUtils");
cls.newInstance();
Method method = cls.getDeclaredMethod("setApiHelper");
method.setAccessible(true);
method.invoke(cls.newInstance(), "TESTING");
I want to block a phone call and i try using reflection android.telecom.Call class with following code but this class does not has constructor .
try {
Class c = Class.forName("android.telecom.Call");
Method m = c.getMethod("disconnect");
m.setAccessible(true);
Object o = m.invoke(c, new Object[] {});
} catch (Exception e) {
Log.e("Exception of Reflection", e.getLocalizedMessage());
}
You need to instantiate Class Call because you'll use the instance as a target for you method invocation.
The method getMethod ignores non-public method. You should use getDeclaredMethod to find your private method.
Your code may look like this:
try
{
Class<?> c = Class.forName("android.telecom.Call");
Object instance = c.newInstance();
Method m = c.getDeclaredMethod("disconnect");
m.setAccessible(true);
m.invoke(instance, new Object[] {});
}
catch (Exception e)
{
Log.e("Exception of Reflection", e.getLocalizedMessage());
}
I am trying to invoke a static method with a Object[] parameter type. When I debug, the correct method is identified and the parameter type I put in seems to me to be of the correct type.
public String convertToJSFunction(Method method, Object[] params) {
String function = method.getName();
for (Method m : JavaToJS.class.getDeclaredMethods()) {
if (m.getName().equals(function))
try {
return (String) m.invoke(null,params);
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
} catch (InvocationTargetException e) {
e.printStackTrace();
return null;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
}
return null;
}
JavaToJS has only static methods. After debugging, the m I am trying to invoke is this method:
public static String setRegionNumber(Object[] params)
This throws an IllegalArgumentException: argument type mismatch. How is this possible?
i guess you are calling
Method setRegionNumber=...; // "setRegionNumber" Method
Object[] params=...; // your Object-Array Parameter
convertToJSFunction(setRegionNumber, params);
but what you need to do is
Method setRegionNumber=...; // "setRegionNumber" Method
Object[] params=...; // your Object-Array Parameter
convertToJSFunction(setRegionNumber, new Object[] { params });
this is because Method.invoke expects the parameter list of the called method as an object Array. So if you pass your object array directly then it interprets that as the parameter list. so if you have an Object[] Parameter you need to wrap it in an Object-Array just like any other parameter.
I have this method that is supposed to set a field in the given class to the specified value:
public void setValue(Class<?> instance, String fieldName, Object value) {
try {
Field field = instance.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(instance, value);
} catch (NoSuchFieldException e) {
if (instance.getSuperclass() != null) {
setValue(instance.getSuperclass(), fieldName, value);
} else {
try {
throw new NoSuchFieldException("Could not find field " + fieldName + " in any class.");
} catch (NoSuchFieldException ex) {
ex.printStackTrace();
e.printStackTrace();
}
}
} catch (SecurityException | IllegalArgumentException | IllegalAccessException exx) {
exx.printStackTrace();
}
}
However, it gives this error when I try to set any field:
java.lang.IllegalArgumentException: Can not set float field net.minecraft.server.v1_6_R2.Packet43SetExperience.a to java.lang.Class
I have tried using an Object(instead of an Class) but it never finds the field that I need, it only finds the fields that the Object class has.
I also tried using generics, but the same thing happened.
You need to have the actual instance of the object to pass in to the set method, not the Class object itself. Add a parameter to your method to take the actual instance:
public void setValue(Class<?> clazz, Object instance, String fieldName, Object value) {
I renamed the Class<?> parameter clazz for clarity, so it would need to be changed elsewhere:
Field field = clazz.getDeclaredField(fieldName);
And pass the actual instance to set:
field.set(instance, value);
I have a 2 POJO classes with getters and setters,now i am trying to get all the class instance variables of that class.
I got to know that we can use reflection how to do it?
This is my POJO Class which will extend my reflection class.
class Details{
private int age;
private String name;
}
Reflection class is like this:
class Reflection{
public String toString(){
return all the fields of that class
}
You could do something like this:
public void printFields(Object obj) throws Exception {
Class<?> objClass = obj.getClass();
Field[] fields = objClass.getFields();
for(Field field : fields) {
String name = field.getName();
Object value = field.get(obj);
System.out.println(name + ": " + value.toString());
}
}
This would only print the public fields, to print private fields use class.getDeclaredFields recursively.
Or if you would extend the class:
public String toString() {
try {
StringBuffer sb = new StringBuffer();
Class<?> objClass = this.getClass();
Field[] fields = objClass.getFields();
for(Field field : fields) {
String name = field.getName();
Object value = field.get(this);
sb.append(name + ": " + value.toString() + "\n");
}
return sb.toString();
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
Adding one more line to the above code. If you want to access the private properties of the class use below line
field.setAccessible(true);
ClassLoader classLoader = Main.class.getClassLoader();
try {
Class cls = classLoader.loadClass("com.example.Example");
Object clsObject = cls.newInstance();
Field[] fields = cls.getFields();
for (Field field : fields) {
String name = field.getName();
Object value = field.get(clsObject);
System.out.println("Name : "+name+" Value : "+value);
}
System.out.println(cls.getName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The resolution code or answer which mentioned above has one issue.
To access the value of a private varible their access type must be set to true
Field[] fields = objClass.getDeclaredFields();
for (Field field : fields) {
NotNull notNull = field.getAnnotation(NotNull.class);
field.setAccessible(true);
}
else it will throw java.lang.IllegalAccessException. Class Reflection can not access a member of class Details with modifiers "private"