Showing posts with label Reflection. Show all posts

How to invoke(call) Setter and Getter method of field(variable) using Reflection?


In my previous article we've seen How to get fields(variables) name and type of class using Reflection?. Now its time to know how you can set value and get value of field using reflection.

Source Code
I've created some sample bean for example.
/* Actor.java */
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Actor {
   private long id;
   private String Name;
   private Set Films;
   private List LanguageSpeaks;
   private Map dummyMap;
}

public String getName() {
   return Name;
}
public void setName(String name) {
   Name = name;
}
/* Other Setter and Getter methods */

Source Code
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;

public class InvokeSetterGetter {

   public static void main(String[] args) {
    /* Create object of Actor. */
    Actor objActor = new Actor();

    InvokeSetterGetter objInvokeSetterGetter = new InvokeSetterGetter();
    /* Call invokeSetter method */
    objInvokeSetterGetter.invokeSetter(objActor, "Name", "Benedict Cumberbatch");
    /* Call invokeGetter method */
    objInvokeSetterGetter.invokeGetter(objActor, "Name");
   }
 
   private void invokeSetter(Object obj, String variableName, Object variableValue){
      /* variableValue is Object because value can be an Object, Integer, String, etc... */
      try {
        /**
         * Get object of PropertyDescriptor using variable name and class
         * Note: To use PropertyDescriptor on any field/variable, the field must have both `Setter` and `Getter` method.
         */
         PropertyDescriptor objPropertyDescriptor = new PropertyDescriptor(variableName, obj.getClass());
         /* Set field/variable value using getWriteMethod() */
         objPropertyDescriptor.getWriteMethod().invoke(obj, variableValue);
      } catch (IllegalAccessException | IllegalArgumentException
        | InvocationTargetException | IntrospectionException e) {
        /* Java 8: Multiple exception in one catch. Use Different catch block for lower version. */
        e.printStackTrace();
      }
   }

   private void invokeGetter(Object obj, String variableName){
      try {
        /**
         * Get object of PropertyDescriptor using variable name and class
         * Note: To use PropertyDescriptor on any field/variable, the field must have both `Setter` and `Getter` method.
         */
         PropertyDescriptor objPropertyDescriptor = new PropertyDescriptor(variableName, obj.getClass());
        /**
         * Get field/variable value using getReadMethod()
         * variableValue is Object because value can be an Object, Integer, String, etc...
         */
         Object variableValue = objPropertyDescriptor.getReadMethod().invoke(obj);
        /* Print value of variable */
         System.out.println(variableValue);
      } catch (IllegalAccessException | IllegalArgumentException
        | InvocationTargetException | IntrospectionException e) {
       /* Java 8: Multiple exception in one catch. Use Different catch block for lower version. */
        e.printStackTrace();
      }
   }
}

How to get fields(variables) name and type of class using Reflection?

Java Reflection
Reflection API is used to interact, examine or modify run-time behavior of programs running in the Java virtual machine. Reflection is bit costly so use it only when you have no other options left. Today we'll see how you can get name and type of fields(variables) declared in class.

Source Code
I've created some sample beans for example.
/* Actor.java */
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Actor {
   private long id;
   private String Name;
   private Set<Film> Films;
   private List<Language> LanguageSpeaks;
   private Map<string long=""> dummyMap;
}

/* Film.java */
public class Film {
   private long id;
   private String Name;
}

/* Language.java */
public class Language {
   private long id;
   private String Name;
}

Source Code
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;

public class ClassFieldsReflection {
   public static void main(String[] args) {
      ClassFieldsReflection objClassFieldsReflection = new ClassFieldsReflection();
      objClassFieldsReflection.AccessFieldsUsingReflection(new Actor());
   }
 
   /**
    * Access fields of Object using Reflection.
    * @param obj
    */
   private void AccessFieldsUsingReflection(Object obj){
      /* Get array of fields declared in Class */
      Field[] fields = obj.getClass().getDeclaredFields();
      /* Loop through all fields */
      for(int i = 0; i < fields.length ; i++){
         /* Get field name */
         String fieldName = fields[i].getName();
         /* Get generic/base type of field (int, short, long, String, etc...) */
         Object fieldType = fields[i].getGenericType();
  
         System.out.println("Field(variable) name: " + fieldName);
         System.out.println("Generic Type: " + fieldType);
   
         /* Set<E>, List<E> and Map<K,V> are ParameterizedType */
         if(fieldType instanceof ParameterizedType){
           /**
            * This will give you Actual Type of Set<E>, List<E> and Map<K,V>.
            * Example:
            * List<String> -> String is ActualType
            * Set<Integer> -> Integer is ActualType
            * Map<String, Long> -> String, Long is ActualType
            */
            System.out.println("Actual Type:");
            for(Object objActualType : ((ParameterizedType) fieldType).getActualTypeArguments()){
                 System.out.println("-- "+objActualType);
            }
         }
         System.out.println("+++++++++++++++++++++++++++++++");
      }
   }
}

Output
Field(variable) name: id
Generic Type: long
+++++++++++++++++++++++++++++++
Field(variable) name: Name
Generic Type: class java.lang.String
+++++++++++++++++++++++++++++++
Field(variable) name: Films
Generic Type: java.util.Set
Actual Type:
-- class javaQuery.beans.Film
+++++++++++++++++++++++++++++++
Field(variable) name: LanguageSpeaks
Generic Type: java.util.List
Actual Type:
-- class javaQuery.beans.Language
+++++++++++++++++++++++++++++++
Field(variable) name: dummyMap
Generic Type: java.util.Map
Actual Type:
-- class java.lang.String
-- class java.lang.Long
+++++++++++++++++++++++++++++++

How to inject code at runtime in Java?

javassist example


Its been never easy for me to believe that you can inject code into existing method without changing its original code but this can also happens using library javassist.

javassist
Javassist (Java Programming Assistant) allows you to manipulate bytecode. It enables Java programs to define a new class at runtime and to modify a class file when the JVM loads it. Read more about plug-in on http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/.

Shigeru Chiba originally created this library now its sub project of Jboss organization. You can read more about author on his blog http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/site/.

Source code background
We created two class files 1. SampleCodeJavassist and 2. CommonUtil under package javaQuery.javassist. You can have your own package name.

Source Code
package javaQuery.javassist;

public class CommonUtil {
    public void printToConsole() {
        System.out.println("javaQuery");
    }
}
/**
 * @author javaQuery
 */
package javaQuery.javassist;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

public class SampleCodeJavassist {
    public static void main(String[] args) throws Exception {
        /* Create object of ClassPool */
        ClassPool objClassPool = ClassPool.getDefault();
        /**
         * Create an object of CtClass.
         * Get the instance of class you want to inject the code.
         * Be careful while accessing the class. You have to specify whole the package name.
         */
        CtClass objCtClass = objClassPool.get("javaQuery.javassist.CommonUtil");
        /**
         * Create an object of CtMethod.
         * Get the method where you want to inject the code.
         */
        CtMethod objCtMethod = objCtClass.getDeclaredMethod("printToConsole");
        /* Inject the code at the begging of the method */
        objCtMethod.insertBefore("{ System.out.println(\"Hello World! at the beggining of method [Runtime from Test class]\"); }");
        /* Inject the code at the end of the method */
        objCtMethod.insertAfter("{ System.out.println(\"Hello World! at the end of method [Runtime from Test class]\"); }");
        /* Create an object of Class */
        Class objClass = objCtClass.toClass();
        /* Create an instance of CommonUtil class using objClass */
        CommonUtil objCommonUtil = (CommonUtil)objClass.newInstance();
        /* Execute method printToConsole */
        objCommonUtil.printToConsole();
    }
}

//output
Hello World! at the beggining of method [Runtime from Test class]
javaQuery
Hello World! at the end of method [Runtime from Test class]
This article is just to give you basic information of plug-in. Read more about plug-in on official website http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/.

jd-gui best Java Decompiler ever...

What is de-compiling?
Its a process of extracting original code from its compiled code ("*.class", "*.jar", "*.dll", etc... files).

Some of you may not know that any code which is not obfuscate can be de-compile. It sounds disappointing for the first time however helpful in some situation. It might possible your system gets crash but you uploaded yout jar bundle on web. So you can de-compile that code and get your original code back. Now lets move to the jd-gui Java Decompiler.

JD-GUI
JD-GUI is a standalone graphical utility that displays Java source codes of ".class",".jar" files. You can have your own free copy of jd-gui.

Features:
      1. Drag and drop file open.
      2. Search within code.
      3. Line number of code.
      4. Save Source file.
      5. Multi tab.

Download : http://jd.benow.ca/

jd-gui


For best practice open reference libraries and class files by drag and drop or by simply opening file from menubar. Methods using reference libraries or class file will be referenced by navigator itself. Methods/objects with underline is one whose reference available in navigator.