Tuesday, May 12, 2015

Java SE 8... What's New? (Part 04/04)

I have provided some of the most important core language enhancements for JDK 8.0, along with code samples. The examples provided below can be directly pasted into your IDE and you may name the class as provided.



Lambda Expressions
Lambda Expression provide a newer way to refer to anonymous methods. It is more like a method interface providing the parameters accepted along with a method body. In a way, it solves the vertical problem - which leads to more maintainable code or lesser lines of code to achieve the same functionality.
 public class jdk8_LambdaExpressions {  
      public static void main(String[] args) {  
           Runnable r2 = () -> System.out.println("Son of God");  
           r2.run(); // note that this is not starting a thread  
      }  
 }  


Parallel Array Operations
Another powerful feature of JDK8 is that parallel operations are allowed on the same set of data. This is by creating stream out of the data. It is guaranteed to be faster if you have multiple processor cores on your system.
 import java.util.ArrayList;  
 import java.util.List;  
 import java.util.Random;  
 public class jdk8_ParallelArrayOperations {  
      static List<Project> projects = new ArrayList<Project>();  
      public static void main(String[] args) {  
           Project project = new Project();  
           project.setName("development");  
           projects.add(project);  
           project = new Project();  
           project.setName("testing");  
           projects.add(project);  
           project = new Project();  
           project.setName("build");  
           projects.add(project);  
           projects.stream().parallel().forEach(a->action(a));  
           for(Project p: projects) {  
                System.out.println(p.getName()+":"+p.getManager());  
           }  
      }  
      public static void action(Project x) {            
           int pmR=new Random().nextInt(1000);  
           x.setManager("john"+pmR);  
      }  
 }  

 class Project {  
      String name;  
      String manager;  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      public String getManager() {  
           return manager;  
      }  
      public void setManager(String manager) {  
           this.manager = manager;  
      }  
 }  


Method Parameter Reflection
Another nice feature, particularly useful when you are using Reflection and Debugging large amount of code - You would want additional introspection on the real parameter names. By compiling the code with JDK8 using the following command, we enable this feature. Note that it will lead to use of additional memory/bytecode size.
 javac -parameters jdk8_MethodParameterReflection.java   

The following method illustrates the use of Method Parameter Reflection in a Java Program.
 import java.lang.reflect.Method;  
 import java.lang.reflect.Parameter;  

 public class jdk8_MethodParameterReflection {  
      public static void main(String[] args) {            
           Class<BlackHat> clazz = BlackHat.class;  
           for(Method m: clazz.getDeclaredMethods()) {  
                for(Parameter p: m.getParameters()) {  
                     System.out.println(p.getName());  
                }  
           }  
      }  
 }  
 class BlackHat {       
      public void payload(String hostName, int hostPort, boolean howdy) {            
           System.out.println("i can do something");  
      }  
 }  


Repeating Annotations
Prior to JDK8, there was no easy way to manage repeating annotations, other than the user or the developer providing custom ways to handle them. With JDK8, one is allowed to define the same annotation more than once. You may place the following code under the package 'jdk8.features'.
 package jdk8.features;  
 import java.lang.annotation.Repeatable;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 @Retention( RetentionPolicy.RUNTIME )  
 @Repeatable(value = jdk8_RepeatableAnnotationsSources.class)  
 public @interface jdk8_RepeatableAnnotationsSource {  
      String version() default "";       
 }  

Now, you can define the Annotation that you had mentioned
as the value for the '@Repeatable' Annotation. You may place the following code under the package 'jdk8.features'.
 package jdk8.features;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 @Retention(RetentionPolicy.RUNTIME)  
 public @interface jdk8_RepeatableAnnotationsSources {  
      jdk8_RepeatableAnnotationsSource[] value();  
 }  

You can use Repeatable Annotations as follows. Also, you can use any of the methods getAnnotation() or getAnnotationsByType() to parse the annotation and process them.
 import jdk8.features.jdk8_RepeatableAnnotationsSource;  
 import jdk8.features.jdk8_RepeatableAnnotationsSources;  

 @jdk8_RepeatableAnnotationsSource(version = "jdk5")  
 @jdk8_RepeatableAnnotationsSource(version = "jdk6")  
 @jdk8_RepeatableAnnotationsSource(version = "jdk7")  
 public class jdk8_RepeatableAnnotations {  
      public static void main(String[] args) {  
           Class<jdk8_RepeatableAnnotations> clazz = jdk8_RepeatableAnnotations.class;  
           jdk8_RepeatableAnnotationsSources sources1 = clazz.  
                     getAnnotation(jdk8_RepeatableAnnotationsSources.class);            
           jdk8_RepeatableAnnotationsSource[] sources2 = clazz.  
                     getAnnotationsByType(jdk8_RepeatableAnnotationsSource.class);  
           for(jdk8_RepeatableAnnotationsSource source: sources1.value()) {  
                System.out.println(source.version());  
           }  
           for(jdk8_RepeatableAnnotationsSource source: sources2) {  
                System.out.println(source.version());  
           }  
      }  
 }  


Method References

Method References are like Lambda Expressions, except that they allow to specify or refer to the existing method by name. The operator to refer to an existing method name is :: You may place the following code under the package 'jdk8.features'.
 package jdk8.features;  
 public class jdk8_MethodReferencesVO {  
      Integer age;  
      String name;  
      public Integer getAge() {  
           return age;  
      }  
      public void setAge(Integer age) {  
           this.age = age;  
      }  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
 }  

Note the usage below of Method References. There can be four types of references to methods, including:
  •     Reference to a static method [ContainingClass::staticMethodName]
  •     Reference to an instance method [containingObject::instanceMethodName]
  •     Reference to a constructor [ClassName::new]
  •     Reference to an instance method [ContainingType::methodName {Arbitary Object}]
 import java.util.Arrays;  
 import jdk8.features.jdk8_MethodReferencesVO;  

 public class jdk8_MethodReferences {  
   public int compareByName(jdk8_MethodReferencesVO a, jdk8_MethodReferencesVO b) {  
     return a.getName().compareTo(b.getName());  
   } 
 
   public int compareByAge(jdk8_MethodReferencesVO a, jdk8_MethodReferencesVO b) {  
     return a.getAge().compareTo(b.getAge());  
   }
  
   public static void main(String[] args) {  
           jdk8_MethodReferencesVO[] refs = new jdk8_MethodReferencesVO[5];  
           jdk8_MethodReferencesVO vo1=new jdk8_MethodReferencesVO();  
           vo1.setAge(21);  
           vo1.setName("Frank");  
           refs[0]=vo1;  
           vo1=new jdk8_MethodReferencesVO();  
           vo1.setAge(22);  
           vo1.setName("Ibrahim");  
           refs[1]=vo1;  
           vo1=new jdk8_MethodReferencesVO();  
           vo1.setAge(24);  
           vo1.setName("Vinod");  
           refs[2]=vo1;  
           vo1=new jdk8_MethodReferencesVO();  
           vo1.setAge(19);  
           vo1.setName("Gurdeep");  
           refs[3]=vo1;  
           vo1=new jdk8_MethodReferencesVO();  
           vo1.setAge(25);  
           vo1.setName("Maxovitch");  
           refs[4]=vo1;  
           jdk8_MethodReferences refC = new jdk8_MethodReferences();  
           Arrays.sort(refs, refC::compareByAge);  
           for(jdk8_MethodReferencesVO rvo: refs) {  
                System.out.println(rvo.getAge()+":"+rvo.getName());  
           }  
      }  
 }  


Happy Life with JDK8!

Sunday, May 10, 2015

Java SE 7... What's New? (Part 03/04)

I have provided some of the most important core language enhancements for JDK 7.0, along with code samples. The examples provided below can be directly pasted into your IDE and you may name the class as provided.



Strings in Switch Statement
You may use Strings in your switch statement, which is a powerful tool. The alternative would have been to use a series of if statements with .equals() comparison. You may directly execute the code below in Eclipse to understand better.
 public class jdk7_StringSwitch {  
      static String day = "SAT";  
     
      public static void main(String[] args) {  
           switch(day) {  
                case "MON": { System.out.println("Monday"); break; }  
                case "TUE": { System.out.println("Tuesday"); break; }  
                case "SUN": { System.out.println("Sunday"); break; }  
                case "SAT": { System.out.println("Saturday"); break; }  
           }  
      }  
 }  


Multiple Exception Handling 
Before JDK7, you would have to catch multiple exceptions in a block - with a catch block for each of the thrown checked exception. But sometimes you may want to take actions for many exceptions that are similar or same. Hence, the utility of this feature. You may directly execute the code below in Eclipse to understand better.
 public class jdk7_ExceptionHandling {  
      
      public static void main(String[] args) {  
           try {                 
                Integer value = Integer.parseInt("ABC");  
                File file = new File("exception.txt");  
                FileReader fileReader = new FileReader(file);                 
           } catch(NumberFormatException | FileNotFoundException foe) {  
                System.out.println("Multiple Exception Types");  
           }  
      }  
 }  

 
Try with Resources
You may use/create a resource withing the try block, from JDK7, and use it within the following block. This includes all objects/resources that implement the java.io.Closeable. Automatically on encountering the exception or if there is no exception, the close() method is guaranteed to be called by the runtime.
 public class jdk7_TryWithResources {  
  
      public static void main(String[] args) throws IOException {            
           try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {  
                br.readLine();  
           } finally {  
                System.out.println("All Resources Closed.");  
           }  
      }  
 }  
Make sure that you have a file.txt in your classpath.
 


Diamond Syntax (Type Inference for Generics) 
Sometimes, in application when we are using generics we may end up with a long line of code, that may be very confusing or have poor readability. This is because there may be multiple generic types that are used in the same line. To improve upon this, JDK7 introduces the concept of diamond operator or diamond syntax, where the type of the generic variable is inferred.
 public class jdk7_DiamondSyntax {  
      public static void main(String[] args) {            
           Map<String, Map<String, List<String>>> list = new HashMap<>();  
           List<String> aList = new ArrayList<String>();  
           aList.add("09.10");  
           aList.add("09.20");  
           aList.add("09.22");  
           Map<String,List<String>> iMap = new HashMap<>();  
           iMap.put("radiac", aList);  
           list.put("radia", iMap);  
      }  
 }  


Binary Literals, Underscore in Literals 
Continuing on the aspects of readability for numeric literals, the concept of the underscore is provided to separate numeric literals like at thousands place, millions place, hundredths place, etc. Also, Binary Literals are allowed in JDK7 starting with 0b. All types of numeric literals will allow the use of '_'. You have to make sure that '_' is not used as the (before) first or (after) last digit of the numeric literal AND '_' is not  used adjacent to the decimal point AND '_' is not used before the F or the L suffix.
 public class jdk7_Literals {  
      int million = 100_000_000;  
      byte b = (byte) 0b0001111111;  
      short s = (short) 0b111100000000;   
      int i = 0b11111111111111111111;  
     
      public static void main(String[] args) {  
           
           jdk7_Literals l = new jdk7_Literals();  
           System.out.println(l.million);  
           System.out.println(l.b + ":" + l.s + ":" + l.i);  
      }  
 }  


Happy Times with JDK 7!

Java SE 6... What's New? (Part 02/04)

I have provided some of the most important core language enhancements for JDK 6.0, along with code samples. The examples provided below can be directly pasted into your IDE and you may name the class as provided.
 
Communication Between Sender and Receiver (SOAP Web Services)
 

From JDK6, Java allows the creation, publishing and lookup of web services through a mixture of annotations and command-line utilities. The below is located in package 'jdk6.features'
 package jdk6.features;  
 import javax.jws.WebMethod;  
 import javax.jws.WebService;  
 import javax.xml.ws.Endpoint;  

 /**  
  * @author sumith_puri  
  *  
  * credits: https://weblogs.java.net/blog/vivekp/archive/2006/12/webservices_in.html  
  *   
  * apt -d sample jdk6_WebServices.java  
  * java -cp sample jdk6.features.jdk6_WebServices  
  * wsimport -p client -keep http://localhost:8080/calculator?wsdl  
  */  
 @WebService  
 public class jdk6_WebServices {  
      @WebMethod  
      public int add(int a, int b) {  
           return (a+b);  
      }  
      public static void main(String[] args) {  
           jdk6_WebServices calculator = new jdk6_WebServices();  
           Endpoint endpoint = Endpoint.publish("http://localhost:8080/calculator", calculator);  
      }  
 }  

In the same folder as the root of the above source file/package, you should type the following:
apt -d sample jdk6_WebServices.java  

Then type the following, to deploy the Web Service at the specified URL.
java -cp sample jdk6.features.jdk6_WebServices

Now, it is time to create the client. You may use the following command to create the client stubs.
wsimport -p client -keep http://localhost:8080/calculator?wsdl 

We can import the generated sources from the 'client' folder now to Eclipse. Using the imported client stubs, you can create client application using the following. Execute it either on command-line or from Eclipse (Run As > Java Application)
 package client;  

 public class JDK6WebServicesClientApp {  
      public static void main(String[] args) {          
           Jdk6WebServicesService service = new Jdk6WebServicesService();  
           Jdk6WebServices serviceProxy = service.getJdk6WebServicesPort();  
           int result = serviceProxy.add(12, 12);  
           System.out.println("Sum: " + result);  
      }  
 }  


Java Compiler API
A powerful feature in JDK6 that will be of really help to create artifacts such as plugins, filters, extensions for dynamic (customer based or client based) execution - is Dynamic Compilation using the Java Compiler API.
 public class jdk6_DynamicCompilation {  

      public static void main(String[] args) throws Exception {            
           System.out.println("Testing Dynamic Compilation....");  
           System.out.println("plugin\\Plugin.java");       
           String fileToStream = "plugin" + java.io.File.separator + "Plugin.java";  
           JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();                 
           FileOutputStream fileOutputStream = new FileOutputStream("errors.txt");  
           int compilationResult = javaCompiler.run(null, null, fileOutputStream,   
                                                          "-verbose", fileToStream);            
           System.out.println("Compilation Result..." + compilationResult);  
      }  
 }  

The following code should be provided under 'plugin'. You may name it as 'Plugin.java'
 package plugin;  
   
 public class Plugin {  
      public boolean filter(String data) {            
           boolean flag=false;  
           if(data.contains("fish")) {                 
                flag=true;  
           }  
           return flag;  
      }  
 
     public static void main(String[] args) {  
      }  
 }  

You may now run the jdk6_DynamicCompilation and obtain Plugin.class as dynamically compiled class under the 'plugin' folder.  Now execute the generated class either using reflection (which you may use in real-world products or solutions) or from the command-line.
java -cp . plugin.Plugin


Scripting Language Support
With JDK6, you may execute JavaScript (Tcl, Ruby, Groovy, etc.) from within Java. This is possible through ScriptingEngine. The example below shows the usage of JavaScript within Java.

 package jdk6.features;  
 import java.io.File;  
 import java.io.FileReader;  
 import javax.script.Invocable;  
 import javax.script.ScriptEngine;  
 import javax.script.ScriptEngineManager;  
   
 public class jdk6_Scripting {  
      public void todaysLogic() throws Exception {            
        // dynamically change script - invoke code in groovy, js - even tcl!  
        ScriptEngineManager manager = new ScriptEngineManager();  
        ScriptEngine jsEngine = manager.getEngineByName("JavaScript");  
        System.out.println(jsEngine.toString());  
        if (jsEngine instanceof Invocable) {  
             try {  
                  File file = new File("market.js");  
             } catch (Throwable e) {  
                  e.printStackTrace();  
             }              
             FileReader reader = new FileReader("market.js");              
             jsEngine.eval(reader);              
             ((Invocable) jsEngine).invokeFunction("current");  
         }  
      }  
      public static void main(String[] args) throws Exception {  
           jdk6_Scripting scripting = new jdk6_Scripting();  
           scripting.todaysLogic();  
      }  
 }  

You must place the following JavaScript code in your classpath, maybe within the root folder of your Eclipse Project. You should name it 'market.js'
 function current() {  
   var x = "", i;  
   for (i=0; i<100; i++) {  
        x="";  
        x = x + "The Number Is " + i;  
        println(x);  
   }    
 }  


Happy Programming with JDK6!

Java SE 5... What's New? (Part 01/04)

I have provided some of the most important core language enhancements for JDK 5.0, along with code samples. The examples provided below can be directly pasted into your IDE and you may name the class as provided.



Enumerations are provided as an easier way to maintain similar values (constants) that can be assigned to a type. The keyword used is enum. You may additionally define constructors. The method ordinal() will return the index of the enum constant and the method name() will return the name of the enum constants. You may also use valueOf() to return the value of a string as an enum constant. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Enum {  
      public static enum Java {JDK5, JDK6, JDK7, JDK8};  
      public static enum JavaVer {   
           JDK5(5), JDK6(6), JDK7(7), JDK8(8);  
           int x;  
           JavaVer(int x) {  
                this.x = x;  
           }  
      }  
     
      public static void main(String[] args) {  
           Java java = Java.JDK6;  
           System.out.println(Java.JDK5);  
           System.out.println(java);  
           System.out.println(java.ordinal() + ":" + java.name());  
           JavaVer javaVer = JavaVer.JDK7;  
           System.out.println(javaVer.x);  
           System.out.println(javaVer.ordinal() + ":" + javaVer.name());  
           String myJava = "JDK8";  
           System.out.println(Java.valueOf(myJava));  
           JavaVer javaSwitchVer=JavaVer.JDK6;  
           switch(javaSwitchVer) {  
                case JDK5: {System.out.println("5.0"); break;}  
                case JDK6: {System.out.println("6.0"); break;}  
                case JDK7: {System.out.println("7.0"); break;}  
                case JDK8: {System.out.println("8.0"); break;}  
           }  
      }  
 }  


Variable Arguments
Varargs should be provided as the last parameter of any method and can be used to pass zero or more arguments to the method. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Varargs {  
      public void getData(String...values) {  
           for(String string:values) {  
                System.out.println(string);  
           }  
      }  
     
      public static void main(String[] args) {  
           jdk5_Varargs varargs = new jdk5_Varargs();  
           varargs.getData("Apple","Banana","Cucumber","Radish");       
           String[] vargs = new String[] {"Radia","Cloud","Hewlett","Packard"};  
           varargs.getData(vargs);  
      }  
 }  


Generics
Generics is used to maintain compile-time type safety on code. It follows type erasure and allows to maintain a control over the types that can be maintained in collections. You may also use generics to define method or class 'templates'. You may directly execute the code below in Eclipse to understand better. For more on generics, refer to my article in CodeGuru.
 public class jdk5_Generics {  
      List<String> genericList = new ArrayList<String>();  
   
      public static void main(String[] args) {            
           jdk5_Generics jGenerics = new jdk5_Generics();  
           // generic for type safety  
           List<String> jGenericsList = jGenerics.genericList;  
           jGenericsList.add("Sumith");  
           jGenericsList.add("Kumar");  
           jGenericsList.add("Puri");  
           for(String str:jGenericsList) {  
                System.out.println(str);  
           }  
           // generic variables - class and method generic templates  
           List<? extends Vehicle> jGenericObjList = new ArrayList();  
           Vehicle car = new Car();  
           RentVehicle<Vehicle> rentVehicle = new RentCar<Car>();  
           rentVehicle.rentOut(car);  
      }  
 }  
 class Vehicle {  
      Integer regn;  
      String type;  
      public Integer getRegn() {  
           return regn;  
      }  
      public void setRegn(Integer regn) {  
           this.regn = regn;  
      }  
      public String getType() {  
           return type;  
      }  
      public void setType(String type) {  
           this.type = type;  
      }            
 }  
 class Car extends Vehicle {  
 }  
 interface RentVehicle <T extends Vehicle> {  
      public void rentOut(T vehicle);  
 }  
 class RentCar<Car> implements RentVehicle{  
      public void rentOut(Vehicle vehicle) {            
           System.out.println("Rent Vehicle => Rent Car");  
      }  
 }  


Autoboxing/Unboxing
Autoboxing or Unboxing will allow to convert from primitive types to wrapper types and vice versa. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Autoboxing {  
      Integer integer = new Integer(50);  
      public void setValue(int integer) {  
      }  
      public Integer getValue() {  
           return integer;  
      }  
      public Float getFloat() {  
           return 6.0f;  
      }  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {            
           jdk5_Autoboxing autoboxing = new jdk5_Autoboxing(); // autounboxing  
           autoboxing.setValue(new Integer(5));  
           int x = autoboxing.getValue();  
           // this is not valid => autounboxing - upcasting - autoboxing  
           // Double y = autoboxing.getFloat();  
      }  
 }  


Enhanced For Loop
Enhanced For Loop allows an easier way to loop through objects of a common super-type. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_EnhancedFor {  
      public static void main(String[] args) {  
           jdk5_EnhancedFor ef = new jdk5_EnhancedFor();  
           List<Animal> animals = new ArrayList();  
           Animal animal = new Animal();  
           animals.add(animal);  
           animal = new Dog();  
           animals.add(animal);  
           animal = new Cat();  
           animals.add(animal);  
           animal = new Dog();  
           animals.add(animal);  
           animal = new Cat();  
           animals.add(animal);  
           animal = new Dog();  
           animals.add(animal);  
           animal = new Animal();  
           animals.add(animal);  
           animal = new Animal();  
           animals.add(animal);  
           for(Animal anim: animals) {  
                anim.print();  
           }  
      }  
 }  
 class Animal {  
      public void print() {  
           System.out.println("Animal");  
      }  
 }  
 class Dog extends Animal {  
      public void print() {  
           System.out.println("Dog");  
      }  
 }  
 class Cat extends Animal {  
      public void print() {  
           System.out.println("Cat");  
      }  
 }  


Static Imports
Static Imports allows you to import static methods and fields from other classes or interfaces, most useful when you to easily refer to static members from other classes without the reference of their class. You may directly execute the code below in Eclipse to understand better. Note that it is a compile-time error to import a type from unnamed or default package. 
 import static jdk5.features.jdk5_StaticImport_Source.product;  
 public class jdk5_StaticImport {  
      public static void main(String[] args) {  
           System.out.println(product);  
      }  
 }  
The source for importing the above is the following class which is located under the package 'jdk5.features'

 package jdk5.features;
 public class jdk5_StaticImport_Source {  
      public static final String product = "radia-cloud";  
      public static final String version = "09.20.0000";  
      public static void setup() {  
           System.out.println("Setting up the Radia Server....");  
      }  
      public static void init() {  
           System.out.println("Initializing the Radia Server....");  
      }  
 }  


Annotations 
Annotations are way of syntactic meta-data to inform and use that it signifies a specific type of functionality that can be processed using reflection. It can also be used to suppress warnings and inform of errors. The source file below is located under the package 'jdk5.features'
 package jdk5.features;  
 import java.lang.annotation.ElementType;  
 import java.lang.annotation.Retention;  
 import java.lang.annotation.RetentionPolicy;  
 import java.lang.annotation.Target;  
 @Retention(RetentionPolicy.RUNTIME)  
 @Target({ElementType.FIELD,ElementType.METHOD})  
 public @interface jdk5_Annotation_Source {  
 }  

The RetentionPolicy as mentioned can be either of Runtime (Retained by VM), Source (Discarded by Compiler) or Class (Not be Retained by VM). The source below is located under the package 'jdk5.features'
 package jdk5.features;  
 public class jdk5_Annotation_Usage {  
      @jdk5_Annotation_Source  
      public String myMessage;  
      public void annotated() {  
           System.out.println(myMessage);  
      }  
 }  

Now, You may directly execute the code below in Eclipse to understand Annotations better. (Default Package)
 import java.lang.reflect.Field;  
 import jdk5.features.jdk5_Annotation_Source;  
 import jdk5.features.jdk5_Annotation_Usage;  
 
 public class jdk5_AnnotationProcessor {  
      public static void main(String[] args) throws Exception {  
           jdk5_Annotation_Usage message = new jdk5_Annotation_Usage();  
           Field[] method = message.getClass().getDeclaredFields();  
           for(Field methd: method) {  
                jdk5_Annotation_Source annos = methd.getAnnotation(jdk5_Annotation_Source.class);                 
                if(annos != null) {  
                     methd.set(message,"Messenger of God!");  
                     // using reflection & annotations we set the value - check if set                  
                     message.annotated();   
                }  
           }  
      }  
 }  


Happy Coding with JDK 5!

Thursday, May 7, 2015

Enforce Size Constraints in Infinispan - Java Instrumentation API!

Infinispan does not provide size constraints out of the box, just like almost all of the other standard caching frameworks. You may use the Java Instrumentation API as follows to enforce cache size constraints for your product or project that uses Infinispan.

1. Introduce Instrumentation API in your code
a. Develop a class that has the following method in it. The VM will automatically insert an implementation of the Instrumentation API - once it encounters this method.
 public class ServerInstrumentation {  
      private Instrumentation instrumentation = null;   
      private static final Logger LOGGER = Logger.getLogger(ServerInstrumentation.class);  
      private static ServerInstrumentation serverInstrumentation;  

      public static void premain(String args, Instrumentation pInstrumentation) {  
           serverInstrumentation = new ServerInstrumentation();  
           serverInstrumentation.instrumentation=pInstrumentation;  
      }  
      public static Instrumentation getInstance() {  
           return serverInstrumentation.instrumentation;  
      }  
}

b. You may choose to add the following EJB (optionally) to make this object available throughout your Java EE application. Re-Implement the methods that you need to use from the Instrumentation API. For example, below we have implemented the sizeOf() which actually internally invokes Instrumentation.getObjectSize().
 @Remote  
 public interface ServerInstrumentationInterface {  
      public long sizeOf(Object toBeSized);  
 }  

 @Singleton  
 @Startup  
 public class ServerInstrumentationEJB implements ServerInstrumentationInterface {  
      private static Instrumentation instrumentation;  
      {  
           ClassLoader classLoader=this.getClass().getClassLoader().getParent();  
           try {  
                Class clazz = classLoader.loadClass(ServerInstrumentation.class.getName());  
                instrumentation=(Instrumentation)clazz.getDeclaredMethod("getInstance").invoke(null);                   
           } catch (Exception e) {  
                System.out.println("FFFFFF");  
           }  
      }  
      public long sizeOf(Object toBeSized) {  
           return instrumentation.getObjectSize(toBeSized);  
      }  
 }  

Package this code as 'agent.jar' with the following contents in MANIFEST.MF
 Premain-Class: ServerInstrumentation  
 Agent-Class: ServerInstrumentation  

c. You should place this in the normal deployment location (standalone\deployments) of Wildfly and also mention it as the -javaagent during server startup.The following contents should be in Wildfly standalone.bat
 "%JAVA%" %JAVA_OPTS% "-javaagent:%JBOSS_HOME%\standalone\deployments\agent.jar" ^  
  "-Dorg.jboss.boot.log.file=%JBOSS_LOG_DIR%\server.log" ^  
  "-Dlogging.configuration=file:%JBOSS_CONFIG_DIR%/logging.properties" ^  
   -jar "%JBOSS_HOME%\jboss-modules.jar" ^  
   -mp "%JBOSS_MODULEPATH%" ^  
    org.jboss.as.standalone ^  
   "-Djboss.home.dir=%JBOSS_HOME%" ^  
    %SERVER_OPTS%  

At the end of this, the Instrumentation methods are available throughout your Java EE application for all instrumentation purposes. The EJB will act as a facade over this functionality. Make sure that the following settings exist in your standalone.conf.bat
set "JAVA_OPTS=%JAVA_OPTS% -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Xbootclasspath/p:d:\wildfly\modules\system\layers\base\org\jboss\log4j\logmanager\main\log4j-jboss-logmanager-1.1.0.Final.jar;d:\wildfly\modules\system\layers\base\org\jboss\logmanager\main\jboss-logmanager-1.5.2.Final.jar" 
set "JAVA_OPTS=%JAVA_OPTS% -Djboss.modules.system.pkgs=org.jboss.byteman,org.jboss.logmanager"


2. Use this in your Actual Application (Client)
a. The lookup code is provided below to perform methods using Instrumentation, such as 'Object Size'. This may be used for multiple purposes in your Java EE products or solutions, apart form caching constraints.
 // let's do the lookup           
ServerInstrumentationInterface cacheInstrumentationService = (ServerInstrumentationInterface)   
               initialContext.lookup("java:global/agent/" + ServerInstrumentationEJB.class.getSimpleName());  
cacheInstrumentationService.sizeOf(new String("Java and Infinispan Caching Innovation")));  

b. The following method can be implemented in a different class (CacheInstrumentation.java) to perform the following function everytime you add an element to the cache, to check whether the Allocated Size is exceeded. This will have the above EJB Reference/Instance encapsulated in it.
 public boolean isEntityCacheLimitExceeded(Cache cache) {  
           boolean exceeded=false;  
           long currSize = cacheInstrumentationService.sizeOf(cache);  
           long allocSize = 10*1000*1024;  // 10 MB = 10 * 1000 * 1024 bytes
           if(currSize >= allocSize) {  
                exceeded=true;  
           }  
           return exceeded;  
}  


3. Use ConfigurationBuilder to Introduce Constraints
a. The following method will be used to setConfiguration() which will help to notify Infinispan that the configuration has changed, so that it can perform eviction dynamically.
 public class CacheManagerUtilities {  
      public static Configuration setConfiguration(int maxNumberofEntries) {  
           return new ConfigurationBuilder().eviction().maxEntries(maxNumberofEntries)  
                     .strategy(EvictionStrategy.valueOf("LIRS")).expiration()  
                     .lifespan(2000)  
                     .wakeUpInterval(500)  
                     .maxIdle(1000).build();  
      }  
 }  


4. Request/Enforce Eviction using EvictionManager [defineConfiguration()]
a. Everytime you put/add an element in your cache, you can use the sizeOf() from the EJB to check if the size constraints are exceeded. If they are, then dyanmically change the configuration to make the max-entries limit to the currently existing max-entries. We will now rely on Infinispan's Eviction Algorithms to kick-in and do its duty.
 public void put(K key, V value) {            
           while (true) {  
                if (!cacheInstrumentation.isEntityCacheLimitExceeded(cache)) {  
                     cache.put(key, value);  
                     break;  
                } else {  
                     // set the configuration to the infinispan cache programmatically  
                     Configuration configuration = CacheManagerUtilities.setConfiguration(cache.size());  
                     cache.getCacheManager().defineConfiguration(cache.getName(), configuration);  
                    
                     // start eviction manually  
                     EvictionManager evictionManager = cache.getAdvancedCache().getEvictionManager();  
                     evictionManager.processEviction();  
                     
                     // set the configuration to the infinispan cache programmatically - large number such as 9999  
                     configuration = CacheManagerUtilities.setConfiguration(9999);  
                     cache.getCacheManager().defineConfiguration(cache.getName(), configuration);  
                }  
           }  
}

The above usually performs three things:
1. Expire all elements that have reached expiration time (Data Container)
2. Expire all elements that have reached expiration time (Cache Store)
2. Remove all elements as per the eviction policy - Prunes to max-entries

You may also test the above using Arquillian to try out whether the eviction works by creating data within test cases that adhere to LIRS, LRU and Size Constraints.


Note that the above code will also make sure that only 'Serializable' objects are allowed to be Cached. Suitable for all Java/Java EE products and solutions that need to Enforce Size as a Constraint mechanism for Caching. Happy Caching!

Friday, April 24, 2015

Manifest Dependencies (Arquillian ShrinkWrap) in Wildfly using Infinispan

Troubled almost half a day by this issue. Should be helpful for all using Arquillian, ShrinkWrap, Infinispan on Wildlfly.

Caused by: javax.ejb.EJBException: java.lang.IllegalArgumentException: 
Can not set org.infinispan.manager.CacheContainer 
field com.psl.radia.gw.cache.manager.CacheManager.cacheContainer 
to org.jboss.as.clustering.infinispan.DefaultCacheContainer

Caused by: java.lang.IllegalArgumentException: 
Can not set org.infinispan.manager.CacheContainer 
field com.psl.radia.gw.cache.manager.CacheManager.cacheContainer 
to org.jboss.as.clustering.infinispan.DefaultCacheContainer


These are the list of steps to be followed to resolve this:

1. Add the MANIFEST.MF to src/test/resources with this content [MANIFEST.MF]
 
Dependencies: org.infinispan export 


2. Modify the standalone.xml or standalone-full.xml [WILDFLY/INFINISPAN]
 
Your standalone-full.xml will already have the following entry
 
<subsystem xmlns="urn:jboss:domain:ee:2.0">
...
</subsystem>

Add the following within the <subsystem> tags:
 
<global-modules> 
    <module name="org.infinispan" slot="main"/>
</global-modules>

 
3. To the Test Case/Deployment, Add the following  [ARQUILLIAN]
 
WebArchive res = ShrinkWrap.create(WebArchive.class, "test.war");        
...
res.addAsManifestResource("MANIFEST.MF");


This is the ONLY way to achieve this, though you may find suggestions all over that require you to change the pom.xml (maven-jar-plugin, maven-ejb-plugin,maven-war-plugin) or that suggest the use of adding the string (Dependencies: org.infinispan export) directly to the MANIFEST.MF created by Arquillian Test Case. 

Saturday, April 18, 2015

JAR File Dependencies (Internal References/Class-Path)

Most often, you end up in the following issue - where you want to refer to a JAR inside another JAR. Many developers would assume that by adding it to the Class-Path within MANIFEST.MF, it should be included in the classpath. But this does not work.

test.jar
|  /META-INF
|  |     MANIFEST.MF
|  |        Main-Class: com.persistent.accelerite.main.AppLauncher

|  |        Class-Path: commons-logging.jar
|  /com/persistent/accelerite/main
|  |     AppLauncher.class
|  commons-logging.jar


This may be very surprising or something that will be away from your strongest belief/intuition - But this will not work! You have to extract the required JARs and put them at the same level or same directory as the directory where test.jar is located. In the above class, trying to use jar:file:jarname.jar!/commons-logging.jar in the Class-Path will also not work. The only other way to achieve this is to write Custom Class Loaders.

This is as per the Java Archive Specification.  From the official Oracle Documentation is as follows:

Class-Path:
The value of this attribute specifies the relative URLs of the extensions or libraries that this application or extension needs. URLs are separated by one or more spaces. The application or extension class loader uses the value of this attribute to construct its internal search path.

Wednesday, April 15, 2015

Debugging using Wildfly and Arquillian

This should be most useful for those starting out with Arquillian! I spent quite some time before finding out the solution.

The arquillian.xml should include the following contents:
 <engine>  
     <property name="deploymentExportPath">target/</property>  
   </engine>  
   <container qualifier="jbossas-managed-wildfly-8" default="true">  
        <protocol type="jmx-as7">  
       <property name="executionType">REMOTE</property>  
     </protocol>  
     <configuration>  
          <property name="allowConnectingToRunningServer">true</property>  
       <property name="jbossHome">C:\Program Files (x86)\PSL\RCA\ApplicationServer</property>  
       <property name="modulePath">C:\Program Files (x86)\PSL\RCA\ApplicationServer\modules</property>  
       <property name="javaVmArguments">-Xrunjdwp=transport=dt_socket,address=8000,server=y,suspend=n -Djava.util.logging.manager=org.jboss.logmanager.LogManager</property>  
     </configuration>  
   </container>  


Include the following profile in your Maven pom.xml,
  <profile>  
   <id>arquillian-wildfly-managed</id>  
   <activation>  
        <activeByDefault>true</activeByDefault>  
        </activation>    
   <dependencies>  
      <dependency>  
        <groupId>org.jboss.spec</groupId>  
        <artifactId>jboss-javaee-6.0</artifactId>  
        <version>3.0.1.Final</version>  
        <type>pom</type>  
        <scope>test</scope>  
      </dependency>  
      <!-- Required by jboss-javaee-6.0:3.0.2.Final (https://issues.jboss.org/browse/JBBUILD-708) -->  
      <dependency>  
        <groupId>xalan</groupId>  
        <artifactId>xalan</artifactId>  
        <version>2.7.1</version>  
        <scope>test</scope>  
      </dependency>  
      <dependency>  
        <groupId>org.wildfly</groupId>  
        <artifactId>wildfly-arquillian-container-managed</artifactId>  
        <version>8.1.0.Final</version>  
        <scope>test</scope>  
      </dependency>  
      </dependencies>  
   </profile>  

When we use Arquillian, there are three VM's that are involved:
 
1. Arquillian (Source) > Remote/Managed Server
Start the Remote/Managed Server with the following line added to standalone.conf.bat
 set "JAVA_OPTS=%JAVA_OPTS% -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n"  

In Eclipse, Right Click on your project and Click on "Debug" and under "Connect" - Select your "Host" and "Port". Click on "Apply" and "Debug". This will connect the Debugger to the Remote VM inside Wildfly. 


2. Test > Remote/Managed Server
Now, Right Click on your Arquillian Test and Click on "Debug As.." or "Debug Configurations". Then select either "TestNG" or "JUnit". 

Now, You will be able to hit the Breakpoint. Happy Debugging!