Sunday, 26 February 2017

Reference - Type of Reference in Java

In java memory automatically managed by garbage collector there is no need of explicit declaration of memory management. But with the introduction of java.lang.ref classes we have a little control over when the object will be garbage collected.

Type of Reference –

1.      Strong References
2.      Soft References
3.      Weak References
4.      Phantom References

Strong References
Any object in the memory which has active strong reference is not eligible for garbage collection. For example, in the below program, reference variable ‘a’ is a strong reference which is pointing to class A-type object. At this point of time, this object can’t be garbage collected as it has strong reference.

Code Snippet –
/**
 * @author Manoj
 */
public class Test {
  public static void main(String args[]) {
     Student std = new Student(); //strong reference
     std = null; // now object is available for GC
  }
}
class Student {
       //student class
}

Weak References
VM ignores the weak references. That means objects which has only week references are eligible for garbage collection. They are likely to be garbage collected when JVM runs garbage collector thread. JVM doesn’t show any regard for weak references.

Code snippet-
import java.lang.ref.WeakReference;

/**
 * @author Manoj
 */
public class Test {
  public static void main(String args[]) {
       Student std = new Student(); //strong reference
       //Creating Weak Reference to Student-type object to which 'std' is also pointing.
    WeakReference<Student> weakStudent = new WeakReference<Student>(std);
    std = null;    //Now, Student-type object to which 'std' is pointing earlier is available for garbage collection.
    std = weakStudent.get(); //we can retrieve back the object which has been weakly referenced.
   }

 }
class Student {
   //student class
}

Soft References
The objects which are softly referenced will not be garbage collected (even though they are available for garbage collection) until JVM badly needs memory. These objects will be cleared from the memory only if JVM runs out of memory. You can create a soft reference to an existing object by using  java.lang.ref.SoftReference class. Below is the code example on how to create a soft reference.

Code snippet –
import java.lang.ref.SoftReference;

/**
 * @author Manoj
 */
public class Test {
  public static void main(String args[]) {
     Student std = new Student(); //strong reference
     //Creating Soft Reference to Student-type object to which 'std' is also pointing
     SoftReference<Student> softStudent = new SoftReference<Student>(std);
     std = null;    //Now, Student-type object to which 'std' is pointing earlier is eligible for garbage collection. But, it will be garbage collected only when JVM needs memory.
    std = softStudent.get();    //You can retrieve back the object which has been softly referenced
    }
}

class Student {
       //student class
}

Phantom References
The objects which are being referenced by phantom references are eligible for garbage collection. But, before removing them from the memory, JVM puts them in a queue called ‘reference queue’. They are put in a reference queue after calling finalize () method on them. You can’t retrieve back the objects which are being phantom referenced. That means calling get () method on phantom reference always returns null.

Code snippet-
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * @author Manoj
 */
public class Test {
  public static void main(String args[]) {
       Student std = new Student(); // strong reference
       // Creating ReferenceQueue
       ReferenceQueue<Student> refQueue = new ReferenceQueue<Student>();
       // Creating Phantom Reference to Student-type object to which 'std' is also
       // pointing
       PhantomReference<Student> phantomStudent = new PhantomReference<Student>(std, refQueue);
       std = null; // Now, Student-type object to which 'std' is pointing earlier is
              // available for garbage collection. But, this object is
              // kept in 'refQueue' before removing it from the memory.
       std = phantomStudent.get(); // it always returns null
  }
}

class Student {
  // student class

}

What is JDBC ? Explain with example?

For simple JDBC Connectivity we need to follow below step-
1.      Register JDBC driver.
2.      Open a connection using DriverManager.getConnection()
3.      Create a statement connectionObj.createStatment()
4.      Execute query using statement stmtObject.executeQuery(query);
5.      Fetch the result in ResultSet object and iterate to get the values
Refer below java program

Simple JDBC Example:

Code Snippet-
import java.sql.*;

public class JdbcTest {
  public static void main(String args[]) {
       try {
              Class.forName("com.mysql.jdbc.Driver");
              Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/Test", "root", "admin");
              Statement stmt = con.createStatement();
              ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEE;");
              while (rs.next())
                     System.out.println(rs.getString(1) + "  " + rs.getString(2) + "  " + rs.getString(3)+ "  " + rs.getInt(4));
              con.close();
       } catch (Exception e) {
              System.out.println(e);
       }
  }
}

Types JDBC Driver-

There are 4 types of JDBC driver

1.      JDBC-ODBC bridge driver
2.      Native-API driver (partially java driver)
3.      Network Protocol driver (fully java driver)
4.      Thin driver (fully java driver)

JDBC-ODBC bridge driver
JDBC Bridge is used to access ODBC drivers installed on each client machine. This type of driver is recommended only for experimental use or when no other alternative is available.

Native-API driver (partially java driver)
This driver typically provided by the database vendor an used in the same manner as JDBC-ODBC bridge driver.

Network Protocol driver (fully java driver)
JDBC clients use standard network socket to communicate with the middleware application server. The socket information is then translated by the middleware application server into the call format required by the DBMS, and forwarded to the database server. It is extremely flexible.

Thin driver (fully java driver)
In a Type 4 driver, a pure Java-based driver communicates directly with the vendor's database through socket connection. This is the highest performance driver available for the database and is usually provided by the vendor itself.

This kind of driver is extremely flexible; you don't need to install special software on the client or server. Further, these drivers can be downloaded dynamically.

Types of Statement-

1.      Statement
2.      Prepared Statement
3.      Callable Statement

Statement
Use the for general-purpose access to your database. Useful when you are using static SQL statements at runtime. The Statement interface cannot accept parameters.

Prepared Statement
Use the when you plan to use the SQL statements many times. The PreparedStatement interface accepts input parameters at runtime.

Callable Statement

Use the when you want to access the database stored procedures. The CallableStatement interface can also accept runtime input parameters.

Saturday, 25 February 2017

Explain different encryption and decryption techniques

Hi guys, here I am going to explain different encryption and decryption algorithm.
In encryption we completely make the readable content into unreadable so that only desirable person can understand the exact data and for outer world that unreadable (encoded) data will be meaningless.

Data encryption is not a new thing it’s happening even in very past time. Enigma is best and most popular example of encryption and decryption. It was more popular during 2nd world war, Enigma was invented by the German engineer Arthur Scherbius at the end of World War I.
Refer below URL to get a flavor

Encryption is a process to encode the meaning full data into unreadable content so that only desire person can decode and read it. Encryption is a security method in which information is encoded in such a way that only authorized user can read it. It uses encryption algorithm to generate cipher text that can only be read if decrypted.



Type’s encryption techniques-

There are two types of encryptions schemes as listed below:

Symmetric methods
Symmetric encryption is also known as private-key cryptography, and is called so because the key used to encrypt and decrypt the message must remain secure, because anyone with access to it can decrypt the data. Using this method, a sender encrypts the data with one key, sends the data (the ciphertext) and then the receiver uses the key to decrypt the data.

Asymmetric methods
Asymmetric encryption, or public-key cryptography, is different than the previous method because it uses two keys for encryption or decryption (it has the potential to be more secure as such). With this method, a public key is freely available to everyone and is used to encrypt messages, and a different, private key is used by the recipient to decrypt messages.

Hashing
Hashing creates a unique, fixed-length signature for a message or data set. Each “hash” is unique to a specific message, so minor changes to that message would be easy to track. Once data is encrypted using hashing, it cannot be reversed or deciphered.



Java encryption examples-

Code snippet-

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AESTest {

       private static SecretKeySpec secretKey;
       private static byte[] key;

       public static void setKey(String myKey) {
              MessageDigest sha = null;
              try {
                     key = myKey.getBytes("UTF-8");
                     sha = MessageDigest.getInstance("SHA-1");
                     key = sha.digest(key);
                     key = Arrays.copyOf(key, 16);
                     secretKey = new SecretKeySpec(key, "AES");
              } catch (NoSuchAlgorithmException e) {
                     e.printStackTrace();
              } catch (UnsupportedEncodingException e) {
                     e.printStackTrace();
              }
       }

       public static String encrypt(String strToEncrypt, String secret) {
              try {
                     setKey(secret);
                     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                     cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                     return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
              } catch (Exception e) {
                     System.out.println("Error while encrypting: " + e.toString());
              }
              return null;
       }

       public static String decrypt(String strToDecrypt, String secret) {
              try {
                     setKey(secret);
                     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
                     cipher.init(Cipher.DECRYPT_MODE, secretKey);
                     return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
              } catch (Exception e) {
                     System.out.println("Error while decrypting: " + e.toString());
              }
              return null;
       }
}

public class EncryptionDecryptionAES {
       static Cipher cipher;

       public static void main(String[] args) throws Exception {
              KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
              keyGenerator.init(128);
              SecretKey secretKey = keyGenerator.generateKey();
              cipher = Cipher.getInstance("AES");

              String plainText = "AES Symmetric Encryption Decryption";
              System.out.println("Plain Text Before Encryption: " + plainText);

              String encryptedText = encrypt(plainText, secretKey);
              System.out.println("Encrypted Text After Encryption: " + encryptedText);

              String decryptedText = decrypt(encryptedText, secretKey);
              System.out.println("Decrypted Text After Decryption: " + decryptedText);
       }

       public static String encrypt(String plainText, SecretKey secretKey)
                     throws Exception {
              byte[] plainTextByte = plainText.getBytes();
              cipher.init(Cipher.ENCRYPT_MODE, secretKey);
              byte[] encryptedByte = cipher.doFinal(plainTextByte);
              Base64.Encoder encoder = Base64.getEncoder();
              String encryptedText = encoder.encodeToString(encryptedByte);
              return encryptedText;
       }

       public static String decrypt(String encryptedText, SecretKey secretKey)
                     throws Exception {
              Base64.Decoder decoder = Base64.getDecoder();
              byte[] encryptedTextByte = decoder.decode(encryptedText);
              cipher.init(Cipher.DECRYPT_MODE, secretKey);
              byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
              String decryptedText = new String(decryptedByte);
              return decryptedText;
       }

}