Monday, March 28, 2011

Marker interfaces in java

Marker interfaces in java

The marker interface is an interface that provides run-time type information about objects.

Dear reader,
Recently an interviewer asked me to give the use of marker interfaces and how to write my own.
some uses you know: Serializable, Cloneable so not repeating here.

Other real time example: Suppose in a company project, there are so many Java API, we want to process/extend
some functionalities to only those API which uses our own marker interface like My_Company_Name_Interface.

If you know then no need to read further, else I will suggest you to read once this:


//MarkerInterface.java (our marker interface)
package markerInterface;

public interface MarkerInterface {
//This interface is like other marker interfaces
//Cloneable, Serializable which don't have any method declaration
}



//MarkerInterfaceImpl.java (our API who implements this interface)
package markerInterface;

public class MarkerInterfaceImpl implements MarkerInterface{
public MarkerInterfaceImpl(){}
}



//MarkerInterfaceNotImpl.java (our other API who doesn't implement this interface)
package markerInterface;

public class MarkerInterfaceNotImpl {
public MarkerInterfaceNotImpl(){}
}



//TestMarker.java (Main program to test)
package markerInterface;

public class TestMarker {
public static void main(String[] args) {
MarkerInterfaceImpl markerImpl=new MarkerInterfaceImpl();
MarkerInterfaceNotImpl markerNotImpl=new MarkerInterfaceNotImpl();

System.out.println(markerImpl instanceof MarkerInterface);
System.out.println(markerNotImpl instanceof MarkerInterface);

if(markerImpl instanceof MarkerInterface){ //This is true
//do something for your own API
}
else {
//do something for other API
}
}
}

//Output:
true
false

//Best use of "instanceof" operator in Java.

Inheritance in Java

Inheritance in Java

Inheritance means a child class can use the property of super/base class, 
results Re-usability of existing code:

Example 1 with output is given below:
//Base.java

package inheritance;

public class Base {
int baseVariable=10;
public void m1(){ System.out.println("Base class, m1 method..");}
public void m2(){System.out.println("Base class, m2 method..");}
public void m3(){System.out.println("Base class, m3 method..");}
}



//Child.java
package inheritance;

public class Child extends Base {
int childVariable=100;
public void m1(){ System.out.println("Child class, m1 method..");}
public void m2(){System.out.println("Child class, m2 method..");}
public void m4(){System.out.println("Child class, m4 method..");}

public static void main(String[] args) {
Base b1=new Base();
Child c1=new Child();
b1.m1();
b1.m2();
b1.m3();
System.out.println(b1.baseVariable);

c1.m1();
c1.m2();
c1.m3();
c1.m4();
System.out.println(c1.baseVariable);
System.out.println(c1.childVariable);

Base b2=new Child();
b2.m1();
b2.m2();
b2.m3();
//b2.m4();  //Illegal, the method m4() is undefined for type Base.
System.out.println(b2.baseVariable);
//System.out.println(b2.childVariable); //b2.childVariable can't be resolved or not a field.

}

}

//Run Child.java, output is mentioned here:
Base class, m1 method..
Base class, m2 method..
Base class, m3 method..
10
Child class, m1 method..
Child class, m2 method..
Base class, m3 method..
Child class, m4 method..
10
100
Child class, m1 method..
Child class, m2 method..
Base class, m3 method..
10



//Other important points regarding inheritance
1) static methods can't be overridden by non static methods, means:
//Base class
public static void m1(){..}

//Child class
public void m1(){..}  //Is wrong, program won't compile
-----------
But, see the below:

//Base class
public static void m1(){..}

//Child class
public static void m1(){..}  //Is right, but in that scenario static methods
//will be treated as class level and local for that class
//so following line generates changed output:
Base b2=new Child();
b2.m1();  //Base class, m1 method..

//Please note if you don't use static in both m1(), it prints 
//Child class, m1 method..




2) If your base class method throws any type of Exceptions (Compile time or run-time),
sub-class doesn't need to override method with same or Higher Exceptions. Means:

//Base class
public void m1() throws Exception { .. }

//Child class
public void m1(){ .. }  //Its right no Exception or problem here. Compiles successfully.

//However you have to handle this while using these two caller objects:

Base b1=new Base();
b1.m1();  //Must handle the Exception, else comment this line

Base b2=new Child();
b2.m1();  //Must handle the Exception, else comment this line




3) Now take case of reverse way:
Sub-class writes an overridden method with throws clause, but in super class
throws is not specified. Compiler will not give exception if throws clause uses a RuntimeException,
but it will give exception, if throws uses a Compile time (Checked exception). Means:

//Base class, no throws clause
public void m1(){ .. }

//Child class
public void m1()throws NullPointerException{ .. }  //Works fine,  no compile error.
or
public void m1()throws RuntimeException{ .. }     //Works fine, no compile error.


But following definition of Child class method:
public void m1()throws IOException{ .. } //Compiler error
or
public void m1()throws Exception{ .. }   //Compiler error




4) If Sub-class method uses throw (not throws) at the end of method definition, 
that throw exception must be handled by the same method. Means if throw uses RuntimeException,
no "throws RuntimeException" is required at the method declaration section, but
if throw clause uses Checked-Exception like IOException then "throws IOException" or
"throws Exception" is required at the method declaration section.
And hence the point-2 and point-3 of this blog is again applied (just now you have read above point).

Means if your base class method declaration uses "throws Exception" or "throws RuntimeException",
your Sub-class method don't need to override the same thing, but if sub-class uses throws clause,
then Base class must define that (if "throws" uses Checked-Exception else no declaration is required at Base class method).
class level.



5) What if you declare static in Sub-class overriding method but not in Base class method.
//Base class
public void m1(){..}

//child class
public static void m1() {..} //Will not compile, Reason: The static method can't hide 
//instance method from Base class

---------------------------END----------------------------

Tuesday, March 22, 2011

REST Webservices in Java

Preparing and Executing a simple REST Webservice using Tomcat and MyEclipse:

1) Create a new WebService Project and name it "RestWebService2".
2) Create a package "model" and create a java file "HelloWorldService.java". This is basically your webservice. 
Contents are shown below.
3) Add some contents into "WEB-INF/web.xml", contents are shown below.
4) Add a new "sun-jaxws.xml" file inside "WEB-INF/" directory.
5) Run your application in Tomcat. In MyEclipse it is in-built, so just right click on project and Choose
"Run as"--> Server application (then choose Tomcat). It will show the browser with Index.jsp (default JSP
page contents in browser).
6) How to hit URL and what you will get as output is also mentioned at the end.
7) This is a basic example, once you run successfully, you can read further in other sites.
8) This is a tested example, works fine for me.

//HelloWorldService.java
package model;
import javax.annotation.Resource;

import java.io.ByteArrayInputStream;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.http.HTTPException;

@WebServiceProvider
@BindingType(value=HTTPBinding.HTTP_BINDING)
public class HelloWorldService implements Provider<Source> {

@Resource(type=Object.class)
protected WebServiceContext context;

public Source invoke(Source source) {
try {
MessageContext mc = context.getMessageContext();

String queryString = (String)mc.get(MessageContext.QUERY_STRING);
String pathInfo = (String)mc.get(MessageContext.PATH_INFO);

if (queryString != null && queryString.contains("name=")) {
return sayHello(queryString);
} else if (pathInfo != null && pathInfo.contains("/name")) {
return sayHello(pathInfo);
} else {
return sayHello("Unknown");
}
} catch(Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}

private Source sayHello(String name) {
Source source = new StreamSource(
new ByteArrayInputStream((new String("<result>Hello Client, Response from Rest Webservice : "+name+"</result>")).getBytes()));
return source;
}
}

//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>helloWorld</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>helloWorld</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


//sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="helloWorld" implementation="model.HelloWorldService"
url-pattern="/hello/*" />
</endpoints>

//index.jsp
It can have anything here.... no use....



URL Hit:
http://10.200.101.156:8080/RestWebService2/hello?name=deepakKumarmodi
Output:
<result>Hello Client, Response from Rest Webservice : name=deepakKumarmodi</result> 


URL Hit:
http://10.200.101.156:8080/RestWebService2/hello/name/deepakKumarmodi
Output:
<result>Hello Client, Response from Rest Webservice : /name/deepakKumarmodi</result> 


URL Hit (Any other non matching pattern):
http://10.200.101.156:8080/RestWebService2/hello
Output:
<result>Hello Client, Response from Rest Webservice : Unknown</result> 


-----------------------END-------------------------------

Saturday, March 19, 2011

How to make a Java class Immutable

Dear reader,
Today's discussion is about: How to make a Java class Immutable. Immutable means non-changeable.

Immutable means once an object is CREATED, you can't make any changes in that. 
Change means: Changing values of instance variables of that Class (check code for more details).

Ex: Take class java.lang.Thread. It is a normal (Mutable) class and having instance variables like name, priority etc. 
See the below example:
======================
public class ThreadClass {
    public static void main(String[] args) {
        Thread t1=new Thread();
        System.out.println("Thread before change:"+t1);
        System.out.println("Hashcode before change: "+t1.hashCode());

        t1.setName("DeepakThread");   //Changing name
        t1.setPriority(6);            //Changing priority
        
        System.out.println("Thread after change:"+t1);
        System.out.println("Hashcode after change: "+t1.hashCode());
    }
}
//Output:
Thread before change:Thread[Thread-0,5,main]
Hashcode before change: 1854077
Thread after change:Thread[DeepakThread,6,main]
Hashcode after change: 1854077

======================
If you see the above example output, you notice that HashCode is SAME and setter method worked fine. And so values of 
properties "name, priority" of thread object are altered. 

Now this is not possible in IMMUTABLE class.

So if you try to do a change an Immutable Class's object, NEW object will be created every-time you attempt to do so, in short NEW HASHCODE value.

======================Check below Example====================
String is an Immutable class, so once assigned a value, the contents can't be modified in the same object, 

//Immutable.java
public class Immutable {
    public static void main(String[] args) {        
        String x=new String("Deepak");      //new object created
        //x.set###();                       //No setter method is given, so nothing can be changed.
        System.out.println("X: hashCode: "+x.hashCode());

        x.replace("D", "C");      //No impact on "x" here but in above Thread example it was impacted.
        System.out.println("X: hashCode after replacement: "+x.hashCode()+", Value: "+x);
        
        x=x.replace("D", "C");  //Change impacted BUT NEW Object is created internally.
        System.out.println("X: hashCode after actual replacement: "+x.hashCode()+", Value: "+x);
    }
}

//Output:
X: hashCode: 2043177526
X: hashCode after replacement: 2043177526, Value: Deepak
X: hashCode after actual replacement: 2014548375, Value: Ceepak

======================

You must be knowing that String class is a final class. Modifier "final" is used to indicate that the 
class can not be extended. This means an IMMUTABLE class must be final.

Also all instance variables must be declared final so that they can be initialized at ONLY once.
Only once initialization should happen only inside the Constructor as there should be NO Setter() method in an IMMUTABLE class. 

But If you are forced to create a setter method then inside setter(), return a new object with new modified values 
as "replace()" method does in String class. But this is a wrong practice.
Remember you must write getter() methods, else how values are accessible outside ????

Also see: String and StringBuffer both are final classes but only first one is Immutable, later is Mutable. Hence just making a class
final will not make your class as an IMMUTABLE.

So the final points are:
A class will be immutable only if all of the following are true:

1) All of its fields are final.
2) The class is declared final.
3) The constructor should set the variable values only once. Once set, shouldn't be modified.
4) Any fields that contain references to Mutable classes like "Date" and Mutable objects such as Arrays, Collections:
    -Should be private
    -Should never return or otherwise exposed to callers (means no setter() methods)
    -Do not change the state of the referenced objects after construction.


Since Immutable Classes are created once once, it can be shared freely among many Objects ex: License Keys (are encrypted strings)
can be shared in entire application. Best use in Fixed Keys Maps, Sets etc.
-----------------------------END---------------------------------------

Wednesday, March 16, 2011

Implementing Timer in Java


Implementing Timer and TimerTask in Java
//Real world example of sending SMSes in Fixed interval, interval is defined in a properties file
//For sending an SMS, you need to have an account with third party SMS provider like Unicel, so they 
//will provide an UserId and Password that you have to use while sending SMS.

//Java code
//TestUnicelConnectivity.java

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.Properties;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;

/**
* @author dmodi
*/
public class TestUnicelConnectivity {
static final Timer t = new Timer();
static int no_sms_sent=1;

//For Unicel testing
private static int intervalForSmsToBeSentInSeconds=30;
private static String unicelURL="";
private static String testingMobileNo="";
private static String testSMSForUnicelConnectivity="";
private static String usernameParam = "uname=******";
private static String passwordParam = "pass=*******";

private static TestUnicelConnectivity automaticConnector=null;
private static Properties props = null;

public TestUnicelConnectivity(String propertiesFilePath) throws Exception{
props=new Properties();
try {
props.load(new FileInputStream(propertiesFilePath));
if(props==null){
throw new IOException("Connectors.properties file not found, please provide path of Connectors.properties correctly");
}
System.out.println("Properties file contents loaded..");
}
catch(IOException e) {
e.printStackTrace();
throw e;
}
}

public static void main(String[] args) {
try {
if(args.length>0) {
automaticConnector=new TestUnicelConnectivity(args[0]);   //Properties file contents is pasted at the end of this blog.

unicelURL = props.getProperty("UnicelURL").trim();
testingMobileNo = props.getProperty("MobileNumber").trim();
testSMSForUnicelConnectivity = props.getProperty("TestSms").trim();
intervalForSmsToBeSentInSeconds=Integer.parseInt(props.getProperty("IntervalForSmsToBeSentInSeconds").trim());

boolean b=automaticConnector.validateSMSParameters(unicelURL,testingMobileNo,testSMSForUnicelConnectivity);
if(b)
automaticConnector.sendRepeatedSMS(intervalForSmsToBeSentInSeconds);
else {
System.out.println("Validation failed for SMS parameters");
System.exit(0);
}
}
else {
System.out.println("Please provide Property file name in command line argument");
System.exit(0);
}
}
catch(Exception e){
System.out.println("Exception occured: "+e.getMessage());
e.printStackTrace();
}
}
private static String formURL() {
String toParam = "****=";
String udhParam = "****=";
String fromParam = "send=*****-T";
String textParam = "msg=";
//String priorityParam = " prty=1";
//String validityPeriodParam = "vp=30";
//String dataCodingSchemeParam = "dcs=";
StringBuffer sb = new StringBuffer();
sb.append(unicelURL).append("?").append(usernameParam + "&").append(passwordParam + "&");
sb.append(toParam).append(testingMobileNo + "&").append(udhParam + "&");
sb.append(fromParam + "&").append(textParam).append(testSMSForUnicelConnectivity);
return sb.toString().replace(" ", "+");
}

public boolean validateSMSParameters(String unicelURL,String mobileNumber,String message){
if (mobileNumber == null || mobileNumber.length() != 12) {
System.out.println("Invalid mobile Number :: Mobile Number must starts with 91. Please check your mobile Number again ...");
return false;
}
Scanner scan = new Scanner(mobileNumber);
if(!scan.hasNextLong())    {
System.out.println("Invalid mobile Number :: Mobile Number must starts with 91. Please check your mobile Number again ...");
return false;
}
if (message == null || "".equalsIgnoreCase(message) || message.length() > 140) {
System.out.println("Invalid message :: Message Exceeds or 140 character or is empty. Please check your message again ...");
return false;
}
if (message == null && message.length() > 140) {
System.out.println("Invalid message :: Message Exceeds or 140 character or is null. Please check your message again ...");
return false;
}
return true;
}

public static void sendSMS() {
try {
System.out.println("URL: "+unicelURL+", SMS Message: "+testSMSForUnicelConnectivity);
String theURL = formURL();
URL url = new URL(theURL);

URLConnection connection = url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String str = null;
String decodedString = null;
//boolean sendFlag = false;
System.out.println("Sending SMS, Count: "+no_sms_sent);
no_sms_sent=no_sms_sent+1;
while ((str = in.readLine()) != null) {
decodedString = str;
System.out.println("Decoded Response String: "+decodedString);
}

in.close();
System.out.println("Message sent successfully to :"+testingMobileNo+"\n");
} catch (MalformedURLException e) {
System.out.println("URL Format Violation, Message sent Failed: "+e.getMessage());
} catch (IOException e) {
System.out.println("IO Exception, Message sent Failed: "+e.getMessage());
}
catch (Throwable e) {
System.out.println("Bigger Exception occured, Message sent Failed: "+e.getMessage());
e.printStackTrace();
}
}

public void sendRepeatedSMS(int interval) {
TimerTask tt = new TimerTask() {
public void run() {
System.out.println("Sending SMS Now :");
sendSMS();
}
};
t.scheduleAtFixedRate(tt, new Date(), interval*1000);
synchronized (TestUnicelConnectivity.class) {
try {
TestUnicelConnectivity.class.wait();
} catch (InterruptedException ie) {
System.out.println("Exception occured in Timer task: "+ie.getMessage());
}
}
}
}


//UnicelConfig.properties
UnicelURL=http://www.unicel.in/SendSMS/sendmsg.php
MobileNumber=919916473353
#Please specify the mobile number with 91 prefix, fortunately this is my number, please don't use this.

TestSms=Welcome to deepakmodi2006.blogspot.in, this is a test SMS for testing sending SMS.
IntervalForSmsToBeSentInSeconds=60
#Means in 60 seconds, it will send 1 sms. If you put 30, means 1 sms in 30 seconds.

//Thats it, now compile it in command prompt, pass the propeties file as command line argument and 
//SMS will be started sending every 60 seconds.

Implementing Timer and TimerTask in Java

Implementing Timer and TimerTask in Java

Dear Reader,
Here is a simple working code which you can utilize in your application for running a task in Timer/Scheduler interval:


import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class TestTimer {
static final Timer t = new Timer();
public static void main(String[] args) {
System.out.println("Testing Timer by Deepak.Modi");

TimerTask tt = new TimerTask() {
public void run() {
//This run block will get executed in every interval. So You can put your method here for repeatitive calls.
YourClass.YourMethod();  
System.out.println("--- Timer is called --");
}
};
t.scheduleAtFixedRate(tt, new Date(), 5000);  //The fixed interval when your run method executes is 5000 milliseconds. 
synchronized (TestTimer.class) {
try {
TestTimer.class.wait();
} 
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}