Wednesday, September 30, 2009

Sending email using Spring with JavaMail

Spring and JavaMail for sending emails:

Being a good java and spring developer, we might face a scenario sometime where we would be asked to construct and send an email from our application when something happens. This something may be like when our timesheet is pending or say when we have deposited or withdrawn some amount from our bank account. When we need to do that, there is nothing much simpler than using spring with javamail api for sending emails. Let us take the same example of the banking operation in our example and see how we configure spring with javamail to send emails.
As we all know, spring uses the concept of DI which is nothing but making our classes and interfaces as beans in the context files and wiring the properties directly or through references. Well, spring uses the same concept for emails. The 2 most important interfaces that we need to configure in spring is:
1. MailSender
2. MailMessage
MailSender: Spring comes with an email abstraction API that makes simple work of sending emails. This is MailSender interface. i.e. The purpose of MailSender interface is to send emails after configuring the mail properties from the MailMessage such as the from and to address, subject of the email, body of the email etc. Spring comes with 2 implementation of MailSender interface. They are CosMailSenderImpl and JavaMailSenderImpl. We will not talk about CosMailSenderImpl.
JavaMailSenderImpl is most versatile and widely used. It is a MailSender based on the JavaMail API. It allows us to send messages of MIME type and even to send non SMTP mail (such as Lotus Notes).
Here is how we configure the JavaMailSenderImpl as a bean in our context file, assuming that we would be sending the email to gmail ids, needing authentication

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="465" />
<property name="protocol" value="smtps" />
<property name="username" value="banking@gmail.com" />
<property name="password" value="banking" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtps.auth">true</prop>
<prop key="mail.smtps.starttls.enable">true</prop>
<prop key="mail.smtps.debug">true</prop>
</props>
</property>
</bean>

The properties explained in the mailSender are self explainatory. For ex: host specifies the hostname of the mail server that we will use for sending emails. port specifies that the mail server is listening to this port no. (This is by default 25. But smtp gmail listens on port no. 465). Since our mails server need authentication, we have specified the username and password property. We have also specified that authentication is required by specifying the mail.smtps.auth javaMailProperty to true. When we specify mail.smtps.starttls.enable as true, it means that the email is delivered in an encrypted way to the user, hence preventing from any unauthorized access.

MailMessage: MailMessage is nothing but the actual message that will be constructed while sending the email. We have lot of implementations of MailMessage but we will just look at its simplest implementation that sends emails as normal text and without any attachments etc. The simplest implementation of the MailMessage is SimpleMailMessage and as said earlier, we configure details like: from and to address, subject and body of the email using the mail message.
It is necessary to configure the MailMessage in the context file, but we have the option of setting its properties in the class level itself. However, it is a generic thing and we can thus create a template of a MailMessage in the context file by specifying the place holders in the template and replace those place holders in the actual class file. Let us see how we can do this:



<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from">
<value>
<![CDATA[JDBCBanking <banking@gmail.com>]]>
</value>
</property>
<property name="subject">
<value><![CDATA[Amount deposited in your account></value>
</property>
<property name="text">
<value>
<![CDATA[Hello %NAME%!
This is to inform you that %AMOUNT% Rupees has been deposited to your account on %DAT%
Your balance is now Rupees %BAL%

Thanks
Admin-JDBCBanking
]]>
</value>
</property>
</bean>

Now, we need to wire the 2 beans that we created above (i.e. mailSender and mailMessage) into our service bean like:



<bean id="memberService" class="com.prokarma.service.MemberServiceImpl">
<property name=”mailSender” ref=”mailSender” />
<property name=”mailMessage” ref=”mailMessage” />
</bean>

Finally, lets see how we consider these properties in our class and replace the place holders for them with specific values and send email.

In MemberServiceImpl class, provide setter methods for MailSender and MailMessage as:


private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}

private SimpleMailMessage mailMessage;
public void setMailMessage(SimpleMailMessage mailMessage) {
this.mailMessage = mailMessage;
}

Here is how you can construct the mail message by obtaining from the context file and replacing the place holders and finally send it:



SimpleMailMessage message = new SimpleMailMessage(mailMessage);
message.setTo(member.getEmail().trim());

String text = message.getText(); //Obtains the text form the template
//replaces the %NAME% placeholder from template with actual member's name
text = StringUtils.replace(text,"%NAME%",member.getName());
text = StringUtils.replace(text,"%AMOUNT%",member.getDepositAmount().toString());
text = StringUtils.replace(text,"%DAT%",member.getDepositDate());
text = StringUtils.replace(text,"%BAL%",member.getBalance());

message.setText(text); // Finally, sets the message text with specific member details

mailSender.send(message);


We have first obtained the template text from the context file, then we edit it for a specific member by replacing the place holders with the specific member details and using StringUtils to replace them. Finally, we set the text of the message again and last step is to send the mail by calling mailSender.send(message);

Saturday, September 5, 2009

Singleton Objects

Singleton objects:

The normal way in which we create an object in java is using the ‘new’ keyword along with the proper constructor. In that way, each time an object is created, we get a new one. However, we may come under scenarios sometimes where we need the same object whenever we access it. That is the time we actually go for creating a singleton object. One very common example is when we have license for only one connection for our database or our JDBC driver has trouble with multi threading. In that case, Singleton ensures that only one connection is made or that only one thread can access to the connection object at any time.

In definitive terms, we can say that a Singleton is an object that can be created but cannot be instantiated by the developers. It does mean that a singleton object has control over how it is created. The restriction on a singleton is that there can be only one instance of a singleton created by the Java Virtual Machine (JVM) and by preventing direct instantiating; we ensure that developers cannot create a second copy.

Let’s take a look at the following example for better understanding of the singleton objects:

public class SingletonExample {

private static SingletonExample ref;
private String name;

private SingletonExample() {

}


public static synchronized SingletonExample getSingletonExample() {
if(ref == null)
ref = new SingletonExample();
return ref;
}


public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}


public static void main(String[] args) {
SingletonExample singletonExample =
SingletonExample.getSingletonExample();
singletonExample.name = "Varun";
SingletonExample singletonExample2 =
SingletonExample.getSingletonExample();
System.out.println(singletonExample2.name);
}
}


If we look at the above example, we find that following are the different rules that need to be applied to make an object singleton.

Rule #1: We should create a default ‘private constructor’. Private constructors ensure that there is no way that an object can be created (instantiated) form outside of the same class.
private SingletonExample() {

}

Rule #2: Create a private static member variable of the class and a public accessor method that returns the singleton objects and does not create a new one every time it is called:
private static SingletonExample ref;
public static SingletonExample getSingletonExample() {
if(ref == null)
ref = new SingletonExample();
return ref;
}

If you look at the method, you will see that when it is called, we first check if the reference is null (which will be the case, when it is called first time) and if it is null, we create the object i.e. instantiate it using the constructor. Note that we can create the object by calling the private constructor here since we have this method in the same class itself and hence have access to private methods/variables/constructors too. If it is however, not null, it means it is already created and hence we return the same instance.
Also, since the member variable ‘ref’ is static, a same copy of it is returned every time allowing the method to return singleton instance.

Rule #3: Mark the accessor method that returns the singleton object as ‘synchronized’: Rule 1 and 2 ensures that the object returned is singleton. Well, not exactly. Imagine what if you have two separate threads say, Thread A and Thread B running and both the threads gets access to the accessor method we created above at the same time. In that case, we still end up in creating two different objects (one by Thread A and other by Thread B). To prevent this, we mark the accessor method as ‘synchronized’ so that only one thread is allowed to access it at any given point of time and hence multithreading also does not ends up in creating 2 different references of a singleton object.
public static synchronized SingletonExample getSingletonExample() {
if(ref == null)
ref = new SingletonExample();
return ref;
}

Rule #4: If we think, there is one more problem that can make our object deviate from its singleton rule. Well, consider what if I clone the already created the singleton object as:
SingletonExample obj = SingletonExample.getSingletonExample();
SingletonExample clone = (SingletonExample) obj.clone();

In the above way, we cloned the already created singleton object and hence ended up in having 2 different copies of the object to play with (1 is the singleton and other one is the cloned one). This violates our singleton principle. So, to prevent this, we need to add the clone() method and make sure that we cannot clone any object of this class by throwing the CloneNotSupportedException.

public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}

Now run the above example. You will find that the name variable is assigned the value of ‘Varun’ even for the second object that is created. This is because we have created a singleton object i.e. a single object is returned every time and hence all the instance variables values are shared.

Friday, September 4, 2009

Serialization in Java

We all know the Java platform allows us to create reusable objects in memory. However, all of those objects exist only as long as the Java virtual machine1 remains running. It would be nice if the objects we create could exist beyond the lifetime of the virtual machine, wouldn't it? Well, with object serialization, you can flatten your objects and reuse them in powerful ways.

Serialization: Object serialization is the process of saving an object's state to a sequence of
bytes, as well as the process of rebuilding those bytes into a live object at some future time.

Following are the set of rules to be implemented when we make an object as Serializable:
Rule #1: The object to be persisted must implement the Serializable interface or inherit that implementation from its object hierarchy

Rule #2: The object to be persisted must mark all nonserializable fields (fields that don't get saved) as transient

Rule #3: The class that is being serialized should declare a serialVersionUID; as private static final long serialVersionUID. This is used to identify the differences between a class's object between a write and read and hence take appropriate actions. If you dont create it, it will be provided by compiler but it has its limitations.

Rule #4: By default, the serialized object would be written to the default stream and that would be taken care by compiler and JVM. However, if you wish to save to some other place like a file or a database, you need to create an OutputStream for it and call the ObjectOutputStream's writeObject method (this is the method that marshalls the actual object fields into sequence of bytes), passing the output stream created. Similarly, at the time of unmarshalling the bytes back to the actual object, we should call the readObject method and cast the received object to its actual type.

Rule #5: If we want to perform some logic (like encrypting a password before saving it and decrypting it upon restoring it), we can override the writeObject and readObject methods with their exact signatures and perform the logic inside those methods and finally call the defaultWriteObject and defaultReadObject from those 2 methods.

Let us consider the above rules with an example:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Employee implements Serializable {

private static final long serialVersionUID = 1L;

private String name;
private int empNo;
private String designation;
private transient String department;

public Employee() {

}

public Employee(String name,int empNo,String designation,String department) {
this.name = name;
this.empNo = empNo;
this.designation = designation;
this.department = department;
}
/*private void writeObject(ObjectOutputStream oos) throws IOException {
if(designation.equalsIgnoreCase("SE"))
this.designation = "Software Engineer";

else if(designation.equalsIgnoreCase("SSE"))
this.designation = "Senior Software Engineer";

oos.defaultWriteObject();
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
}*/


public String toString() {
return "Employee name is: "+this.name+" and his designation is: "+this.designation+" his id is: "+this.empNo+" " +
"and his department is: "+this.department;
}
}
public class SerializedEmployee {

public static void main(String[] args) {
try {
FileOutputStream fos = new FileOutputStream("emp.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Employee employee = new Employee("Varun",123,"SE","Java");
oos.writeObject(employee);
System.out.println("Object saved to the file");
FileInputStream fis = new FileInputStream("emp.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
Employee emp = (Employee) ois.readObject();
System.out.println("Object read is: ");
System.out.println(emp);
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException");
} catch (IOException e) {
System.out.println("IOException");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException");
}
}
}


From the above example, we see each rule is marked in the same color in the code as the one it is explained under. i.e.
Rule# 1: Employee class is a persistent class as it is implementing Serializable
Rule #2: the 'department' field is marked as transient. So, this field wont be persistent. This can be seen when we called the writeObject and then subsequent call to readObject prints null value for the department field. Try to run the above example and you will see that 'though, we have passed 'Java' as the employee's department field, department' will be shown as 'null' when we print that employee object.
Rule #3: We have declared a 'serialVersionUID' for the class. This helps us in Versioning control which is explained below:
Versioning:
Imagine you create a class, instantiate it, and write it out to an object stream. That flattened object sits in the file system for some time. Meanwhile, you update the class file, perhaps adding a new field. What happens when you try to read in the flattened object?
Well, the bad news is that an exception will be thrown -- specifically, the java.io.InvalidClassException -- because all persistent-capable classes are automatically given a unique identifier. If the identifier of the class does not equal the identifier of the flattened object, the exception will be thrown. However, if you really think about it, why should it be thrown just because I added a field? Couldn't the field just be set to its default value and then written out next time?

Yes, but it takes a little code manipulation. The identifier that is part of all classes is maintained in a field called serialVersionUID. If you wish to control versioning, you simply have to provide the serialVersionUID field manually and ensure it is always the same, no matter what changes you make to the classfile.

For trying to know it better, just run the above example once. Then, comment the part that saves or writes the employee object, change the serialVersionUID to 2L or anything other than 1L (or) perform any change from the bleow list that can adversely affect the saved object.

The Sun documentation lists the various class format changes that can adversely affect the restoration of an object (if the serialVersionUID is changed or not provided). A few of these include:

1 Deleting a field, or changing it from non-static or non-transient to static or transient, respectively.
2 Changing the position of classes in a hierarchy.
3 Changing the data type of a primitive field.



You will notice that you get an exception that states:
"IOException--->java.io.InvalidClassException: Employee; local class incompatible: stream classdesc serialVersionUID = 1L, local class serialVersionUID = 2L".

On the other hand, not every change will have a negative effect. Here are some changes to class versions that do not have a detrimental effect on object behavior:

1 Adding fields, which will result in default values (based on data type) being assigned to the new fields upon restoration.
2 Adding classes will still allow an object of the added class to be created, since the class structure information is included in the stream. However, its fields will be set to the default values.
3 Changing the access modifier (public, private, etc.) for a field, since it is still possible to assign a value to the field.
4 Changing a field from static or transient to to non-static or non-transient, respectively.



Rule #4: We have created the employee object. We want to store the object into a File. So, we created the File using FileOutputStream and then created an ObjectOutputStream with the reference of fileoutput stream. Finally called the writeObject method of the stream by passing the employee object. Here, it saves all the fields of the employee object except those which are marked transient (as explained in rule#2) and those will be saved or marshalled as sequence of bytes.
Similarly, We retreive the marshalled sequence of bytes of the employee object by calling the readObject method and casting it back to employee object.

Rule #5: Say, we have a scenario where we want to process some values just before it is been saved. In this case, we can override the writeObject method. So, from our example, remove the comments for the writeObject and readObject method of the exmployee class. In the writeObject, we have performed a logic which cheks for the designation code and updates the proper designation value. After this is done, we call the defaultWriteObject() that is the method which will be called by writeObject if we dont override it. Similarly, we can even perform some logic while unmarshalling (reading) the object in the readObject method. We did nothing here but just called the defaultReadObject method.

NOTE: If we have a class in a inheritance hierarchy such that the superclass implements serializable, but we dont want the subclass to be serialized, then the only way we can acheive it is by overriding the writeObject and readObject methods in subclass with their exact signatures and throwing "NotSerializableException" from those two methods.