Wednesday, December 15, 2010

JDK 7 Features

JDK 7 Features
Project Coin : Small language enhancements

Its a time to think of new features in JDK, entire JAVA community closely watching the progress of JAVA/JDK development in Oracle. This release comes with small java language change to major featuristics. Following are few details of feature/changes

Strings in switch
void print(String s) { 
  switch (s) {
    case "hello":
      System.out.println("hello: "+s); 
      break;
    case "wow":
      System.out.println("wow: "+s); 
   break;
    default:
      System.out.println("Wrong option: "+s);
  }
}
Refer for more details in blog
Binary integral literals and underscores in numeric literals
Read here
Multi-catch and more precise rethrow
try {
    doWork(file);
} catch (final IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
Refer for more details in mail archive
Improved type inference for generic instance creation (diamond)
Read mail archive
try-with-resources statement
Read here
Simplified varargs method invocation
Read here

Read following links to know more about the JDK SE 7.0 features. JDK 7 Project Coin: Project Page | mailing list | Joe Darcy and other Sun bloggers | wiki

Monday, October 11, 2010

LazyHolder Pattern

Design Pattern

A pattern describes a proven solution to a recurring design problem, placing particular emphasis on the context and forces surrounding the problem, and the consequences and impact of the solution. Find more details about design patterns in http://java.sun.com/blueprints/corej2eepatterns/Patterns/index.html

Singleton Pattern

This pattern helps to create only one instance of a class in a ClassLoader. This is achieved by holding the created object in class level variable.

Eagerly Initialization:

Following are the points needs to be done

  • All constructor method has to be decalared with private access specifier
  • A variable has to be declared to hold the object with private access specifier and static and finalaccess modifier and singleton object created and assigned here itself
  • A method has to be created with public access specifier and static access modifier
SingleTonEarlyInitialization.java

public class SingleTonEarlyInitialization {
private static final SingleTonEarlyInitialization sObj = new SingleTonEarlyInitialization();

private SingleTonEarlyInitialization() {}

public static SingleTonEarlyInitialization getInstance() {
return sObj;
}
}

Lazy Initialization:

Following are the points needs to be done

  • All constructor method has to be decalared with private access specifier
  • A variable has to be declared to hold the object with private access specifier and static access modifier
  • A method has to be created with public access specifier and static access modifier and object will be created and returned from here.
SingleTonLazyInitialization.java

public class SingleTonLazyInitialization {
private static SingleTonLazyInitialization sObj = null;

private SingleTonLazyInitialization() {
}

public static SingleTonLazyInitialization getInstance() {
if(null == sObj)
sObj = new SingleTonLazyInitialization();
return sObj;
}
}

Thread Safe

In multi-threaded environment, Lazy Initialization based singleton is not threadsafe. Hence, getInstance() method has to be enforced with class level monitoring to achieve threadsafe.

Option 1 - Make getInstance() as Synchronized method
public static synchronized SingleTonLazyInitialization getInstance() {  
  if(null == sObj)
  sObj = new SingleTonLazyInitialization();  
  return sObj;
 }
Option 2 - Introduce Synchronized block on the class
public static SingleTonLazyInitialization getInstance() {
  synchronized(SingleTonLazyInitialization.class)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }
Option 3 - Introduce Synchronized block on the dummy Object
private static final Object lockObj=new Object();
 public static SingleTonLazyInitialization getInstance() {  
  synchronized(lockObj)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }
Performance Bottleneck

Introducing the synchronized block/method performs slightly slower than the normal and causes performance bottleneck. In the object instantiation time, we need to make sure that not more than one object get instantiated. Afterwards, any number of threads can possibly access with zero delay. While introducing the synchronized block/method, some delay may occur.

To overcome this delay, we may need to introduce the null-if check before obtaining the monitoring-lock.

private static final Object lockObj=new Object();
 public static SingleTonLazyInitialization getInstance() {
  if(null != sObj)
   return sObj;  
  synchronized(lockObj)
  {
  if(null == sObj)   
  sObj = new SingleTonLazyInitialization();
  }  
  return sObj;
 }

LazyHolder Pattern

Before object initialization itself, we get more than 100 threads span and waits to obtain the lock on synchronized block, then the above sample also will not perform good.

As per Java Language Specification, in JVM, class load and initialization phase is serial. Utilizing this as an advantage, we can initialize the singleton object through some other class initialization phase. This approach works as on-demand(lazy loading) initialization object.

public class SingletonLazyHolder { 
 private SingletonLazyHolder() {
 }
 
 private static class LazyHolder {
  private static final SingletonLazyHolder sObj = new SingletonLazyHolder();
 }
 
 public static SingletonLazyHolder getInstance() {  
  return LazyHolder.sObj;
 }
}

Multiton Pattern

Multiton pattern alows to have map of named instances as key-value pairs, in which getInstance() method key has to be passed and specific instance get initialized and returned.

MultitonSample.java:
import java.util.HashMap;
import java.util.Map;

public class MultitonSample {
 private static final Map<String,MultitonSample> maps = new HashMap<String,MultitonSample>();

 private MultitonSample() {
 }

 public static MultitonSample getInstance(String key) {
  MultitonSample mObj = null;
  synchronized(maps)
  {
   mObj = maps.get(key);
   if(null == mObj)
   {
    mObj = new MultitonSample();
    maps.put(key, mObj);
   }
  }
  return mObj;
 }
}

Monday, October 4, 2010

DataTypeConverter usage in JAXB

JAXB : DataTypeConverter

Accessing the actual value as-it-is using JAVA API will be pain in some cases. For instance, list of values get stored in attribute with comma separation. Now, these value has to be retrieved as List object rather String object, then only it make sense and simple to use.

We are extending the sample written in JAXB Sample post to explain DataTypeConverter and XMLAdapter.

fruits.xsd

<?xml version="1.0" encoding="utf-8"?>
<schema targetNamespace="http://mycompany.org/jaxbsample"
 xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1">
 <annotation>
  <appinfo>
   <jaxb:schemaBindings>
    <jaxb:package name="jaxbexample.model" />
   </jaxb:schemaBindings>
  </appinfo>
 </annotation>


 <element name="Fruits">
  <complexType>
   <sequence>
    <element name="Fruit" maxOccurs="unbounded">
     <complexType>
      <attribute name="name" type="string" />
      <attribute name="qty" type="int" />
      <attribute name="listValue" type="string">
       <annotation>
        <appinfo>
         <jaxb:property>
          <jaxb:baseType>
           <jaxb:javaType
            name="Object"
            parseMethod="jaxbexample.DataTypeConverter.parseStringToList"
            printMethod="jaxbexample.DataTypeConverter.printListToString" />
          </jaxb:baseType>
         </jaxb:property>
        </appinfo>
       </annotation>
      </attribute>
     </complexType>
    </element>
   </sequence>
  </complexType>
 </element> 
</schema>

jaxbexample.DataTypeConverter is a JAVA file and it has two methods parseStringToList, printListToString. In the time of generating JAXB beans, Adapter1.java is get created in jaxbexamples.model package.

DataTypeConverter.java

package jaxbexample;

import java.util.ArrayList;
import java.util.List;

public class DataTypeConverter {

 /** This method called in the time of unmarshalling
  * XML to Java
  * @param value
  * @return
  */
 public static List<String> parseStringToList(String value) {
  
  List<String> list = new ArrayList<String>();
  if (null == value || "".equals(value))
   return list;

  
  String[] strs = value.split(",");
  for (String str : strs) {
   list.add(str);
  }

  return list;
 }

 /** This method called in the time of marshalling
  * Java to XML
  * @param val
  * @return
  */
 public static String printListToString(List<String> val) {

  if (null == val)
   return null;

  StringBuilder sb = new StringBuilder();
  for (String str : val) {
   if (sb.length() > 0)
    sb.append(",");
   sb.append(str);
  }

  return sb.toString();
 }
}

JAXBAdapterSample.java

package jaxbexample;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import jaxbexample.model.Fruits;
import jaxbexample.model.Fruits.Fruit;

public class JAXBAdapterSample {

 public static void main(String[] args) throws Exception {

  String filename = "./jaxbexample/fruits.xml";
  InputStream is = new FileInputStream(filename);

  Fruits fruits = (Fruits) unmarshallObject(is);

  for (Fruit fruit : fruits.getFruit()) {
   System.out.println("Name : " + fruit.getName() + " Qty:"
     + fruit.getQty());

   fruit.setQty(fruit.getQty() + 1);
   int i = 1;
   for (String possiblefruit : (List<String>) fruit.getListValue()) {
    System.out.println(i++ + ". " + possiblefruit);
   }
  }
 }

 public static Object unmarshallObject(InputStream is) throws Exception {
  String packageName = "jaxbexample.model";
  JAXBContext context = JAXBContext.newInstance(packageName);
  Unmarshaller unmarshaller = context.createUnmarshaller();
  Object jaxbObject = unmarshaller.unmarshal(is);
  return jaxbObject;

 }

 public static void marshallObject(Object o, String filename)
   throws Exception {
  String packageName = "jaxbexample.model";
  File f = new File(filename);

  JAXBContext context = JAXBContext.newInstance(packageName);
  Marshaller marshaller = context.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

  OutputStream fos = new FileOutputStream(f);
  marshaller.marshal(o, fos);

  try {
   fos.close();
  } finally {
   // do nothing
  }
 }

}

output

Name : Apple Qty:10
1. Apple
2. Orange
3. Banana
Name : Orange Qty:5
1. Apple
2. Orange
3. Banana
Name : Banana Qty:20
1. Apple
2. Orange
3. Banana

Simple JAXB Sample

JAXB

Java Architecture for XML Binding (JAXB) helps to read/write XML Document using simple JAVA APIs. Based on the structure of the XSD, JAVA classes and APIs are generated.

JAXB implementation from eclipse can be downloaded from Nightly Build. MoXy(JAXB) has the necessary tools, and runtime jars. To create java classes jaxb-compiler command get used

jaxb-compiler.cmd /tmp/fruits.xsd -d /eclipse/work/TestProject

Now, JAVA files will be created in /eclipse/work/TestProject location under the package jaxbexample.model. Since this package name mentioned in XSD.

fruits.xsd

<?xml version="1.0" encoding="utf-8"?>
<schema targetNamespace="http://mycompany.org/jaxbsample"
 xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="1.0">
 <annotation>
  <appinfo>
   <jaxb:schemaBindings>
    <jaxb:package name="jaxbexample.model" />
   </jaxb:schemaBindings>
  </appinfo>
 </annotation>


 <element name="Fruits">
  <complexType>
   <sequence>
    <element name="Fruit" maxOccurs="unbounded">
     <complexType>
      <attribute name="name" type="string" />
      <attribute name="qty" type="int" />
      <attribute name="listValue" type="string">
      </attribute>
     </complexType>
    </element>
   </sequence>
  </complexType>
 </element> 
</schema>

UnMarshalling

Load the XML content and convert to JAVA object in runtime.


public static Object unmarshallObject(InputStream is) throws Exception {
  String packageName = "jaxbexample.model";
  JAXBContext context = JAXBContext.newInstance(packageName);
  Unmarshaller unmarshaller = context.createUnmarshaller();
  Object jaxbObject = unmarshaller.unmarshal(is);
  return jaxbObject;

 }

Marshalling

Convert/persist JAVA object into XML Document content.


public static void marshallObject(Object o, String filename) throws Exception {
  String packageName = "jaxbexample.model";
  File f = new File(fileName);
  
  JAXBContext context = JAXBContext.newInstance(packageName);
  Marshaller marshaller = context.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

  OutputStream fos = new FileOutputStream(f);
  marshaller.marshal(o, fos);

  try {
   fos.close();
  } finally {
   // do nothing
  }
 }

fruits.xml

Create fruits.xml file in jaxbexamples package as below

<?xml version="1.0" encoding="UTF-8"?>
<Fruits xmlns="http://mycompany.org/jaxbsample" xmlns:ns0="http://mycompany.org/jaxbsample">
   <Fruit name="Apple" qty="10" listValue="Apple,Orange,Banana"/>
   <Fruit name="Orange" qty="5" listValue="Apple,Orange,Banana"/>
   <Fruit name="Banana" qty="20" listValue="Apple,Orange,Banana"/>
</Fruits>

JAXBSample.java


package jaxbexample;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import jaxbexample.model.Fruits;
import jaxbexample.model.Fruits.Fruit;

public class JAXBSample {

 public static void main(String[] args) throws Exception {

  String filename = "./jaxbexample/fruits.xml";
  InputStream is = new FileInputStream(filename);

  Fruits fruits = (Fruits) unmarshallObject(is);

  for (Fruit fruit : fruits.getFruit()) {
   System.out.println("Name : " + fruit.getName() + " Qty:"
     + fruit.getQty());

   fruit.setQty(fruit.getQty() + 1);
  }
  marshallObject(fruits, filename);
 }

 public static Object unmarshallObject(InputStream is) throws Exception {
  String packageName = "jaxbexample.model";
  JAXBContext context = JAXBContext.newInstance(packageName);
  Unmarshaller unmarshaller = context.createUnmarshaller();
  Object jaxbObject = unmarshaller.unmarshal(is);
  return jaxbObject;

 }

 public static void marshallObject(Object o, String filename)
   throws Exception {
  String packageName = "jaxbexample.model";
  File f = new File(filename);

  JAXBContext context = JAXBContext.newInstance(packageName);
  Marshaller marshaller = context.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

  OutputStream fos = new FileOutputStream(f);
  marshaller.marshal(o, fos);

  try {
   fos.close();
  } finally {
   // do nothing
  }
 }
}

Output

After running first time the above given JAXBSample program, the @qty will be increased by 1.

Name : Apple Qty:11
Name : Orange Qty:6
Name : Banana Qty:21

Some useful links JAXB @ Oracle | jaxb.dev.java.net

Wednesday, September 15, 2010

ObjectOutputStream with base64 Encoding

ObjectOutputStream with base64 Encoding

Most of the time we do write simplestic code to persist object state using ObjectOutputStream. This will work most of the serializable objects, however some cases serialized objects comes with multi-byte character. In this case, while converting persisted object to java object, we end up seeing weired exception message. To avoid this inconsistent, we have to get a help of any encoder. I have tried with base64 encoding mechanism, I did not face any issues.

Please follow the link, which explains with a sample of no encoding used to persist Java Objects

javax.mail.internet.MimeUtility class helps to encode/decode in base63 format. Generally, this class comes as part of mail.jar as a java extension tool.


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.mail.internet.MimeUtility;

public class ObjectStreamBase64Test {
public static void main(String[] args) throws Exception {
List emp = new ArrayList();
emp.add("1");
emp.add("second Object");
emp.add("Krishna 3");
emp.add("last");

ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream mout = MimeUtility.encode(bos, "base64");
ObjectOutputStream out = new ObjectOutputStream(mout);
out.writeObject(emp);
out.flush();

byte[] bytes = bos.toByteArray();
String str = new String(bytes);

System.out.println("base64 Encoded String: \n"+str);

ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes());
ObjectInputStream in = new ObjectInputStream(MimeUtility.decode(bis,
"base64"));
Object obj = in.readObject();
ArrayList emp1 = (ArrayList) obj;
System.out.println("\nArrayList values:\n"+emp1);

}
}
Spring Recipes: A Problem-Solution Approach, Second Edition

Output

base64 Encoded String: 
rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAEdwQAAAAK
dAABMXQADXNlY29uZCBPYmplY3R0AAlLcmlzaG5hIDN0AARsYXN0eA==

ArrayList values:
[1, second Object, Krishna 3, last]

Wednesday, June 23, 2010

Cache - Least Recently Used Algorithm

LRU algorithm is heavily used in most of the cache implementation. In general, most of the time we depend on heavy weighted caching implementation and end up paying huge for that softwares.

java.util.LinkedHashMap provides simplest way to do this by overriding a method removeEldestEntry().

Here, I would like to present as an utilit class which will be reused our needs. New class LRUHashMap created from LinkedHashMap and cacheSize limit has to be passed as argument.

LRUHashMap Implementation

LRUHashMap.java 
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * LRUHashMap implements Least Recently Used algorithm to store and retrive the
 * values from {Map}.
 */

public class LRUHashMap<K, V> extends LinkedHashMap<K, V> {

 private static final long serialVersionUID = -6805360112277349979L;
 private final static int DEFAULT_INITIALCAPACITY = 10;
 private final static float LOADFACTOR = 0.75f;

 /**
  * Number of entries possible to keep maximum in given time in this {Map}
  */
 private final int cacheSize;

 public LRUHashMap() {
  super(DEFAULT_INITIALCAPACITY, LOADFACTOR, true);
  cacheSize = -1;
 }

 public LRUHashMap(int cacheSize) {
  super(DEFAULT_INITIALCAPACITY, LOADFACTOR, true);
  this.cacheSize = cacheSize;
 }
 
 /**
  * @param initialCapacity
  */
 public LRUHashMap(int initialCapacity, int cacheSize) {
  super(initialCapacity, LOADFACTOR, true);
  this.cacheSize = cacheSize;
 }

 /**
  * @param m
  */
 public LRUHashMap(Map<K, V> m, int cacheSize) {
  super(DEFAULT_INITIALCAPACITY, LOADFACTOR, true);
  putAll(m);
  this.cacheSize = cacheSize;
 }

 /**
  * @param initialCapacity
  * @param loadFactor
  */
 public LRUHashMap(int initialCapacity, float loadFactor, int cacheSize) {
  super(initialCapacity, loadFactor, true);
  this.cacheSize = cacheSize;
 }



 
 /** To achieve Thread Safe
 * @return
 */
 public Map<K, V> getsynchronizedMap()
 {
  return Collections.synchronizedMap(this);
 }

 @Override
 protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
  return size() > cacheSize;
 }
}

Test

LRUHashMapTest.java

public class LRUHashMapTest {

 public static void main(String[] args) {
  Map<Integer, String> map = new LRUHashMap<Integer, String>(10);
  
  //Enables Thread Safe
  //map = ((LRUHashMap<Integer, String>)map).getsynchronizedMap();
  
  for (int i = 0; i < 100; i++) {
   map.put(i, "valueof :" + i);

   for (int j = i - 5; j >= 0; j--)
    map.get(j);
  }

  System.out.println(map);
 }
}

Here, Cache Size set to 10, hence at any given time only 10 entries will be stored in Map. Additionally, whenever read access happens that object will be removed from actual location and added to rear of Map.

Output:

{95=valueof :95, 96=valueof :96, 97=valueof :97, 98=valueof :98, 99=valueof :99,
 4=valueof :4, 3=valueof :3, 2=valueof :2, 1=valueof :1, 0=valueof :0}

Thread Safe

The above mentioned implementation alone will not achieve thread safe. If our application is multi-threaded then we may need to fall-back to Collections.SynchronizedMap. We can achieve this by calling getsynchronizedMap(); in LRUHashMap.
Map<Integer, String> map = ((LRUHashMap<Integer, String>)map).getsynchronizedMap();

Monday, June 7, 2010

PropertyIgnoreCase

java.util.Properties helps to store and retrieve the key-value pair, where non-null values in key and value. This implementation made on top of java.util.HashTable. We do get all the features and APIs of HashTable additionally, getProperty(...), load() APIs.

In getProperty method, key has to be passed as argument to retrive the value. We can even specify the default value also in it, if no key found in list.

Then, What makes different in this blog posting ?. Here, the key is case-sensitive one. We have to send exact word to get the value. Most of the time, we may need to retrieve value for case-insensitive key. This is where, why don't we extend the functionality to give support to retrieve value with case-insensitive key.

Here, Properties extended to create PropertyIgnoreCase class, and added two APIs - getPropertyIgnoreCase(String key), getPropertyIgnoreCase(String key, String defaultV)


import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

public class PropertyIgnoreCase extends Properties {

 private static final long serialVersionUID = 7511088737858527084L;

 /**
  * get value from {Properties}
  * 
  * @param props
  * @param key
  * @return
  */
 public String getPropertyIgnoreCase(String key) {
  return getPropertyIgnoreCase(key, null);
 }

 /**
  * get value from {Properties}, if no key exist then return default value.
  * 
  * @param props
  * @param key
  * @param defaultV
  * @return
  */
 public String getPropertyIgnoreCase(String key, String defaultV) {
  String value = getProperty(key);
  if (null != value)
   return value;

  // Not matching with the actual key then
  Set<Entry<Object, Object>> s = entrySet();
  Iterator<Entry<Object, Object>> it = s.iterator();
  while (it.hasNext()) {
   Entry<Object, Object> entry = it.next();
   if (key.equalsIgnoreCase((String) entry.getKey())) {
    return (String) entry.getValue();
   }
  }
  return defaultV;
 }

 public static void main(String[] args) {
  PropertyIgnoreCase props = new PropertyIgnoreCase();
  props.put("Abc", "Value of Abc");
  props.put("xYZ", "Value of xYZ");

  System.out.println("get Key 'XYZ' using API from Properties = "
    + props.getProperty("XYZ"));
  System.out.println("get Key 'XYZ' using new API  = "
    + props.getPropertyIgnoreCase("XYZ"));
 }

}
Output:
get Key 'XYZ' using API from Properties = null
get Key 'XYZ' using new API  = Value of xYZ

Thursday, March 11, 2010

Sample XSLT Processor

Extensible Style Language Transformation (XSLT) helps to convert an XML from one form to another. Resulting format could be anything, it could be XML, HTML, XFDF, and etc.,.

XSLT Mapper file

Most of the IDE provides XSLT auto mapping facility to convert/map from one XSD format to another XSD format. XPATH, XQuery, and XSLT functions helps to locate and manipulate the source XML file and result the format in target.

XSLT Processor

XSLT processing capability/library comes with most of the popular languages.


import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;

import oracle.xml.parser.v2.DOMParser;
import oracle.xml.parser.v2.XMLDocument;
import oracle.xml.parser.v2.XMLParseException;
import oracle.xml.parser.v2.XSLException;
import oracle.xml.parser.v2.XSLProcessor;
import oracle.xml.parser.v2.XSLStylesheet;

import org.xml.sax.SAXException;

public class XSLTTransformation {
public static void main(String[] args) throws MalformedURLException,
XSLException, XMLParseException, SAXException, IOException {

URL xslURL = new URL("file:///tmp/shiporder.xsl");

URL xmlURL = new URL("file:///tmp/shiporder.xml");

XSLProcessor processor = new XSLProcessor();
XSLStylesheet xsl = processor.newXSLStylesheet(xslURL);

// parser input XML content
DOMParser parser = new DOMParser();
parser.setPreserveWhitespace(true);
parser.parse(xmlURL);

XMLDocument xml = parser.getDocument();
processor.showWarnings(true);
processor.setErrorStream(System.err);

// Transform the document
StringWriter strWriter = new StringWriter();
processor.processXSL(xsl, xml, new PrintWriter(strWriter));

System.out.println("Transformed XML file: "
 + strWriter.getBuffer().toString());
strWriter.close();
}
}
javas -cp xmlparserv2.jar XSLTTransformation.java

javas -cp xmlparserv2.jar XSLTTransformation

In the following xml file, If we apply below given XSLT then city and note element are get removed.

shiporder.xml

<?xml version="1.0" encoding="UTF-8" ?>
<shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.example.org a.xsd" 
orderid="1" ns0="ns02" xsi="xsi3" xmlns="http://www.example.org">
   <orderperson>orderperson4</orderperson>
   <shipto>
      <name>name5</name>
      <address>address6</address>
      <city>city7</city>
      <country>country8</country>
   </shipto>
   <item>
      <title>title9</title>
      <note>note10</note>
      <quantity>11</quantity>
      <price>120.72</price>
   </item>
   <item>
      <title>title13</title>
      <note>note14</note>
      <quantity>15</quantity>
      <price>160.73</price>
   </item>
   <item>
      <title>title17</title>
      <note>note18</note>
      <quantity>19</quantity>
      <price>200.73</price>
   </item>
</shiporder>

shiporder.xsl

<?xml version="1.0" encoding="UTF-8" ?>
<?oracle-xsl-mapper
  <!-- SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY. -->
  <mapSources>
    <source type="XSD">
      <schema location="../a.xsd"/>
      <rootElement name="shiporder" namespace="http://www.example.org"/>
    </source>
  </mapSources>
  <mapTargets>
    <target type="XSD">
      <schema location="../b.xsd"/>
      <rootElement name="shiporder" namespace="http://www.example.org"/>
    </target>
  </mapTargets>
  <!-- GENERATED BY ORACLE XSL MAPPER 11.1.1.2.0(build 091116.1400.3492) AT [THU MAR 11 12:51:59 IST 2010]. -->
?>
<xsl:stylesheet version="1.0"
                xmlns:xpath20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
                xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
                xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.MediatorExtnFunction"
                xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:ns0="http://www.example.org"
                xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"
                xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:med="http://schemas.oracle.com/mediator/xpath"
                xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"
                xmlns:bpm="http://xmlns.oracle.com/bpmn20/extensions"
                xmlns:xdk="http://schemas.oracle.com/bpel/extension/xpath/function/xdk"
                xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:ora="http://schemas.oracle.com/xpath/extension"
                xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator"
                xmlns:ldap="http://schemas.oracle.com/xpath/extension/ldap"
                exclude-result-prefixes="xsi xsl ns0 xsd xpath20 bpws mhdr oraext dvm hwf med ids bpm xdk xref ora socket ldap">
  <xsl:template match="/">
    <ns0:shiporder>
      <xsl:attribute name="orderid">
        <xsl:value-of select="/ns0:shiporder/@orderid"/>
      </xsl:attribute>
      <xsl:attribute name="ns0">
        <xsl:value-of select="/ns0:shiporder/@ns0"/>
      </xsl:attribute>
      <xsl:attribute name="xsi">
        <xsl:value-of select="/ns0:shiporder/@xsi"/>
      </xsl:attribute>
      <xsl:attribute name="schemaLocation">
        <xsl:value-of select="/ns0:shiporder/@schemaLocation"/>
      </xsl:attribute>
      <ns0:orderperson>
        <xsl:value-of select="/ns0:shiporder/ns0:orderperson"/>
      </ns0:orderperson>
      <ns0:shipto>
        <ns0:name>
          <xsl:value-of select="/ns0:shiporder/ns0:shipto/ns0:name"/>
        </ns0:name>
        <ns0:address>
          <xsl:value-of select="/ns0:shiporder/ns0:shipto/ns0:address"/>
        </ns0:address>
        <ns0:country>
          <xsl:value-of select="/ns0:shiporder/ns0:shipto/ns0:country"/>
        </ns0:country>
      </ns0:shipto>
      <xsl:for-each select="/ns0:shiporder/ns0:item">
        <ns0:item>
          <ns0:title>
            <xsl:value-of select="ns0:title"/>
          </ns0:title>
          <ns0:quantity>
            <xsl:value-of select="ns0:quantity"/>
          </ns0:quantity>
          <ns0:price>
            <xsl:value-of select="ns0:price"/>
          </ns0:price>
        </ns0:item>
      </xsl:for-each>
    </ns0:shiporder>
  </xsl:template>
</xsl:stylesheet>
Refer Convert XMLElement/XMLDocument to String

Friday, February 12, 2010

IBM: DB Tools dbbeans.jar

DBBeans.jar

IBM DBBeans.jar comes with elegant APIs for JDBC and simplifies JDBC. Approx +/- 25 JAVA files implemented to do this. This jar is shipped as part of WSAD/RAD in datatools plugin. This jar is DB acqnostic and ready to use directly in application

In JDBC implementation, we have to establish DB connection and then create statement from connection. However, in this jar, we can tag a connection in a statement bean object.

DBStatement is the super class which helps to define statements. DBStatement offers API to release the resource in various levels by calling close(...) API. DBStatement comes with three different flavours

DBSelect
created and used to select rows from DB, which gives facility to retrieve number of rows fetched.
DBModify
makes insert or update or delete operation in DB
DBProcedureCall
calls stored procedure in DB. This class is subclass of DBSelect

DBSelectBeanInfo, DBModifyBeanInfo, DBProcedureCallBeanInfo are the beans stores information for the above listed statements.

DB Events

This implementation facilitate to triggers events before/after calling/executing the DBStatement. We can achive this by registering listener(DBBeforeListener/DBAfterListener) implemented classes in DBStatement.


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.ibm.db.beans.DBModify;
import com.ibm.db.beans.DBProcedureCall;
import com.ibm.db.beans.DBSelect;
import com.ibm.db.beans.DBStatement;

public class DBStatementFactory {

 public static DBSelect getDBSelect() {
  DBSelect dbSelect = new DBSelect();
  dbSelect = (DBSelect) initializeDBStatement(dbSelect);
  return dbSelect;
 }

 public static DBModify getDBModify() {
  DBModify dbModify = new DBModify();
  dbModify = (DBModify) initializeDBStatement(dbModify);
  return dbModify;
 }

 public static DBProcedureCall getDBProcedureCall() {
  DBProcedureCall dbProcedureCall = new DBProcedureCall();
  dbProcedureCall = (DBProcedureCall) initializeDBStatement(dbProcedureCall);
  return dbProcedureCall;
 }

 public static DataSource getDataSource() throws ServiceLocatorException {
  //write a logic to get DataSource
 }

 private static DBStatement initializeDBStatement(DBStatement dbStatement) {
  try {
   Connection conn = getDataSource().getConnection();
   dbStatement.setConnection(conn);
   dbStatement.setOptimizeForNoListeners(true);
  } catch (Exception e) {
   e.printStackTrace();
  }
  return dbStatement;
 } 
}

DBConnectionSpec

If we want to establish connection without any of connection pooling mechanism, this class helps to do that.

private static DBStatement initializeDBStatement(DBStatement dbStatement) {
 try {
 DBConnectionSpec connectionSpec = new DBConnectionSpec();
 connectionSpec.setUsername(user);
 connectionSpec.setPassword(password);
 connectionSpec.setDriverName(driver);
 connectionSpec.setUrl(url);
 
 dbStatement.setConnectionSpec(connectionSpec);
 } catch (Exception e) {
    e.printStackTrace();
 }
}

DBSelectMetaData

DBSelectMetaData stores meta data of DBSelect which will be resulted out after execution

DBSelectMetaData dm= dbSelect.getMetaData();
for(int i=0;i<dm.getColumnCount();i++)
{
System.out.println(dm.getColumnName(i)+" Type:"+dm.getColumnType());
}

DBSelect and ResultSet

Create DBSelect statement and tag with DB connection using DBStatementFactory class and then set SQL command using setCommand(). Once all set to go then execute() has to be called to retrieve data from DB.


String SELECT_ALL_SHIRTS_CATALOGS = "SELECT SHIRTNAME, SHIRTDESC FROM catalogs";
public void displayAllShirtsCatalogs() throws Exception { 
  DBSelect dbSelect = null;
  try {
   DBSelect dbSelect = DBStatementFactory.getDBSelect();
   dbSelect.setCommand(SELECT_ALL_SHIRTS_CATALOGS);

   dbSelect.execute();

   if (dbSelect.onRow()) {
    int size = dbSelect.getRowCount();
    do {
  System.out.println(dbSelect.getColumn(1) 
  + " " + dbSelect.getColumn(2)); 
    } while (dbSelect.next());
   }

  } finally {
   dbSelect.close(DBStatement.LEVEL_CONNECTION);
  } 
 }
 

Tuesday, February 9, 2010

Sample HTTPs Server

HTTPS server

As similar to building HTTP server, we have to establish the ServerSocket with SSL certificates. Client has to confirm the certificate and its validity by checking the Certification Path.

EnabledCipherSuites

SSLServerSocket or SSLSocket provides api to retrieve the supported CipherSuites combinations


String[] ecs=socket.getEnabledCipherSuites();

Results:

SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA

EnabledProtocols

Supported security protocols are listed by getEnabledProtocols() APIs


String[] eps=socket.getEnabledProtocols()

Results:

SSLv2Hello
SSLv3
TLSv1

This protocol names used while creating SSLContext object.

KeyManagerFactory

This class holds the details of how the keys are managed to secure the sockets. Default would be SunX509. We can parallely come to know from file JAVA_HOME/jre/lib/security/java.security. Similarly, keystore type would be JKS


import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.util.Enumeration;
import java.util.Properties;

import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;

public class HTTPs {

 public static final String CONTENT_LENGTH = "Content-length";
 public static final String CONTENT_TYPE = "Content-type";

 private static char NEW_LINE = '\n';

 private static final String EOL = "\r\n";

 private BufferedInputStream is;
 private DataOutputStream os;
 String keystore = "/tmp/keystore.jks";
 char keystorepass[] = "welcome1".toCharArray();
 char keypassword[] = "welcome2".toCharArray();

 private static final String SC_NO_CONTENT = "HTTP/1.1 200 No Content" + EOL
   + "Content-Type: text/plain" + EOL + "Cache-Control: private" + EOL
   + EOL;

 // The port number which the server will be listening on
 public static final int HTTPS_PORT = 7777;

 public ServerSocket getServerSocket() throws Exception {

  KeyStore ks = getKeyStore();

  KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
    .getDefaultAlgorithm());
  kmf.init(ks, keypassword);

  SSLContext sslcontext = SSLContext.getInstance("SSLv3");
  sslcontext.init(kmf.getKeyManagers(), null, null);
  ServerSocketFactory ssf = sslcontext.getServerSocketFactory();
  SSLServerSocket serversocket = (SSLServerSocket) ssf
    .createServerSocket(HTTPS_PORT);

  return serversocket;
 }

 private KeyStore getKeyStore() {
  try {
   KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
   ks.load(new FileInputStream(keystore), keystorepass);
   return ks;
  } catch (Exception e) {
   System.out.println(e.getLocalizedMessage());
   System.exit(-1);
  }

  return null;

 }

 // multi-threading -- create a new connection
 // for each request
 public void run() {
  ServerSocket listen;
  try {
   listen = getServerSocket();
   while (true) {
    Socket socket = listen.accept();

    is = new BufferedInputStream(socket.getInputStream());
    os = new DataOutputStream(socket.getOutputStream());
    readHTTPMessage();

    StringBuffer strbuffer = new StringBuffer();

    strbuffer.append(SC_NO_CONTENT);
    writebytes(socket, strbuffer.toString());
   }
  } catch (Exception e) {
   System.out.println("Exception: " + e.getMessage());
  }
 }

 private void writebytes(Socket socket, String data) {
  try {
   //
   os.write(data.getBytes());
   os.flush();
   if (!socket.isClosed())
    is.close();
   if (!socket.isClosed())
    os.close();

  } catch (Throwable e) {
   System.out.println(e);
  }

  try {
   if (!socket.isClosed())
    socket.close();
  } catch (Throwable e) {
   System.out.println("Problem in data writing in channel");
   System.out.println(e);
  }
 }

 public String readHTTPMessage() throws IOException {
  String result = null;
  StringBuffer strb = new StringBuffer();
  int bufferSize = 1024; // is.available()==0 ? 1024:is.available();
  int contentLength = 0;
  int headerLength = 0;
  int bodyLength = 0;
  try {
   byte[] buf = new byte[bufferSize];
   int nread = 0;
   while ((nread = is.read(buf)) != -1) {
    if (nread == 0)
     continue;
    strb.append(new String(buf, 0, nread));
    // System.out.println(strb);
    result = strb.toString();

    if (contentLength == 0) {

     // atleast 50 bytes required to identify content length
     if (result.length() < 50)
      continue;

     HTTPRequest request = new HTTPRequest(result.getBytes());
     String contentStr = getPropertyIgnoreCase(request
       .getHeaders(), CONTENT_LENGTH);

     // if length specified
     if (null == contentStr || "".equals(contentStr))
      break;

     contentLength = Integer.parseInt("" + contentStr.trim());
     bodyLength = request.getBodyContent().length;
     headerLength = result.length() - bodyLength;
    } else {
     bodyLength = result.length() - headerLength;
    }

    if (bodyLength < contentLength) {
     bufferSize = contentLength - bodyLength;
     buf = new byte[bufferSize];
    } else {

     if (bodyLength >= contentLength || result.endsWith(EOL)) {

      // try{socket.shutdownInput();}catch(Exception e){}
      break;
     }

    }
   }
  } catch (Exception e) {
   System.out.println(e);
  } finally {
   // try{is.close();}catch(Exception e){}

  }
  return result;
 }

 // main program
 public static void main(String argv[]) throws Exception {
  HTTPs https = new HTTPs();
  https.run();
 }

 private class HTTPRequest {

  private byte[] request;

  private int headerIndex = 0;

  private Properties headers;
  private byte[] bodyContent;

  public HTTPRequest(byte[] request) {

   this.request = request;
   init();

  }

  private void init() {

   if (request == null)
    return;

   for (int i = 0; i < request.length; i++) {
    if ((NEW_LINE == (char) request[i]) && (13 == request[i + 1])) {
     headerIndex = i;
     break;
    }
   }

   initHeaders();
   initBodyContent();
  }

  private void initHeaders() {
   String httpMethod;
   String httpVersion;
   String path;
   String headerContent = new String(request, 0, headerIndex);

   String[] availbleHeaders = headerContent.split("\n");

   if (availbleHeaders != null && availbleHeaders.length > 0) {
    String[] typeContainer = availbleHeaders[0].split(" ");

    if (typeContainer != null && typeContainer.length > 2) {
     httpMethod = typeContainer[0];
     path = typeContainer[1];
     httpVersion = typeContainer[2];
    }
   }

   if (availbleHeaders.length > 1) {
    this.headers = new Properties();

    for (int index = 1; index < availbleHeaders.length; index++) {
     String key = availbleHeaders[index].substring(0,
       availbleHeaders[index].indexOf(':'));
     String value = availbleHeaders[index].substring(
       availbleHeaders[index].indexOf(':') + 1,
       availbleHeaders[index].length() - 1);
     this.headers.put(key, value);
    }
   }
  }

  private void initBodyContent() {
   int bodyIndex = headerIndex + 3;
   bodyContent = new byte[request.length - bodyIndex];

   for (int i = (bodyIndex), j = 0; i < request.length; i++, j++) {
    bodyContent[j] = request[i];
   }
  }

  public Properties getHeaders() {
   return headers;
  }

  public byte[] getBodyContent() {
   return bodyContent;
  }
 }

 public static String getPropertyIgnoreCase(Properties props, String key) {
  String value = null;

  Enumeration enum0 = props.propertyNames();
  while (enum0.hasMoreElements()) {
   String name = (String) enum0.nextElement();
   if (key.equalsIgnoreCase(name)) {
    value = props.getProperty(name);
    break;
   }
  }

  return value;
 }
}

prerequisite: Create keystore and keep the same in /tmp folder as mentioned in http://www.javafundu.com/2010/02/keystore-and-keytool.html

Monday, February 8, 2010

KeyStore and KeyTool

KeyStore

A storage/repository to store/retrieve key entries based on a provider format. This entry can be stored in three different format

KeyStore.PrivateKeyEntry
represents Privatekey entry which will be stored and protected from unauthorized access. This key used to singing and decrypting the message. This key is accompanied by a Publickey.
KeyStore.SecretKeyEntry
entry holds javax.crypto.SecretKey
KeyStore.TrustedCertificateEntry
entry contains a single public key Certificate belonging to another party

KeyTool

As part of JAVA SE, the keytool is shipped which helps to create keystore, import/export/print certificates and etc.,. Following are the list of operations possible to using keytool

  • -certreq
  • -changealias
  • -delete
  • -exportcert
  • -genkeypair
  • -genseckey
  • -help
  • -importcert
  • -importkeystore
  • -keypasswd
  • -list
  • -printcert
  • -storepasswd

Sample Keystore

Create keystore with RSA algorithm, where JAVA_HOME/bin folder is set in PATH environment variable


keytool -genkey -keystore keystore.jks -keyalg rsa -alias mykey
Enter keystore password: welcome1
Re-enter new password: welcome1
What is your first and last name?
  [Unknown]:  my.org
What is the name of your organizational unit?
  [Unknown]:  myorg
What is the name of your organization?
  [Unknown]:  myorg
What is the name of your City or Locality?
  [Unknown]:  blr
What is the name of your State or Province?
  [Unknown]:  ka
What is the two-letter country code for this unit?
  [Unknown]:  in
Is CN=my.org, OU=myorg, O=myorg, L=blr, ST=ka, C=in correct?
  [no]:  yes

Enter key password for <mykey>
        (RETURN if same as keystore password): welcome2
Re-enter new password: welcome2
Export Certificate
keytool -export -alias mykey -keystore keystore.jks -keyalg rsa -file myorg_public.cer
Import Certificate
keytool -import -alias mykey -keystore keystore.jks -keyalg rsa -file myorg_public.cer
List Certificate
keytool -list -keystore keystore.jks -keyalg rsa
JarSigner - If we want to ship jars and monitor that whether it get tempared in medium.
jarsigner -keystore keystore.jks -storepass welcome1 -keypass welcome2 -signedjar smycode.jar mycode.jar mykey

KeyStore in JAVA Object

java.security.KeyStore class loads keysore file and provides APIs to do the above listed operations.


private KeyStore getKeyStore()
 {
  try
  {
   KeyStore ks = KeyStore.getInstance("JKS");
   ks.load(new FileInputStream("keystore.jks"), "welcome1");
   return ks;
  }catch (Exception e)
  {
   System.out.println(e.getLocalizedMessage());
  }
  return null;
 }

Oracle PKI key store will be loaded using following code


private KeyStore getOracleKeyStore()
 {
  try
  {
  Security.addProvider(new oracle.security.pki.OraclePKIProvider());
   KeyStore ks = KeyStore.getInstance("PKCS12", "OraclePKI");
   ks.load(new FileInputStream("keystore.jks"), "welcome1");
   return ks;
  }catch (Exception e)
  {
   System.out.println(e.getLocalizedMessage());
  }
  return null;
 }

While creating keystore file, we have to pass oracle.security.pki.OraclePKIProvider as a provider class to the keytool command.

Sun Key Store:
keytool -genkey -keystore keystore.jks -keyalg rsa -alias mykey -providerName SUN -providerClass sun.security.provider.Sun

Wednesday, February 3, 2010

Java Logger with Custom Formatter

In production or development environment, log files are playing major role to identify the nature of the issue and how often it raises. This information reduces the number of question needed to ask customer to understand the issue. Most valuable and precised data has to be captured in log files.

Developers, some time log there native language based log information and product also may shipped with these log information to customer. These kind of non-english or non-locale logs makes customer to panic and get back to vendors ;). Software developers and Quality Assurance folks has to spend considerable effort in stopping these kind of log details.

JAVA logger comes as part of JAVA SE and helps us to easy to configure and store/retrieve log information. Major components in Logger are

Level
specifies levels of information needed to be logged. In production, we may need only SEVERE information. In Development, we may need all information for debugging purpose, we may need to set FINEST or ALL. Possible log levels are OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, and ALL
LogRecord
Log level and message forms log record and it internally keeps time of record creation
Formatter
This component decides, in what format data has to go to log file. In JAVA SE, java.util.logging.XMLFormatter is default one
Handler
this holds the details of where to store and how to rotate and etc.,
Filter
filter decides given logrecord is logable or not
Logger
Exposes factory method to create Logger object for given name
Exposes APIs to log messages in various level.

XMLFormatter and custom formatter used to show how the log records are created in log file in /tmp/ folder.


import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.XMLFormatter;

public class LoggerTest {

 public static void main(String[] args) throws IOException {
  final Logger log = Logger.getLogger("LoggerTest", null);
  log.setLevel(Level.FINEST);
  log.setUseParentHandlers(false);
  FileHandler handler = new FileHandler("/tmp/log.log", false);
  log.addHandler(handler);

  // XML formatted log
  handler.setFormatter(new XMLFormatter());
  log.log(Level.FINEST, "Hello world");

  // Custom formatted log
  handler.setFormatter(new Formatter() {
   @Override
   public String format(LogRecord record) {
    return " custom log - " + log.getName() + " : "
      + record.getMillis() + ":" + record.getMessage();
   }
  });

  log.log(Level.FINEST, "Hello world");
 }
}

User Lockout

In general, password guessing raises serious attack to our application server. Weblogic provides the way to stop guessing the password by locking the particular user, if the number of invalid consecutive password attempt made more than configured.
Banking service applications very much needs this user locking mechanism. If customer found that their account is locked then they have to request the Bank to unlock the account by submitting application or sending email from trusted account. Alternate way would be, unlock automatically after some time, may be a day or two.
Lockout Threshold
specifies number of maximum invalid password attempt possible to make in consecutive attempts.
Lockout Duration
specifies number of minutes to wait for auto unlock once the account locked.
Lockout Reset Duration
lock account only Lockout Threshold reached within this specified minutes. For example, user may be tried to log in yesterday with invalid password. If he tries to login today, then he can attempt to login Lockout Threshold time consecutively with invalid password. If we wants to count the first attempt of yesterday's one, then we have to set minutes value to cover 48 hrs.
Steps to reach User Lockout in weblogic
  1. Login weblogic console
  2. Select Security Realms in Domain Structure panel
  3. In Summary of Security Realms, configured realms will be listed and any of select realms,we go with default myrealm
  4. Select User Lockout tab, where we could see the user lock out properties.

Monday, February 1, 2010

Java Mail

In JAVA Platform Enterprise Edition, javax.activation, and javax.mail packages has APIs to send or receive EMAIL. javax.mail.internet.InternetAddress class helps us to construct Address from String object.

Variety of properties which used to control the flow, monitor the flow, per session based properties and global properties for JAVA Mail. It is very tedious to remember all those properties. However, JAVA Doc is nicely written to list all those properties with brief explanation. Mail Session Properties | MIME properties | sMTP Properties

Mail Send

In the following sample, mail server is running with default port mail.smtp.port:25 in same machine, where this program is get executed. If no Mail server is configured to run in local, then we can configure to point thirdparty mailserver like gmail, hotmail, or rediffmail.


import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailTest {
 private static Session session = null;

 public static void main(String[] args) throws Exception {
  sendMail("krishna.oracleb2b@gmail.com", "abc@abc.com",
    "abc1@abc.com,abc2@abc.com", "Test mail",
    "Hello All, this is test message", true);
 }

 public static void sendMail(String sFrom, String sTo, String sBcc,
   String sSubject, String sBody, boolean sTextBody) throws Exception {
  try {
   Message message = new MimeMessage(getMailSession());
   message.setFrom(new InternetAddress(sFrom));
   InternetAddress to[] = new InternetAddress[1];
   to[0] = new InternetAddress(sTo);
   message.setRecipients(javax.mail.Message.RecipientType.TO, to);

   if (sBcc.length() > 0) {
    message.setRecipients(javax.mail.Message.RecipientType.BCC,
      InternetAddress.parse(sBcc));
   }

   message.setSubject(sSubject);
   if (sTextBody)
    message.setContent(sBody, "text/plain");
   else
    message.setContent(sBody, "text/html");

   Transport.send(message);

  } catch (MessagingException m) {
   m.printStackTrace();
   // throw new ShirtCommonException(m);
  } catch (Exception m) {
   m.printStackTrace();
  }
 }

 /**
  * getMail session
  * 
  * @return
  */
 private static Session getMailSession() {
  if (session == null) {
   // Get system properties
   Properties props = new Properties();

   // Setup mail server
   props.put("mail.smtp.host", "localhost");

   // Get session
   session = Session.getDefaultInstance(props, null);
   session.setDebug(true);
  }
  return session;
 }
}

In the above example, no security details used to send the message. Some server mandates user has to create session with username and password. And even more with SSL enable socket needs to be used to connect. In these cases, Transport has to be instantiated with proper SMTP security properties.Here is the sample for username-password authentication


Transport tr = session.getTransport("smtp");
tr.connect(smtphost, username, password);
msg.saveChanges();
tr.sendMessage(msg, msg.getAllRecipients());
tr.close();

Mail Read

To read mail from MailServer, Mailserver has to support any of the mail reading protocol pop3, imap. Based on this, we have to create instance of javax.mail.Store and get the folder which ever we wants to operate on.


import java.io.InputStream;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;

public class MaieReceivelTest {
 private static Session session = null;

 public static void main(String[] args) throws Exception {
  readMail();
 }

 public static void readMail() throws Exception {
  try {
   Store store = getMailSession().getStore();
   store.connect("localhost", "username", "password");
   
   Folder folder = store.getFolder("Inbox");
   System.out.println(folder.getMessageCount());
   Message[] msgs = folder.getMessages();
   if (null != msgs) {
    for (Message msg : msgs) {

     InputStream is = msg.getDataHandler().getInputStream();
     if (is != null) {
      byte[] bytes = new byte[is.available()];
      is.read(bytes);
      System.out.println(new String(bytes));
     } else {
      Multipart mp = (Multipart) msg.getDataHandler()
        .getContent();
      is = mp.getBodyPart(0).getInputStream();
      byte[] bytes = new byte[is.available()];
      is.read(bytes);
      System.out.println(new String(bytes));
     }

    }
   }

  } catch (MessagingException m) {
   m.printStackTrace();
   // throw new ShirtCommonException(m);
  } catch (Exception m) {
   m.printStackTrace();
  }
 }

 /**
  * getMail session
  * 
  * @return
  */
 private static Session getMailSession() {
  if (session == null) {
   // Get system properties
   Properties props = new Properties();

   // Setup mail server
   props.put("mail.smtp.host", "localhost");
//   mail.smtp.user
      
   // Get session
   session = Session.getDefaultInstance(props, null);
   session.setDebug(true);
  }
  return session;
 }
}

Friday, January 29, 2010

JMS Sample

Java Message Service

JMS APIs provides the way to send, receive messages in enterprises asynchronous way. There is no need of wait for the message to get processed in server and continue the business in client. Just post, and let it get processed. These APIs are bundles under the package javax.jms and JAVA Documentation found at JMS APIs

JMS comes with flavours of messaging - Queue(point-to-point destination) and Topic(publish/subscribe model). Best sample usecase would be, Queue will be useful to communicate any one consumer has to act on request. In cluster environment, Topic helps to send broadcast message to all the nodes.

  • Message types can be byte, text or object messages. JMS provides API to construct message based on the message - javax.jms.TextMessage, javax.jms.ByteMessage, javax.jms.StreamMessage and javax.jms.ObjectMessage.
  • javax.jms.ConnectionFactory helps to define connection configuration properties such as Transaction, LoadBalancing and etc.,. Using ConnectionFactory, Connection get created. Using this javax.jms.Connection, javax.jms.Session is created to post/receive message.
  • Queue/Topic helps to locate or point the destination where the message has to go and/or pulled from.
  • javax.jms.QueueSession exposes APIs to create sender, receiver, browser and Queue.
    QueueBrowser used to read message from Queue without deleting from Queue.
  • javax.jms.TopicSession exposes APIs to create publisher, consumer, and Topic.

Here is simple example code which helps to post/receive text message from weblogic server.


import java.util.Hashtable;

import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class QSendTest {
 public static void main(String[] args) 
 throws Exception {
  QueueConnectionFactory qconFactory = null;
  QueueConnection qcon = null;
  QueueSession qsession = null;
  Queue queue = null;
  TextMessage msg = null;

  InitialContext ctx = getInitialContext();
  qconFactory = (QueueConnectionFactory) 
  ctx.lookup("jms/MyQueueFactory");
  qcon = qconFactory.createQueueConnection();
  qsession = qcon.createQueueSession(false, 
   QueueSession.AUTO_ACKNOWLEDGE);

  queue = (Queue) ctx.lookup("jms/MyQueue");
  
//Posting message to Queue
  QueueSender qsender = qsession.createSender(queue);
  msg = qsession.createTextMessage();
  msg.setStringProperty("MSG_ID", "12345678947");
  msg.setText("Hello at " + System.currentTimeMillis());
  qsender.send(msg);

  System.out.println("Sent");
  qsender.close();

//To receive message from Queue
  qcon.start();
  QueueReceiver qReceiver = qsession.createReceiver(queue);
  while (true) {
   TextMessage txt = (TextMessage)
   qReceiver.receiveNoWait();
   if (txt == null)
    break;
   System.out.println(txt.getText() 
   + "with header MSG_ID="
   + txt.getStringProperty("MSG_ID"));
  }

  qReceiver.close();
  qsession.close();
  qcon.close();
 }

 private static InitialContext getInitialContext()
 throws NamingException {
  Hashtable<String, String> env = new Hashtable<String, String>();
  env.put(Context.INITIAL_CONTEXT_FACTORY,
    "weblogic.jndi.WLInitialContextFactory");
  env.put(Context.PROVIDER_URL, "t3://localhost:7001/");
  return new InitialContext(env);
 }
}

In weblogic, javax.jms_1.1.1.jar has JMS APIs and its implementaions. Before running this program, we have set up JMS configuration in Server. Steps are given below

Create JMS Server
  1. Login weblogic console, select services from Domain structure tab.
  2. Select JMS Servers
  3. In JMS Servers tab, click New
  4. Type MyJMsServer and select AdminServer
  5. click on finish
Create JMS Module
  1. Login weblogic console, select services from Domain structure tab.
  2. Select JMS Modules
  3. In JMS Modules tab, click New
  4. Type MyJMsModule and select AdminServer
  5. click on finish
Create Subdeployments
  1. Login weblogic console, select services from Domain structure tab.
  2. Select MyJMsModule and select subdeployments
  3. li>In Summary of Resources panel, click New
  4. Type MyQueue and select MyJMsServer
  5. click on finish
Create JMS Connection Factory
  1. Login weblogic console, select services from Domain structure tab.
  2. Select JMS Modules and select MyJMsModule
  3. In Summary of Resources panel, click New
  4. Select Connection Factory and say Next
  5. Type Name as MyQueueFactory and JNDI Name as jms/MyQueueFactory
  6. Click Next and Finish
Create JMS Queue
  1. Login weblogic console, select services from Domain structure tab.
  2. Select JMS Modules and select MyJMsModule
  3. In Summary of Resources panel, click New
  4. Select Queue and say Next
  5. Type Name as MyQueue and JNDI Name as jms/MyQueue
  6. Click Next and Finish
Create JMS Queue
  1. Login weblogic console, select services from Domain structure tab.
  2. Select JMS Modules and select MyJMsModule and MyQueue
  3. In Summary of Resources panel, click New
  4. Select Queue and say Next
  5. Type Name as MyQueue and JNDI Name as jms/MyQueue
  6. Click Next and Finish

Monday, January 25, 2010

JDBC

Java Database Connectivity (JDBC)

JDBC is the industry standard for database agnostic connectivity, where developer can read/write data from/to DBMS, without worry about the platform, DBMS and its implementation. SQL or non-SQL based possible to connect using this JDBC. We have to make a call using JDBC where it takes responsibility of how it has to be translated to DB calls and vice versa.

Types of JDBC Drivers

JDBC-ODBC bridge
access through ODBC drivers. Performance of this connection is not good compare with others
Native-API partly Java technology-enabled driver
Converts JDBC calls into direct DB API calls. Some DB binaries has to be placed in client system.
Net-protocol fully Java technology-enabled driver
JDBC API calls converted into middleware understanable calls, same will convert back to DBMS understandable call by middleware server. Hence, DB vendors has to support and adhere with middleware and vice versa.
Native-protocol fully Java technology-enabled driver
converts JDBC API calls to network protocol which is supported by DBMS vendor. Hence, client machine directly access DB without middleware.

Connection Establishment

After successful installation of Database, We have to start the Database with listening port number, default port numbers MySQL(3306), Oracle(1521). Following steps has to be catered in our implementation to establish connection.
  1. Load and Register Driver class, which has static block to set DriverInfo (driver, driverClass, driverClassName) using java.sql.DriverManager.registerDriver.
    Class.forName("oracle.jdbc.OracleDriver");
  2. Form Connection URL, which helps to identify which DB driver has to be used as like jdbc:subprotocol:subname
     String url = "jdbc:oracle:thin:@xyz.oracle.com:1521/xyz" ;
  3. Set values for properties like username and password, and etc.,or pass credentials while creating/fetching connection from DriverManager.
    
     java.util.Properties info = new java.util.Properties();
     info.put("user", user);
     info.put("password", password);
  4. Fetch/create connection from DriverManager
    
    java.sql.Connection conn=getConnection(url, info);
    or
    java.sql.Connection conn=getConnection(url, user, password);
    

Loading Class

Class.forName(className) is equivalent to Class.forName(className, true, ClassLoader.getCallerClassLoader()), where true says that className class can be intialized(static blocks get executed). Almost all the the Driver has the following code to register DriverInfo to DriverManager


static 
{
 try
 {
 DriverManager.registerDriver(new Driver());
 }
 catch(SQLException E)
 {
 throw new RuntimeException("Can't register driver!");
 }
}

DataSource

Instead of creating connection from DriverManager and maintaing it, we can fetch the unused connection from javax.sql.DataSource, which will take care of lifecycle of connection. DataSource comes with three different implementation flavour Basic, ConnectionPool, Distributed

In server based application, we can access DataSource object through JNDI look up.


InitialContext ic = new InitialContext(); 
DataSource ds = ic.lookup("java:jdbc/mydb/MyDataSource");
Connection con = ds.getConnection(); 

In standalone application also, we can


DataSource ds = new OracleDataSource();
 ds.setURL(url);
 ds.setUser(user)
 ds.setPassword(password); 
Connection con = ds.getConnection(); 

Statement

Once Connection establishment is completed, we can get start with reading/writing to Database. To input our requirement to DB, we need an interface that is nothing but a java.sql.Statement.

Statement comes in three different flavour

  1. Statement - to run Dynamic SQL queries, which will be parsed and compiled everytime it gets executed.
  2. Prepare Statement - to run parameterized SQL query with getting benefit of precompilation of SQL
  3. Callable Statement - to execute stored procedures

Statement can executed using the following API's

  1. execute - executes SQL query and returns true if found first result as ResultSet
  2. executeQuery - used to execute SQL SELECT query and returns ResultSet
  3. executeBatch - executes all the SQL queries which are added using Statement.addBatch(sqlQuery)
  4. executeUpdate - used to execute SQL UPDATE, DELETE, INSERT and TRUNCATE queries and results number of impacted records count

Auto Generated Keys

Generally, we specify primary key columns to auto generate value by DB to avoid duplications. We may need this value in caller place to utilize in other business. Best example would be, in PurchaseOrder scenario, where master entry created with buyer details and date of order in PurchaseOrderMaster entry, where item and quantity lists are captured in PurchaseOrderChild table.

We can request DB driver to send back the generated key to caller by passing Statement.RETURN_GENERATED_KEYS in execute, and executeUpdate APIs.


Statement stmt = con.createStatement();
if(stmt.execute(insertStmt, Statement.RETURN_GENERATED_KEYS))
{
ResultSet rs=stmt.getGeneratedKeys();
while (rs.next()) {
System.out.println(rs.getString(1));
}
}

Maximum Rows and Timeout

Additionally, We can set property like maximum number of rows need to be fetched, maximum time to wait for query to process(Timeout), maximum field size, cursor name, fetching direction and etc.,


stmt.setMaxRows(50);
stmt.setFetchDirection(ResultSet.FETCH_REVERSE);

ResultSet

java.sql.ResultSet captures outcome from DB call. It gives details about the column, and its value. If SQL SELECT statement executed using executeQuery API then we do get ResultSet object as output. This resulted object has cursor which positioned before the first row of result. We have to call next() API to get into first row of result. If no argument passed, while creating connection then we can move the cursor only towards forward

If we wants to move cursor forward and backward then we have to pass ResultSet.TYPE_SCROLL_INSENSITIVE or ResultSet.TYPE_SCROLL_SENSITIVE. We have following APIs to ease the cursor movement - next(), previous(), first(), last(), beforeFirst(), afterLast(), relative(int rows), and absolute(int row)

We can eventually update ResultSet which will be updated in DB. To enable this, we have pass second argument as ResultSet.CONCUR_UPDATABLE, default is ResultSet.CONCUR_READ_ONLY


Statement stmt = con.createStatement(
 ResultSet.TYPE_SCROLL_SENSITIVE,
 ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT 1 FROM DUAL");

ResultSet comes with row manipulating APIs like insertRow(), deleteRow(), updateRow() and refreshRow().

Similarly, ResultSet helps to get value of columns either passing number or column name. First column is refered using 1 and its go on.


int Id=rs.getInt(1);
float amt= rs.getFloat("amount");
Blob blob=rs.getBlob("policy");
Clob clob=rs.getClob("policyinclob");
Reader reader=rs.getCharacterStream("policy");
InputStream is=rs.getBinaryStream("policy");

Release resource

We have established a connection and ran Statement and retrieved result. What next ?

We have to release used resource like Sonnection, statement, and ResultSet. Since these are making physical connection to DB, it is application responsibility to notify Driver to release or pool the resources. close() api called in these resources to release. if connection pooling is enabled, then connection will be collected for reuse.


rs.close();
stmt.close();
conn.close();

Read more : JDBC Basic | JDBC Overview

How to read data from Blob?

java.sql.Blob interface exposes two APIs to read bytes from Blob object.


Blob blob=rs.getBlob("policy");

InputStream is = blob.getBinaryStream() ; //option 1
byte[] bytes = blob.getBytes(1, (int) blob.length()); //option 2

Friday, January 22, 2010

Simple Custom ClassLoader

ClassLoader is provisioning us to bring the JAVA Class to executable format. JAVA SE comes with default ClassLoader and URLClassLoader. First one is called SystemClassLoader, which will access the classes from bootstrap path, classpath, JAVA extension and library. If our application wants to access Class from external URL then URLClassLoader will be useful. If requested class found in specified URLs, then that gets priority than Classpath classes.

Static Classloader will load all the classes from the classpath in startup itself. This class loader is not capable of reloading modified classes from jars in the JVM runtime.

Dynamic Classloader will load classes on demand basis and capable of reloading classes anything found changed.

Custom Classloader will be useful for plugin based applications, application servers and etc., This helps to load and remove class definitions from the JVM. For instance, we are creating instance of class from .class file, if we want to create class from .cls file. We can achive this from Custom Classloader, just implementing two APIs loadClass(), and findClass()

Custom ClassLoader

Custom classloader has to take care of following responsibilities.

  1. Make sure Class not loaded already by any of the parent classloader including system loader
  2. Find Class from repository
  3. Fefine the class by loading the bytes and resolve if needed
  4. Return the class

LoadClass

loadClass() method gets called whenever we try to access new Class. This API is responsible of check

  • Is this class name loaded by current context classloader ?
  • If not found, check parent classloader
  • If no parent found, then check findBootstrapClass loader
  • If none of the above mentioned step aware of Class then call findClass()
In general, we do not need to rewrite this API. It may come necessary, if we wants to change this order or some other thing.

FindClass

findClass method aligns or corrects the Class name to point the actual resource. If we wants to create instance of the String, then we will pass the class name as java.lang.String and Classloader will construct URL as java/lang/String.class and finds this resource from classpath.

In custom Classloader, we may need to give additionally the repository of classes location if we are accessing class form other than classpath.

CustomClassLoader.java

import java.io.FileInputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

public class CustomClassLoader extends ClassLoader {

 String repoLocation = "/tmp/";

 public CustomClassLoader() { }
 
 public CustomClassLoader(ClassLoader parent) {
  super(parent);
 }
 
 @Override
 protected Class<?> findClass(final String name)
   throws ClassNotFoundException {

  AccessControlContext acc = AccessController.getContext();

  try {
   return (Class)AccessController.doPrivileged(
     new PrivilegedExceptionAction() {
      public Object run() throws ClassNotFoundException {

       FileInputStream fi = null;
       try {

        String path = name.replace('.', '/');
        fi = new FileInputStream(repoLocation + path
          + ".cls");
        byte[] classBytes = new byte[fi.available()];
        fi.read(classBytes);
        return defineClass(name, classBytes, 0,
          classBytes.length);
       }catch(Exception e )
       {
        throw new ClassNotFoundException(name);
       }
      }
     }, acc);
  } catch (java.security.PrivilegedActionException pae) {
   return super.findClass(name);
  }
 }
 
 public static void main(String[] args) throws Exception{
  ClassLoader cls= new CustomClassLoader(ClassLoader.getSystemClassLoader());
  Class stringClass=cls.loadClass("ABC");
  stringClass.newInstance();
 }
}
ABC.java

public class ABC {
 public ABC() {
 System.out.println("Hello");
 }
}

After compiling these two classes, rename the ABC.class to ABC.cls and then run java CustomClassLoader

Now, simple class loader which loads class from .cls file.

If we use MANIFEST.MF in jar files to define the package, then attributes will be read using java.util.jar.Manifest. Based on these attributes ClassLoader will behave.

Similar to finding Class from ClassLoader, we can overwrite findResource() and findLibrary() to alter the approach of loading resources and libraries

Wednesday, January 20, 2010

Reverse reading

In C, C++, we have the option to make FILE pointer to point the last byte and make reverse read by decreasing pointer position. However, we do not have option to do the same in Java using pre-existing InputStream or Reader in JAVA SE.

One of the classic cryptography uses reverse the file content and share to the receiver. Receiver also needs to reverse the content and understand the meaning. If we would like to do the same in computer, reversing algorithm useful. However, just reversing will not help we have several mechanism to protect the message over network in modern cryptography.

If we ask our friends to write reversing program, most of them will write a program, in which content first read and put it into bytes or character array and then reverse order will be stored in another byte or character array. This program perform not good for bigger files.


Reader content reversing

To reverse content from java.io.Reader, we do not require char array. We can use StringBuilder which helps us to append/insert content in any index place. Read character one by one from Reader and insert at ZERO location, which will reverse the content.


InputStream content reversing

In InputStream, we have an API available() which gives the content length. byte array will be created using this length. Read bytes from this InputStream and store in byte array with reverse order


import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

public class ReverseReaderTest {
public static void main(String[] args) 
throws Exception {
File f = new File("/tmp/sample.txt");

FileReader fr = new FileReader(f);
System.out.println("Using Reader: \n" + reverseRead(fr));

InputStream is = new FileInputStream(f);
System.out.println("Using InputStream:\n" + reverseRead(is));
}

/**
 * Reverse read using Reader
 * 
 * @param reader
 * @return
 * @throws IOException
 */
public static String reverseRead(Reader reader)
 throws IOException {
StringBuilder sb = new StringBuilder();
int ch = -1;
while ((ch = reader.read()) != -1) {
 sb.insert(0, (char) ch);
}
return sb.toString();
}

/**
 * Reverse read using InputStream
 * 
 * @param is
 * @return
 * @throws IOException
 */
public static String reverseRead(InputStream is) 
throws IOException {
int length = is.available();
byte[] bytes = new byte[length];
int ch = -1;
while ((ch = is.read()) != -1) {
 bytes[--length] = (byte) ch;
}
return new String(bytes);
}
}

Assume, if sample.txt has the content as Hello World , output looks like below

Using Reader: 
dlroW olleH
Using InputStream:
dlroW olleH

Tuesday, January 19, 2010

Exception Utility

In JAVA, Throwable/Exception thrown for many reasons. Based on its impact to the application, Throwable category is splitted into two - Exception, Error.

  • java.lang.Exception indicates that malfunction happened, and possible to correct it using try-catch block.
    • Checked Exception must to be captured in try-catch block to succeed compilation
    • UnChecked Exception need not to be captured in try-catch block to get successful compilation. These exceptions are having java.lang.RuntimeException as super class. Examples, java.lang.IllegalArgumentException, java.lang.ArrayIndexOutOfBoundsException. If we feel JVM may throw this RuntimeException then we may need to use try-catch block to capture it. Java compiler will not enforce us to use try-catch block for unchecked exception. It is developer responsibility to catch this exception, and run resolving code.
  • java.lang.Error indicates that serious problem happened which adviced not to capture using try-catch block.

Cause in Exception

In a method, Exception captured using try-catch block and thrown back to the caller method with reconstructing using some other Exception class. For instance, we got some unknown/unexpected exception in a API, which will be used to create instance of caller understandable Exception and send back to them. While reconstructing, Exception catched will be treated as cause in constructed/new Exception.

Here, very first occuring exception is called Actual Cause. Rest are just used to convey the issue to the root of the caller, where we decide alternate for this issue.

We have to know, how the issue throwing API reached from root?. This will be done by traversing stack trace of Thread from the issue araised line of code. Throwable.printStackTrace() used to get the stack trace of complete Exception and Cause. Actual cause will be displayed in end of the trace. If reconstrcution happened in various layer on the Exception then we will get equal number of Cause trace, which may annoy our customer, even developer.

We have to take a call on this and provide only the issue and trace of the same to Customer/log file. Pushing all the Cause trace, impacts peformance in multi-threaded environment, where we do log variety of details to console/Log file parallely, where as console/Log stream is synchronized which blocks/waits for other thread to relase the lock. Pushing minimal and adequate data increase the performance of application.


Exception Util

In the following sample program, APIs are exposed - getCause(), exceptionToString(),printActualCause().

  • getCause() - helps to retrieve actual cause from Exception
  • exceptionToString() - helps to retrieve stacktrace information as a String object
  • printActualCause() - prints the stacktrace, message of actual cause


import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

public class ExceptionUtil {
/**
 * get Actual cause from the exception thrown
 * 
 * @param throwable
 * @return
 */
public static Throwable getCause(Throwable throwable) {
 if (null == throwable)
  return null;
 Throwable cause = getCause(throwable.getCause());
 if (null == cause)
  cause = throwable;
return cause;
}

/** Converts stacktrace to string
 * @param t
 * @return
 */
private static String exceptionToString(Throwable t) {
String stackTrace = null;
OutputStream os = null;
try {
 os = new ByteArrayOutputStream();
 PrintWriter printWriter = new PrintWriter(os);
 t.printStackTrace(printWriter);
 printWriter.close();
 stackTrace = os.toString();
} catch (Exception exc) {
} finally {
 try {
 os.close();
 } catch (Exception e) {
 //do nothing
 }
}
return stackTrace;
}

public static void printActualCause(Throwable throwable)
{
 Throwable cause=getCause(throwable);
 String stack= exceptionToString(cause);
 String msg=cause.getLocalizedMessage();

 System.out.println(msg+"\n"+stack);
}

public static void main(String[] args) {
try
{
 throw new IllegalArgumentException("Actual exception");
}catch(Exception e)
{
 try
 {
  throw new Exception(e);
 }catch(Exception e1)
 {
  printActualCause(e1);
 }
}
} }

Monday, January 18, 2010

Native payload Parsing

Most of the medium and large organization uses XML format of message to make communication with their customer or vendor. However, still we do fall in native format like EDI, JSON, and etc to transmit data over network. Even in webservice.

XML is the simplest way of transmitting message, however still native format has its own space to popularly used.

Native format defined by Industry standard bodys, and makes organization's life easy by putting hands together to train and develop the community. Specifically, B2B domain runs on top these standards and provisioning to marshall and unmarshalling data from native to xml and xml to native.

Why do we need native format?
Transmitting XML formatted data consumes considerable cost in network than native format.
Large System implemented before XML inventions and found ease of maintenance
Large number of dependencies like customer and vendors system

We may be interested in knowing market share of native and xml payloads. Upto me, I believe still large organizations which transmits very small(less than 1 KB) and very large(100MB) uses native format. XML fits in between of these two extreme.


Scannar


To write converter between native to object/xml or vice versa, we have to write a string parsing program using java.util.StringTokenizer, which will splits the string based on the static delimiters. We do get token only in the form of String, and it is our responsibility of converting into respective primitive format.

java.util.Scanner introduced in Java SE 5.0, in which we can take input either from InputStream, Readable, and String and possible to split using dynamic delimiters. Here, in the below samples, orgScanner used to split Organization name and employee name. Same orgScanner used to split organization name and age.


import java.util.Scanner;

public class ScannerTest {
public static void main(String[] args) {
String input = "Emp Krishna name Dharma Org Oracle " +
  "Age 29 Emp Suresh name Dharma Org Oracle Age 28";
Scanner s = new Scanner(input).useDelimiter("\\s*Emp\\s*");
while (s.hasNext()) {
 processEmployee(s.next());
}
s.close();
}

private static void processEmployee(String empStr) {
Scanner orgScanner = new Scanner(empStr).useDelimiter("\\s*Org\\s*");
if (orgScanner.hasNext()) {
 Scanner nameScanner = new Scanner(orgScanner.next())
   .useDelimiter("\\s*name\\s*");
 System.out.println("FirstName:" + nameScanner.next() + " LastName:"
   + nameScanner.next());
}

if (orgScanner.hasNext()) {
 orgScanner = orgScanner.useDelimiter("\\s*Age\\s*");
 System.out.println("Organization:" + orgScanner.next() + " Age:"
   + orgScanner.nextInt());
} else {
 System.out.println("No Organization specified");
}}
}
 Output:
javac ScannerTest
java ScannerTest

FirstName:Krishna LastName:Dharma
Organization: Org Oracle Age:29
FirstName:Suresh LastName:Dharma
Organization: Org Oracle Age:28

Tuesday, January 12, 2010

Password Masking

In most of our development time, we see security vulnerability bug file for storing password in text file or getting password from commandline without masking the characters.

If it is AWT/SWING/Web application, we can add a keyUp/keyDown event and do the magic. What about in standalone JAVA program. Whatever we type that will be displayed and read using System.in. There is a nice technical article written by Qusay H. Mahmoud with contributions from Alan Sommerer, July 2004 to make password maskin in commandline. For this we have to write a piece of code to mask the character by running a Thread, which has a while-loop continuously run with interrupt using Thread.sleep(1); for 1ms. While entering password, if system load is heavy then the letters might be displayed in console for a while and then converted to asterisk. This is unavoidable in commandline password masking.

Few of us, built Swing application (Login Dialogue) only to receive password without echoing in console. Most of the time, this is what the story upto Java SE 6 ("Mustang").

Console

java.io.Console introduced to solve this password masking issue in Java SE 6.0. This class not only intended for password masking also for formatted string input and output like C language.

System.console().printf("Happy %s year %d", "new",2010);

Iin JVM, Console instance will be, by default, assigned to System.console, if application started from interactive commandline. Console behaviour varies depending on the platform in which application started. Usually, System.in and System.out deals with byte based I/o. However, System.console deals with character based devices. If no redirection specified for I/O then keyboard and monitor will be used as I/O devices by Console.

If application started from IDE like Eclipse, NetBeans, JDEV or as a background job then this Console instance will not be exist and NullPointerException will be thrown out. NPE is special exception which is very much hate by Application Developer and Customer, and the same time, Production support, Sustain Egnineers are happy to take this NPE bugs ;). This exception does not need any intelligence to fix it, just see the exception trace first code line number, make a if check for null, slick. I am going to do samething below, while using Console Object

if(null != System.console()){
 String username=System.console().readLine("Enter username");
 System.out.println("Username is "+new String(username));
}

Here is the example code to read password using console

public class ConsoleTest {
public static void main(String[] args) {
if(null != System.console()){
 char[] paswd=System.console().readPassword("Enter password");
 System.out.println("Password is "+new String(paswd));
}}}

Note: null will be assigned to paswd, only when End of File is reached, means that CTRL+C, CTRL+D, and CTRL+Z.

Sunday, January 10, 2010

Reflection : Dynamic Proxy

Dynamic Proxy: Proxy and InvocationHandler

java.lang.reflect.Proxy class offers the way to create Dynamic proxy for the classes. newProxyInstance API creates proxy enabled object for interfaces implemented in the classes. Interface java.lang.reflect.InvocationHandler implemented class also needs to be passed as an argument to monitor method invoke .


Proxy helps to create delegate classes which will take responsible of an actual class operations. Reflection helps to achive delegation not with to much botheration of actual operation signatures. In general, developer use Proxy most of the time for delegation and debugging.


In pluggable architecture, we register listeners to make calls to our implementation by implementing prescribed interface. Where, calling methods in listener will started by calling some other API. For instance, an Event has listener registered with init, processEvent, commit operations. An API has to implemented to complete Event request, means call these three methods one by one.


public void callEvent()
{
init();
processEvent();
commit();
}

Instead of exposing new API(callEvent) to customer to complete Even, call processEvent API that will internally serve complete operations. Can we ask our customer to call init and commit methods from processEvent method, it won't make sense. Again, we are making things more complicated.

Here, Proxy and InvocationHandler helps us, following lines in invoke() method, does this job. For user, they are calling, their implementation of processEvent method, but in reality pre and post get called.


el.init();
result = method.invoke(el, args);
el.commit();
Whenever, user register their listener (EventListener) with event, our implementation will return same interface object(IListener) to them. User has to call ilistener.processEvent(), for them it looks like calling direct API, which intern calls pre and post operations.





import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class DynamicProxyTest implements java.lang.reflect.InvocationHandler {
interface IListener {
 void init();
 String processEvent(String eventNames);
 void commit();
}

static class EventListener implements IListener {

public void commit() {System.out.println("Commit");}

public void init() {System.out.println("initEvent");}

public String processEvent(String eventName) {
 System.out.println("processEvent" + eventName);
 return "success";
}
}

IListener el;

int countAPICall;

public DynamicProxyTest(IListener emp) {
 this.el = emp;
}

public Object invoke(Object proxy, Method method, Object[] args)
 throws Throwable {
// TODO Auto-generated method stub
Object result;
try {
 System.out.println("Enter:" + method.getName());
 countAPICall++;
 el.init();
 result = method.invoke(el, args);
 el.commit();
} catch (Exception e) {
 System.err.println(e.getMessage());
 result = null;
} finally {
 System.out.println("Exit:" + method.getName());
}
return result;
}

public static IListener newInstance(DynamicProxyTest dp) {
 return (IListener) java.lang.reflect.Proxy.newProxyInstance(dp.el
   .getClass().getClassLoader(),
   dp.el.getClass().getInterfaces(), dp);
}

public static void main(String[] args) {
EventListener el = new EventListener();

DynamicProxyTest dp = new DynamicProxyTest(el);
IListener ilistener = newInstance(dp);

System.out.println(ilistener.processEvent("ActionEvent"));
System.out.println("Count API calls=" + dp.countAPICall);
}
}

Wednesday, January 6, 2010

DOJO and JSON Toolkit

DOJO

Dojo Toolkit is an open-source JavaScript toolkit, which helps to build nice/rice web applications. Dojo Core comes with Ajax, events, packaging, CSS-based querying, animations, JSON, language utilities, and a lot more in just 26k size(gzip). We can do all magic related to Javascript and DHTML, simply invoking repective API in Dojo script as similaror equal to widget.

Dojo is nice toolkit which completelty makes us not to think of writing cross-platform script, all these environmental botherations are taken care by Dojo. We can download, this javascript and place it in our webapplication to use it, or else we can use any of the Content Delivery Network to refer from our web application.

JSON

JavaScript Object Notation is lightweight data interchange format. Usually, we get use SOAP message to send/receive platform agnostic messages, Whereas we have to use any of the XML parsing technique DOM, SAX, JAXB and StAX. And moreover, the message size will be increased to hold tag names meaningful. If we have client-server application where our software runs in client environment which knows what data is getting transmitted between server and client then JSON is the best option.

JSON provides facility to convert normal string to object and Object to normal string in most of the softwares - JAVA, ASP, PHP and etc.,

JSON can represent four primitive types (strings, numbers, booleans, and null) and two structured types (objects and arrays).Read more RFC 4627


Samples and Documentations:
API reference | Dojo QuickStart |Dojo download |JSON

Recent Posts

Unix Commands | List all My Posts

Texts

This blog intended to share the knowledge and contribute to JAVA Community such a way that by providing samples and pointing right documents/webpages. We try to give our knowledege level best and no guarantee can be claimed on truth. Copyright and Terms of Policy refer blogspot.com

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More