Thursday, 28 April 2016

Java Reflection

Introduction -
Reflection is a powerful feature of a programming language that enables it to provide the ability to examine, inspect, “reflect on” or modify the structure of programs at runtime. Not all programming languages support it but the concepts and the principles related to it are usually the same in languages that support it.

Reflection in Java -
In Java, Reflection is a mechanism by which it exposes the features of a class during runtime thereby making it possible to enumerate and access the class’ fields, constructors, methods as objects. More specifically, Java provides object-based mirrors that reflect the Java object model and these objects can be used to access the object’s features at runtime using the runtime API constructs instead of compile-time language constructs.

Each object instance has a getClass() method, inherited from java.lang.Object, which returns an object with the runtime representation of that object's class; this object is an instance of the java.lang.Class, which in turn has methods that return the fields, methods, constructors, superclass, and other properties of that class. We can use these reflection objects to access fields, invoke methods, or instantiate instances, all without having compile-time dependencies on those features.

Reflection is a powerful technique and can enable applications to perform operations which would otherwise be impossible. But it should be used carefully as it is rightly said, “With great power comes great responsibility”. If it is possible to perform a task without reflection, then it is preferable to avoid using it because of some concerns related with reflection.

Performance concerns -
The Java virtual machine performs some internal optimizations for normal non-reflective code but as Reflection involves types that are dynamically resolved, these optimizations are not performed as a result of which the reflective operations are slower compared to their non-reflective counterparts. So reflection should be strictly avoided in sections of frequently accessed code in performance sensitive applications.

Exposure of Internals -
The use of reflection can cause unexpected side-effects, since it allows code to perform operations that are strictly speaking not legal in non-reflective code, such as accessing private fields and methods.

Demonstration -
Let’s see an example now where we will load a class “Employee” and access its fields and invoke its methods using reflection.

Employee.java
The java class whose fields will be accessed and methods will be invoked using reflection.

package reflectiondemo;

public class Employee {

   public int EmployeeAge;
   public String EmployeeName;

   public void printEmployeeName() {
       System.out.println("Employee Name : " + EmployeeName);
   }
   
   public void printEmployeeAge() {
       System.out.println("Employee Age : " + EmployeeAge);
   }

   public void setAndPrintEmployeeAge(int Age) {
       EmployeeAge = Age;
       System.out.println("Employee Age : " + EmployeeAge);
   }
}

ReflectionDemo.java
This class will load the “Employee” class, create it’s new instance and access its fields and call its methods at runtime. The code is supplemented by self-explanatory comments.

package reflectiondemo;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionDemo {
   public static void main(String[] args) {
       try {
           //a Class array for invoking a no paramater method
           Class noparams[] = {};

           //a Class array for invoking a method with int parameter
           Class[] paramInt = new Class[1];
           paramInt[0] = Integer.TYPE;

           //load the Employee class at runtime
           Class cls = Class.forName("reflectiondemo.Employee");
           
           //create a new instance of the Employee class
           Object obj = cls.newInstance();

           //get the field EmployeeAge
           Field fieldEmployeeAge = cls.getField("EmployeeAge");

           //set the EmployeeAge of the instance of Employee class
           fieldEmployeeAge.set(obj, 25);

           //get the field EmployeeName
           Field fieldEmployeeName = cls.getField("EmployeeName");

           //set the EmployeeName of the instance of Employee class
           fieldEmployeeName.set(obj, "John");

           //call the printEmployeeName method
           Method method = cls.getDeclaredMethod("printEmployeeName",noparams);
           method.invoke(obj, null);

           //call the printEmployeeAge method
           method = cls.getDeclaredMethod("printEmployeeAge", noparams);
           method.invoke(obj, null);

           //call the setAndPrintEmployeeAge method, pass a int param
           method = cls.getDeclaredMethod("setAndPrintEmployeeAge", paramInt);
           method.invoke(obj, 35);

       } catch (Exception ex) {
           ex.printStackTrace();
       }
   }
}


Output -
Employee Name : John
Employee Age : 25
Employee Age : 35


Conclusion -
To conclude, we have seen an overview of Reflection in Java, a related example demonstrating the use of Reflection API and some concerns related to the usage of reflection which point that it should be used carefully to avoid performance overhead and some related side-effects.


Friday, 8 April 2016

Netbeans - Background Scanning Optimization

Introduction :
People using NetBeans for Java development must have encountered the “Background scanning of projects...” message every now and then. This usually happens on opening the IDE, during project build operations or changing any resource used in an open project externally outside NetBeans.


Background scanning is quite essential and important otherwise some productivity features such as code completion, refactoring, go to definition, etc. which require a knowledge of the source code structure could not be used.


Problem Statement :
Unfortunately it is reported by many NetBeans users that the Background scanning of projects is quite slow and it takes too long to complete before the IDE is usable. This is valid for a range of NetBeans versions (NetBeans 6.x, 7.x, 8.x).


Scanning issues are the most commonly heard “deal-breakers” for the NetBeans IDE and the NetBeans forum is full with bug reports regarding this issue of slow Background scanning of projects and the bug fixes and corrective actions mentioned therein have not worked for me and also might not have worked for many other users as suggested in many Stackoverflow questions and comments.


Solution :
Today I am sharing with you a technique that worked for me in optimizing the Background scanning of projects (particularly large Java projects)


My configuration :
Operating system : Mac OS X Yosemite (version 10.10.5)
Processor : 2.2 GHz Intel Core i7
Memory : 16GB
NetBeans version : 8.0.2


Procedure :
1) In NetBeans IDE, go to Window-->Files. This opens the Files Tab.
2) In the Files Tab for each opened project open the nbproject folder and inside it open the project.properties file.
3) Now in this file below the property "excludes" there are file references listed for all your referred Libraries (JARs)
4) There might be some repeated file references with paths that may be old or on someone else's machine(if you are working in a group and transferred projects from someone's machine)
5) Delete those old path references.
Example -


excludes=
file.reference.xyz.jar=../not/correct/path.jar  //delete this line
file.reference.xyz.jar-1=../correct/path.jar    //remove -1
....
includes=**


6)Also locate the property "javac.classpath" and delete the unnecessary classpath entries corresponding to the deleted references as described above.
Example -


javac.classpath=\
${file.reference.xyz.jar}:\       //keep this line
${file.reference.xyz.jar-1}:\     //delete this line
....
javac.compilerargs=


7) So now the file reference mentioned in the file reference section and the javac.classpath property is same and points to a valid Library (JAR) address on your machine or network.
Example -


excludes=
file.reference.xyz.jar=../correct/path.jar//correct reference & path
....
includes=**
....
javac.classpath=\
${file.reference.xyz.jar}:\ //the correct classpath entry for reference
....
javac.compilerargs=
....


Reason :
The reason I faced the above issue was because my projects were transferred from many machines and had repeated references to many other machines and NetBeans was scanning for those unreachable paths.


Conclusion :
The above procedure works because it prevents NetBeans from scanning unnecessary Library paths that may not be present on your machine/network.

Hope this helps you in improving the background scanning performance of NetBeans.