Exception Handling Java Interview Questions | Eklavya Online

Exception Handling Java Interview Questions

In general, unchecked exceptions represent defects in the program (bugs), which are normally Runtime exceptions.

Furthermore, checked exceptions represent invalid conditions in areas outside the immediate control of the program.

Explain Checked Exceptions and Unchecked Exceptions with examples

Unchecked exceptions :

represent defects in the program (bugs) – often invalid arguments passed to a non-private method. To quote from The Java Programming Language, by Gosling, Arnold, and Holmes : “Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program’s logic and cannot be reasonably recovered from at run time.”

are subclasses of RuntimeException, and are usually implemented using IllegalArgumentException, NullPointerException, or IllegalStateException

a method is not obliged to establish a policy for the unchecked exceptions thrown by its implementation (and they almost always do not do so)

Checked exceptions :

represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files)

are subclasses of Exception

a method is obliged to establish a policy for all checked exceptions thrown by its implementation (either pass the checked exception further up the stack, or handle it somehow)

It is somewhat confusing, but note as well that RuntimeException (unchecked) is itself a subclass of Exception (checked).

 

Example 1

Model Objects are the data-centric classes used to represent items in a particular domain. Model Object constructors need to handle both arbitrary user input, and input from underlying database ResultSets.

 

Model Object constructors should throw checked exceptions:

 

the program may have no direct control over user input. This is particularly true in web applications. It seems safest for a Model Object to treat user input as having arbitrary, unvalidated content.

it is not safe for an application to make any assumptions about the state of the database. The database is an independent entity, and its data may be changed by various means, outside of any particular application. For example, data load tools are commonly used to create an initial state for a new database. Such data can easily violate the constraints built into a calling application. Thus, the safest assumption is to treat database ResultSets as having arbitrary, unvalidated content.

Here is an example Model Object, taken from the WEB4J example application. Its constructor throws ModelCtorException (a checked exception) :

 

package hirondelle.fish.main.resto;

 

import hirondelle.web4j.model.ModelCtorException;

import hirondelle.web4j.model.ModelUtil;

import hirondelle.web4j.model.Id;

import hirondelle.web4j.security.SafeText;

import hirondelle.web4j.model.Decimal;

import static hirondelle.web4j.model.Decimal.ZERO;

import hirondelle.web4j.model.Check;

import hirondelle.web4j.model.Validator;

import static hirondelle.web4j.util.Consts.FAILS;

 

/** Model Object for a Restaurant. */

public final class Resto {

 

/**

Full constructor.

 

@param aId underlying database internal identifier (optional) 1..50 characters

@param aName of the restaurant (required), 2..50 characters

@param aLocation street address of the restaurant (optional), 2..50 characters

@param aPrice of the fish and chips meal (optional) $0.00..$100.00

@param aComment on the restaurant in general (optional) 2..50 characters

*/

public Resto(

Id aId, SafeText aName, SafeText aLocation, Decimal aPrice, SafeText aComment

) throws ModelCtorException {

fId = aId;

fName = aName;

fLocation = aLocation;

fPrice = aPrice;

fComment = aComment;

validateState();

}

 

public Id getId() { return fId; }

public SafeText getName() {  return fName; }

public SafeText getLocation() {  return fLocation;  }

public Decimal getPrice() { return fPrice; }

public SafeText getComment() {  return fComment; }

 

@Override public String toString(){

return ModelUtil.toStringFor(this);

}

 

@Override public  boolean equals(Object aThat){

Boolean result = ModelUtil.quickEquals(this, aThat);

if ( result ==  null ) {

Resto that = (Resto) aThat;

result = ModelUtil.equalsFor(

this.getSignificantFields(), that.getSignificantFields()

);

}

return result;

}

 

@Override public int hashCode(){

if ( fHashCode == 0 ){

fHashCode = ModelUtil.hashCodeFor(getSignificantFields());

}

return fHashCode;

}

 

// PRIVATE //

private final Id fId;

private final SafeText fName;

private final SafeText fLocation;

private final Decimal fPrice;

private final SafeText fComment;

private int fHashCode;

 

private static final Decimal HUNDRED = Decimal.from(“100”);

 

private void validateState() throws ModelCtorException {

ModelCtorException ex = new ModelCtorException();

if ( FAILS == Check.optional(fId, Check.range(1,50)) ) {

ex.add(“Id is optional, 1..50 chars.”);

}

if ( FAILS == Check.required(fName, Check.range(2,50)) ) {

ex.add(“Restaurant Name is required, 2..50 chars.”);

}

if ( FAILS == Check.optional(fLocation, Check.range(2,50)) ) {

ex.add(“Location is optional, 2..50 chars.”);

}

Validator[] priceChecks = {Check.range(ZERO, HUNDRED), Check.numDecimalsAlways(2)};

if ( FAILS == Check.optional(fPrice, priceChecks)) {

ex.add(“Price is optional, 0.00 to 100.00.”);

}

if ( FAILS == Check.optional(fComment, Check.range(2,50))) {

ex.add(“Comment is optional, 2..50 chars.”);

}

if ( ! ex.isEmpty() ) throw ex;

}

 

private Object[] getSignificantFields(){

return new Object[] {fName, fLocation, fPrice, fComment};

}

}

 

Example 2

Args is a convenient utility class. It performs common validations on method arguments. If a validation fails, then it throws an unchecked exception. It is suitable for checking the internal consistency of program, but not for checking arbitrary user input.

 

package hirondelle.web4j.util;

 

import java.util.regex.*;

 

/**

Utility methods for common argument validations.

 

<P>Replaces <tt>if</tt> statements at the start of a method with

more compact method calls.

 

<P>Example use case.

<P>Instead of :

<PRE>

public void doThis(String aText){

if (!Util.textHasContent(aText)){

throw new IllegalArgumentException();

}

//..main body elided

}

</PRE>

<P>One may instead write :

<PRE>

public void doThis(String aText){

Args.checkForContent(aText);

//..main body elided

}

</PRE>

*/

public final class Args {

 

/**

If <code>aText</code> does not satisfy {@link Util#textHasContent}, then

throw an <code>IllegalArgumentException</code>.

 

<P>Most text used in an application is meaningful only if it has visible content.

*/

public static void checkForContent(String aText){

if( ! Util.textHasContent(aText) ){

throw new IllegalArgumentException(“Text has no visible content”);

}

}

 

/**

If {@link Util#isInRange} returns <code>false</code>, then

throw an <code>IllegalArgumentException</code>.

 

@param aLow is less than or equal to <code>aHigh</code>.

*/

public static void checkForRange( int aNumber, int aLow, int aHigh ) {

if ( ! Util.isInRange(aNumber, aLow, aHigh) ) {

throw new IllegalArgumentException(aNumber + ” not in range ” + aLow + “..” + aHigh);

}

}

 

/**

If <tt>aNumber</tt> is less than <tt>1</tt>, then throw an

<tt>IllegalArgumentException</tt>.

*/

public static void checkForPositive(int aNumber) {

if (aNumber < 1) {

throw new IllegalArgumentException(aNumber + ” is less than 1″);

}

}

 

/**

If {@link Util#matches} returns <tt>false</tt>, then

throw an <code>IllegalArgumentException</code>.

*/

public static void checkForMatch(Pattern aPattern, String aText){

if ( ! Util.matches(aPattern, aText) ){

throw new IllegalArgumentException(

“Text ” + Util.quote(aText) + ” does not match ‘” +aPattern.pattern()+ “‘”

);

}

}

 

/**

If <code>aObject</code> is null, then throw a <code>NullPointerException</code>.

 

<P>Use cases :

<pre>

doSomething( Football aBall ){

//1. call some method on the argument :

//if aBall is null, then exception is automatically thrown, so

//there is no need for an explicit check for null.

aBall.inflate();

 

//2. assign to a corresponding field (common in constructors):

//if aBall is null, no exception is immediately thrown, so

//an explicit check for null may be useful here

Args.checkForNull( aBall );

fBall = aBall;

 

//3. pass on to some other method as parameter :

//it may or may not be appropriate to have an explicit check

//for null here, according the needs of the problem

Args.checkForNull( aBall ); //??

fReferee.verify( aBall );

}

</pre>

*/

public static void checkForNull(Object aObject) {

if ( aObject == null ) {

throw new NullPointerException();

}

}

 

// PRIVATE //

private Args(){

//empty – prevent construction

}

Yes, 2 things — firstly, the above sort is case sensitive, that is the uppercase takes priority over lowercase pushing ‘Java’ after ‘JSP’. Secondly, if the collection had any null values, it will throw a NullpointerException.

These two issues can be rectified by providing a custom sorting implementation that ignores case and handles null values by pushing them to the end. The Collections class’s sort method takes a Comparator implementation as a second argument. In the code below, the Comparator has been implemented as an anonymous inner class. The compare(…) method will be called a number of times by the Collections.sort(list, comparator).

import java.util.Arrays;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

 

public class Sort2 {

 

public static void main(String[] args) {

List<String> values = Arrays.asList(“JEE”, “Java”, null,  “Servlets”, null, “JMS”, “JNDI”, “JDBC”, “JSP”, null,”EJB”);

 

//The comparator is defined as an anonymous inner class, but it can be

//defined in its own class. Handles nulls and ignores case

Collections.sort(values, new Comparator<String>() {

 

@Override

public int compare(String o1, String o2) {

//push the null values to the end

if(o1 == null){

if(o2 == null) {

return 0;

}

return 1;

}

else if(o2 == null){

return -1;

}

return o1.compareToIgnoreCase(o2);

}

}); // anonymous inner class end

 

System.out.println(values);

}

}

A checked exception is any subclass of Exception (or Exception itself), excluding class RuntimeException and its subclasses.

Making an exception checked forces client programmers to deal with the possibility that the exception will be thrown. eg, IOException thrown by java.io.FileInputStream’s read() method

Unchecked exceptions are RuntimeException and any of its subclasses. Class Error and its subclasses also are unchecked.

With an unchecked exception, however, the compiler doesn’t force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. eg, StringIndexOutOfBoundsException thrown by String’s charAt() method.

Checked exceptions must be caught at compile time. Runtime exceptions do not need to be. Errors often cannot be, as they tend to be unrecoverable.

Yes, an exception can be rethrown.

The finally clause is used to provide the capability to execute code no matter whether or not an exception is thrown or caught.

final : final keyword can be used for class, method and variables. A final class cannot be subclassed and it prevents other programmers from subclassing a secure class to invoke insecure methods. A final method can’t be overridden. A final variable can’t change from its initialized value. finalize() : finalize() method is used just before an object is destroyed and can be called just prior to garbage collection. finally : finally, a key word used in exception handling, creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block. The finally block will execute whether or not an exception is thrown. For example, if a method opens a file upon exit, then you will not want the code that closes the file to be bypassed by the exception-handling mechanism. This finally keyword is designed to address this contingency.

This Error is thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. Note: Its an Error (extends java.lang.Error) not Exception. Two important types of OutOfMemoryError are often encountered

  • lang.OutOfMemoryError: Java heap space
    • The quick solution is to add these flags to JVM command line when Java runtime is started:
      • -Xms1024m -Xmx1024m
    • lang.OutOfMemoryError: PermGen space
      • The solution is to add these flags to JVM command line when Java runtime is started:
        • -XX:+CMSClassUnloadingEnabled
        • -XX:+CMSPermGenSweepingEnabled

Long Term Solution: Increasing the Start/Max Heap size or changing Garbage Collection options may not always be a long term solution for your Out Of Memory Error problem. Best approach is to understand the memory needs of your program and ensure it uses memory wisely and does not have leaks. You can use a Java memory profiler to determine what methods in your program are allocating large number of objects and then determine if there is a way to make sure they are no longer referenced, or to not allocate them in the first place.

Integer / and % can result in the throwing of an ArithmeticException.

Finally is the block of code that executes always. The code in finally block will execute even if an exception is occurred. Finally block is NOT called in following conditions

  • If the JVM exits while the try or catch code is being executed, then the finally block may not execute. This may happen due to System.exit() call.
  • if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
  • If a exception is thrown in finally block and not handled then remaining code in finally block may not be executed.

A throw statement may throw any expression that may be assigned to the Throwable type.

A Java object is considered immutable when its state cannot change after it is created. Use of immutable objects is widely accepted as a sound strategy for creating simple, reliable code. Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state. java.lang.String and java.lang.Integer classes are the Examples of immutable objects from the Java Development Kit. Immutable objects simplify your program due to following characteristics :

  • Immutable objects are simple to use test and construct.
  • Immutable objects are automatically thread-safe.
  • Immutable objects do not require a copy constructor.
  • Immutable objects do not require an implementation of clone.
  • Immutable objects allow hashCode to use lazy initialization, and to cache its return value.
  • Immutable objects do not need to be copied defensively when used as a field.
  • Immutable objects are good Map keys and Set elements (Since state of these objects must not change while stored in a collection).
  • Immutable objects have their class invariant established once upon construction, and it never needs to be checked again.

Immutable objects always have “failure atomicity” (a term used by Joshua Bloch) if an immutable object throws an exception, it’s never left in an undesirable or indeterminate state

A method’s throws clause must declare any checked exceptions that are not caught within the body of the method.

A catch clause can catch any exception that may be assigned to the Throwable type. This includes the Error and Exception types.

Overridden methods must have the same name, argument list, and return type.

The overriding method may not limit the access of the method it overrides.

The overriding method may not throw any exceptions that may not be thrown by the overridden method.

The Java runtime system generates RuntimeException and Error exceptions.

When a task’s interrupt() method is executed, the task enters the ready state. The next time the task enters the running state, an InterruptedException is thrown

When an exception is thrown within the body of a try statement, the catch clauses of the try statement are examined in the order in which they appear. The first catch clause that is capable of handling the exception is executed. The remaining catch clauses are ignored.

The finally clause of the try-catch-finally statement is always executed unless the thread of execution terminates or an exception occurs within the execution of the finally clause.

?– The exception class defines mild error conditions that your program encounters. Exceptions can occur when trying to open the file, which does not exist, the network connection is disrupted, operands being manipulated are out of prescribed ranges, the class file you are interested in loading is missing. The error class defines serious error conditions that you should not attempt to recover from. In most cases it is advisable to let the program terminate when such an error is encountered.

The marker interface is a design pattern, used with languages that provide run-time type information about objects. It provides a way to associate metadata with a class where the language does not have explicit support for such metadata. To use this pattern, a class implements a marker interface, and code that interact with instances of that class test for the existence of the interface. Whereas a typical interface specifies methods that an implementing class must support, a marker interface does not do so. The mere presence of such an interface indicates specific behavior on the part of the implementing class. There can be some hybrid interfaces, which both act as markers and specify required methods, are possible but may prove confusing if improperly used. Java utilizes this pattern very well and the example interfaces are:

  • io.Serializable – Serializability of a class is enabled by the class implementing the java.io.Serializable interface. The Java Classes that do not implement Serializable interface will not be able to serialize or deserializ their state. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
  • rmi.Remote – The Remote interface serves to identify interfaces whose methods may be invoked from a non-local virtual machine. Any object that is a remote object must directly or indirectly implement this interface. Only those methods specified in a “remote interface”, an interface that extends java.rmi.Remote are available remotely.
  • lang.Cloneable – A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class. Invoking Object’s clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.
  • servlet.SingleThreadModel – Ensures that servlets handle only one request at a time. This interface has no methods.
  • util.EvenListener – A tagging interface that all event listener interfaces must extend.
  • The “instanceof” keyword in java can be used to test if an object is of a specified type. So this keyword in combination with Marker interface can be used to take different actions based on type of interface an object implements.

An uncaught exception results in the uncaughtException() method of the thread’s ThreadGroup being invoked, which eventually results in the termination of the program in which it is thrown.

The exception propagates up to the next higher level try-catch statement (if any) or results in the program’s termination.

If a checked exception may be thrown within the body of a method, the method must either catch the exception or declare it in its throws clause.

In Java, if the super class of a class is implementing Serializable interface, it means that it is already serializable. Since, an interface cannot be unimplemented, it is not possible to make a class non-serializable. However, the serialization of a new class can be avoided. For this, writeObject () and readObject() methods should be implemented in your class so that a Not Serializable Exception can be thrown by these methods. And, this can be done by customizing the Java Serialization process. Below the code that demonstrates it

class MySubClass extends SomeSerializableSuperClass {

private void writeObject(java.io.ObjectOutputStream out)

throws IOException {

throw new NotSerializableException(“Can not serialize this class”);

}

private void readObject(java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException {

throw new NotSerializableException(“Can not serialize this class”);

}

private void readObjectNoData()

throws ObjectStreamException; {

throw new NotSerializableException(“Can not serialize this class”);

}

}

You can provide a try/catch block to handle it. OR

Make sure method declaration includes a throws clause that informs the calling

method an exception might be thrown from this particular method

When you extend a class and override a method, can this new method throw

exceptions other than those that were declared by the original method

No it cannot throw, except for the subclasses of those exceptions

If you put finally after a try block without a matching catch block then it will be

executed after the try block

If it is placed after the catch block and there is no exception then also it will be

executed after the try block

If there is an exception and it is handled by the catch block then it will be executed

after the catch block

Many leave out Trees and Graphs. Trees and Graphs are very useful data structures as well.Whilst it is not recommended to write your own implementation when Java provides proven and tested implementations, the interviewer is testing your understanding on data structures. My book entitled “Core Java Career Essentials” covers this in more detail with diagrams, examples, and code.

Here are the common data structures.

Arrays are the most commonly used data structure. Arrays are of fixed size, indexed, and all containing elements are of the same type (i.e. a homogenous collection). For example, storing employee details just read from the database as EmployeeDetail[ ], converting and storing a string as a byte array for further manipulation or processing, etc. Wrap an array in a class to protect it from being inadvertently altered. This would be true for other data structures as well.

Lists are known as arrays that can grow. These data structures are generally backed by a fixed sized array and they re-size themselves as necessary. A list can have duplicateelements. For example,  adding new line items to an order that stores its line items as a list, removing all expired products from a list of products, etc. Initialize them with an appropriate initial size to minimize the number of re-sizes

Sets are like lists but they do not hold duplicate elements. Sets can be used when you have a requirement to store unique elements.

Stacks allow access to only one data item, which is the last item inserted (i.e. Last In First Out – LIFO). If you remove this item, you can access the next-to-last item inserted, and so on. The LIFO is achieved through restricting access only via methods like peek( ), push( ), and pop( ). This is useful in many programing situations like parsing mathematical expressions like (4+2) * 3, storing methods and exceptions in the order they occur, checking your source code to see if the brackets and braces are balanced properly, etc.

The LIFO access mechanism used by a stack has many practical uses.  For example, Evaluation of expressions / syntax Parsing, validating and parsing XML, undo sequence in a text editor, pages visited history in a web browser, etc. Java interview questions and answers on stack data structure.

Queues are somewhat like a stack, except that in a queue the first item inserted is the first to be removed (i.e. First In First Out – FIFO). The FIFO is achieved through restricting access only via methods like peek( ), offer( ), and poll( ). For example,  waiting in a line for a bus, a queue at the bank or super market teller, etc.

LinkedLists are data structures made of nodes, where each node contains data and a reference to the next node, and possibly to the previous node as well for a doubly linked list. For example, a stack or queue can be implemented with a linked list or a doubly linked list because you can insert and delete at both ends. There would also be other situations where data will be frequently inserted and deleted from the middle. The Apache library provides a TreeListimplementation, which is a good replacement for a LinkedList as it performs much better than a LinkedList at the expense of using a little more memory.  This means a LinkedList is rarely a good choice of implementation.

 

ArrayList is a good general purpose list implementation. An ArrayList is faster than a TreeList for most operations except inserting and removing in the middle of the list. A TreeList implementation utilizes a tree structure internally to ensure that all insertions and removals are O(log n). This provides much faster performance than both an ArrayList and a LinkedListwhere elements are inserted and removed repeatedly from anywhere.

 

 

class Link

{

private int id;                    // data

private String name;               // data

private Link next;                 // reference to next link

}

HashMaps are amortized constant-time access data structures that map keys to values. This data structure is backed by an array. It uses a hashing functionality to identify a location, and some type of collision detection algorithm is used to handle values that hash to the same location. For example, storing employee records with employee number as the key, storing name/value pairs read from a properties file, etc. Initialize them with an appropriate initial size to minimize the number of re-sizes.

 

Trees are the data structures that contain nodes with optional data elements and one or more child elements, and possibly each child element references the parent element to represent a hierarchical or ordered set of data elements.  For example, a hierarchy of employees in an organization, storing the XML data as a hierarchy, etc.  If every node in a tree can have utmost 2 children, the tree is called a binary tree. The binary trees are very common because the shape of a binary tree makes it easy to search and insert data. The edges in a tree represent quick ways to navigate from node to node.

list.

Java does not provide an implementation for this but it can be easily implemented as shown below. Just make a class Node with an ArrayList holding links to other Nodes.

package bigo;

import java.util.ArrayList;

import java.util.List;

 

public class Node {

private String name;

private List<node> children = new ArrayList<node>( );

private Node parent;

 

public Node getParent( ) {

return parent;

}

 

public void setParent(Node parent) {

this.parent = parent;

}

 

public Node(String name) {

this.name = name;

}

 

public void addChild(Node child) {

children.add(child);

}

 

public void removeChild(Node child) {

children.remove(child);

}

 

public String toString( ) {

return name;

}

}

Graphs are data structures that represent arbitrary relationships between members of any data sets that can be represented as networks of nodes and edges. A tree structure is essentially a more organized graph where each node can only have one parent node. Unlike a tree, a graph’s shape is dictated by a physical or abstract problem. For example,nodes (or vertices)  in a graph may represent cities, while edges may represent airline flight routes between the cities.

 

To make a Java graph class, you will have to work out the way in which the information can be stored and accessed. A graph will be using some of the data structures mentioned above. The Java API does not provide an implementation for this. But there are a number of third party libraries like  JUNG, JGraphT, and JDSL (does not seem to support generics).The book “Core Java Career Essentials” covers working examples using Java.

The init method is designed to be called only once. It is called when the servlet is first created, and not called again for each user request. So, it is used for one-time initializations, just as with the init method of applets.

The servlet is normally created when a user first invokes a URL corresponding to the servlet, but you can also specify that the servlet be loaded when the server is first started.

When a user invokes a servlet, a single instance of each servlet gets created, with each user request resulting in a new thread that is handed off to doGet or doPost as appropriate. The init() method simply creates or loads some data that will be used throughout the life of the servlet.

The init method definition looks like this:

public void init() throws ServletException

{

// Initialization code…

}

There are two ways to find it:

Using Classloader

Below code snippet can be used to find the location of java class

com.fromdev.MyClass
this.getClass().getClassLoader().getResource(“com/fromdev/MyClass.class”)

 

Using Protection Domain

We can use this to find the exact location a jar file containing the class JVM is using

clazz.getProtectionDomain().getCodeSource().getLocation()

How Java handles Two classes with same name in classpath

If I have two classes with same name say MyClass.java in two different jar in my classpath which one will be picked up by JVM , is there anyway I can suggest JVM to pick a specific one ?

Java interpreter loads classes based on the order they are specified in the CLASSPATH variable.
For example, lets say this is your classpath variable value

C:\Project\Dir1;C:\Project\Dir2

The Java interpreter will first look for MyClass class in the directory C:\Project\Dir1. Only if it doesn’t find it in that directory it will look in the C:\Project\Dir2 directory.

How to Add A Jar File To Java Load Path At Run Time

This can done by use of URLClassloader. A sample implementation of this code is shown below

 

import java.net.URL;

import java.net.URLClassLoader;

 

public class SimpleJarLoader {

 

public static void main(String args[]) {

if (args.length < 2) {

System.out.println(“Usage: [Class name] [Jar Path]”);

return;

}

try {

System.out.println(“Trying to load the class…”);

Class.forName(args[0]);

} catch (Exception ex) {

System.out.println(“Not able to load class…” + args[0]);

}

 

try {

String url = “jar:file:/” + args[1] + “!/”;

URL urls[] = { new URL(url) };

URLClassLoader cl = new URLClassLoader(urls,

SimpleJarLoader.class.getClassLoader());

System.out.println(“Looking into jar… ” + url);

cl.loadClass(args[0]);

System.out.println(“Woohoo….I found it”);

} catch (Exception ex) {

System.out.println(“Oops…Still cant find the jar”);

ex.printStackTrace();

}

}

}

You can run this code by below command. (Make sure to use forward slash “/” as directory separator.)

 

java SimpleJarLoader org.springframework.core.SpringVersion C:/spring.jar

 

The output is like this

 

Trying to load the class…

Not able to load class…org.springframework.core.SpringVersion

Looking into jar… jar:file:/C:/spring.jar!/

Woohoo….I found it

The death of thread

– Use of system.exit()

– Turning off the power to CPU

– An exception arising in the finally block itself

Rules for catching multiple exceptions

– A more specific catch block must precede a more general one in the source, else it

gives compilation error

– Only one catch block, that is first applicable one, will be executed

The Observer pattern is a behavioral design pattern that  allows an object (an Observer) to watch another object (a Subject). The subject and observer to have a publish/subscribe relationship. Observers can register to receive events from the Subject.

Some of the practical uses of observer pattern are:

  • When a change to one object requires changing of others, and you don’t know how many objects need to be changed.
  • When an object should be able to notify other objects without making assumptions about who these objects are and not tightly coupling them.
  • When a report is received or an event occurs, a message needs to be sent to the subscribed handlers.

Examples:

  • Programming Swing based GUI applications where the listeners register them with events like button click, property change, etc.
  • Programming a stock market application to know when the price of a stock changes.
  • Programming a order placement or trading application to know the status changes like pending, filled, shipped, rejected, etc.

So, whenever you want to have the state change or other information, instead of polling every few second, register the observers with a subject.

 

Here is some pseudo code of this third scenario

STEP 1: Define the Subject and Observer interfaces

This is the subject interface

package com;

 

public interface ReportExecutor {

public void addHandler(ReportHandler rh);

public void removeHandler(ReportHandler rh);

public void processReport(String message);

}

This is the observer interface

package com;

 

public interface ReportHandler {

//handles report

public void handleMessage(String message);

}

STEP 2: Define the concrete subject and observers

The concrete subject

package com;

 

import java.util.ArrayList;

import java.util.List;

 

public class SalesReportExecutor implements ReportExecutor {

 

//list of observers that register their interest in SalesReport

private List<reporthandler> reportHandlers = new ArrayList<reporthandler>();

@Override

public void addHandler(ReportHandler rh) {

reportHandlers.add(rh);

}

@Override

public void processReport(String message) {

for (ReportHandler reportHandler : reportHandlers) {

reportHandler.handleMessage(message);

}

}

@Override

public void removeHandler(ReportHandler rh) {

reportHandlers.remove(rh);

}

}

The concrete observers

package com;

 

public class LoggingReportHandler implements ReportHandler {

 

@Override

public void handleMessage(String message) {

//handles report by formatting and printing

System.out.println(“Logging report  ” + message);

}

}

 

package com;

 

public class EmailReportHandler implements ReportHandler {

 

@Override

public void handleMessage(String message) {

//handles the report by formatting it differently and emailing.

System.out.println(“Emailing report ” + message);

//logic to email report.

}

}

 

STEP 3: Finally, the JMS listener class that uses the subject. The JMS Listener class listens on a queue for presence of a report.

package com.mgl.mts.fix;

 

import javax.jms.Message;

import javax.jms.TextMessage;

 

public class MyAppListener {

 

public void onMessage(Message message) {

if (message instanceof TextMessage) {

 

ReportExecutor executor = new SalesReportExecutor();

executor.addHandler(new LoggingReportHandler());

executor.addHandler(new EmailReportHandler());

executor.processReport(message.toString());

 

} else {

throw new IllegalArgumentException(“Message must be of type TextMessage”);

}

}

}

In Java, memory leaks are possible under a number of scenarios. Here is a typical example where hashCode( ) and equals( ) methods are not implemented for the Key class that is used to store key/value pairs in a HashMap.

This will end up creating a large number of duplicate objects. All memory leaks in Java end up with java.lang.OutOfMemoryError, and it is a matter of time. The following code agressively creates the OutOfMemoryError via an endless loop for demonstration purpose.

If you are not familiar with the significance of equals( ) and hashCode ( ) methods in Java, then learn with this example how to define proper key class in Java.

import java.util.HashMap;

import java.util.Map;

 

public class MemoryLeak {

 

public static void main(String[] args) {

Map<Key, String> map = new HashMap<Key, String>(1000);

 

int counter = 0;

while (true) {       // creates duplicate objects due to bad Key class

map.put(new Key(“dummyKey”), “value”);

counter++;

if (counter % 1000 == 0) {

System.out.println(“map size: ” + map.size());

System.out.println(“Free memory after count ” + counter + ” is ” + getFreeMemory() + “MB”);

 

sleep(1000);

}

}

}

 

 

// inner class key without hashcode() or equals() — bad implementation

 

static class Key {

private String key;

 

public Key(String key) {

this.key = key;

}

 

}

 

//delay for a given period in milli seconds

 

public static void sleep(long sleepFor) {

try {

Thread.sleep(sleepFor);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

//get available memory in MB

public static long getFreeMemory() {

return Runtime.getRuntime().freeMemory() / (1024 * 1024);

}

 

}

 

If you run the above code, you will get the ouput as shown below

map size: 1000

Free memory after count 1000 is 4MB

map size: 2000

Free memory after count 2000 is 4MB

map size: 1396000

Free memory after count 1396000 is 2MB

map size: 1397000

Free memory after count 1397000 is 2MB

map size: 1398000

Free memory after count 1398000 is 2MB

map size: 1399000

Free memory after count 1399000 is 1MB

map size: 1400000

Free memory after count 1400000 is 1MB

map size: 1401000

Free memory after count 1401000 is 1MB

…..

…..

map size: 1452000

Free memory after count 1452000 is 0MB

map size: 1453000

Free memory after count 1453000 is 0MB

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

 at java.util.HashMap.addEntry(HashMap.java:753)

 at java.util.HashMap.put(HashMap.java:385)

 at MemoryLeak.main(MemoryLeak.java:10)

As you could see, the size of the map keeps growing with the same objects and the available memory keeps coming down from 4MB to 0MB. At the end, the program dies with an OutOfMemoryError.

This is one of the most commonly asked questions from JDBC fundamentals, and knowing all the steps of JDBC connection is important.

import java.sql.*;

class JDBCTest {

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

{

//Load driver class

Class.forName (“oracle.jdbc.driver.OracleDriver”);

//Create connection

Connection conn = DriverManager.getConnection

(“jdbc:oracle:thin:@hostname:1526:testdb”, “scott”, “tiger”);

// @machineName:port:SID,   userid,  password

 

Statement stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(“select ‘Hi’ from dual”);

while (rs.next())

System.out.println (rs.getString(1));   // Print col 1 => Hi

stmt.close();

}

}

The transient keyword in Java is used to indicate that a field should not be serialized. Once the process of de-serialization is carried out, the transient variables do not undergo a change and retain their default value. Marking unwanted fields as transient can help you boost the serialization performance. Below is a simple example where you can see the use of transient keyword.

class MyVideo implements Serializable  {

private Video video;

private transient Image thumbnailVideo;

private void generateThumbnail()

{

// Generate thumbnail.

}

private void readObject(ObjectInputStream inputStream)

throws IOException, ClassNotFoundException

{

inputStream.defaultReadObject();

generateThumbnail();

}

}

All exceptions are subclasses of a class called java.lang.Throwable

Method forName() is a static method of java.lang.Class. This can be used to dynamically load a class at run-time. Class.forName() loads the class if its not already loaded. It also executes the static block of loaded class. Then this method returns an instance of the loaded class. So a call to Class.forName(‘MyClass’) is going to do following:

  • Load the class MyClass.
  • Execute any static block code of MyClass.
  • Return an instance of MyClass.

JDBC Driver loading using Class.forName is a good example of best use of this method. The driver loading is done like this

Class.forName(“org.mysql.Driver”);

All JDBC Drivers have a static block that registers itself with DriverManager and DriverManager has static initializer method registerDriver() which can be called in a static blocks of Driver class. A MySQL JDBC Driver has a static initializer which looks like this:

static {

try {

java.sql.DriverManager.registerDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException(“Can’t register driver!”);

}

}

Class.forName() loads driver class and executes the static block and the Driver registers itself with the DriverManager.

This indicates that the method throws some exception and the caller method

should take care of handling it

NoClassDefFoundError and ClassNotFoundException are very closely related and often confused with each other by many developers. Below is the description of each from the Java API Specifications

ClassNotFoundException

Thrown when an application tries to load in a class through its string name using:

  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader.
  • The loadClass method in class ClassLoader.

but the definition of the class with the specified name could not be found due to following reasons

  • The specified name class does not exist.
  • The specified name class is not in the classpath
  • The specified name class is not visible to the classloader.

NoClassDefFoundError

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.

Key Differences

  • The NoClassDefFoundError is thrown when the source was successfully compiled, but during runtime, the required class files were not found. This may be a case when some dependency jar files were not included or not in classpath.
  • A ClassNotFoundException is thrown when the reported class is not found by the ClassLoader or not visible to the Classloader.
  • Another important distinction between these two is, NoClassDefFoundError is a sub class of java.lang.Error and the ClassNotFoundException is a subclass of java.lang.Exception.
  • NoClassDefFoundError is a critical error for JVM since its having problems finding a class it expected to find.

On the other hand, the ClassNotFoundException is an Exception. Use of reflection api can be error-prone and there is no compile-time check to validate reflection call is loading right classes, so there can be situations when some classes may not be found.

Some scenario when ClassNotFoundException may occur:

Scenario 1 (Use of reflection) – You will see ClassNotFoundException when you are using reflection to load classes at runtime, and the class you are trying to load does not exist or not in classpath.

Scenario 2 (Multiple Classloaders being used) – You will see ClassNotFoundException when a class is being loaded from another class which was already loaded in a parent classloader and the class from the child classloader is not visible.

At high level – Fail-fast is a property of a system or software with respect to its response to failures. A fail-fast system is designed to immediately report any failure or condition that is likely to lead to failure. Fail-fast systems are usually designed to stop normal operation rather than attempt to continue a possibly-flawed process. When a problem occurs, a fail-fast system fails immediately and visibly. Failing fast is a non-intuitive technique: “failing immediately and visibly” sounds like it would make your software more fragile, but it actually makes it more robust. Bugs are easier to find and fix, so fewer go into production. In Java, Fail-fast term can be related to context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object “structurally”, a concurrent modification exception will be thrown. It is possible for other threads though to invoke “set” method since it doesn’t modify the collection “structurally”. However, if prior to calling “set”, the collection has been modified structurally, “IllegalArgumentException” will be thrown.

We can do this by using try/catch/finally blocks

You place the normal processing code in try block

You put the code to deal with exceptions that might arise in try block in catch block

Code that must be executed no matter what happens must be place in finally block

The JdbcRowSet implementation is a wrapper around a ResultSet object that has following advantages over ResultSet

  • This implementation makes it possible to use the ResultSet object as a JavaBeans component. A JdbcRowSet can be used as a JavaBeans component in a visual Bean development environment, can be created and configured at design time and executed at run time.
  • It can be used to make a ResultSet object scrollable and updatable. All RowSet objects are by default scrollable and updatable. If the driver and database being used do not support scrolling and/or updating of result sets, an application can populate a JdbcRowSet object with the data of a ResultSet object and then operate on the JdbcRowSet object as if it were the ResultSet object.

CallableStatement Example in Java

The JDBC CallableStatement interface extends PreparedStatement and provides support for output and input/output parameters. The CallableStatement interface also has support for input parameters that is provided by the PreparedStatement interface.

The CallableStatement interface allows the use of SQL statements to call stored procedures. Stored procedures are programs that have a database interface. These programs possess the following:

  • They can have input and output parameters, or parameters that are both input and output.
  • They can have a return value.
  • They have the ability to return multiple ResultSets.

CREATE PROCEDURE GetImmediateManager

@employeeID INT,

@managerID INT OUTPUT

AS

BEGIN

SELECT @managerID = ManagerID

FROM HumanResources.Employee

WHERE EmployeeID = @employeeID

END

Conceptually in JDBC, a stored procedure call is a single call to the database, but the program associated with the stored procedure may process hundreds of database requests. The stored procedure program may also perform a number of other programmatic tasks not typically done with SQL statements.

public static void executeStoredProcedure(

Connection con) {

try {

CallableStatement cstmt = con.prepareCall(“{call dbo.GetImmediateManager(?, ?)}”);

cstmt.setInt(1, 5);

cstmt.registerOutParameter(2, java.sql.Types.INTEGER);

cstmt.execute();

System.out.println(“MANAGER ID: ” + cstmt.getInt(2));

}

catch (Exception e) {

e.printStackTrace();

}

}

Get CLOB Object Using JDBC

package com.Javastuff.jdbc;

import java.sql.*;

import java.util.*;

import java.io.*;

public class GetEmployeeDetails {

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

Driver d= (Driver) ( Class.forName(

“oracle.jdbc.driver.OracleDriver”).newInstance());

Properties p=new Properties ();

p.put(“user”,”scott”);

p.put(“password”,”tiger”);

Connection con=d.connect(

“jdbc:oracle:thin:@mysys:1521:javastuff”,p);

Statement st=con.createStatement();

ResultSet rs=st.executeQuery( “select profile from empprofiles where empno=”+s[0]);

while (rs.next()) {

Reader r=rs.getCharacterStream(1);

FileWriter fw=new FileWriter(“ProfileOf”+s[0]+”.doc”);

int i=r.read();

while (i!=-1){

fw.write(i);

i=r.read();

}//while

}//while

System.out.println(“Profile retrived”);

con.close();

}//main

}//class

How to convert blob to byte array in java

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] buf = new byte[1024];

InputStream in = blob.getBinaryStream();

int n = 0;

while ((n=in.read(buf))>=0)

{

baos.write(buf, 0, n);

}

in.close();

byte[] bytes = baos.toByteArray();

BatchUpdate in JDBC

The JDBC drivers that support JDBC 2.0 and above support batch updates. Batch updates is a option given by the JDBC in which application developers can submit a set of SQL update statements as batch to the database.

The following methods used for creating, executing, and removing a batch of SQL updates:

  • addBatch
  • executeBatch
  • clearBatch

package com.javstuff.jdbc;

 

import java.sql.*;

import java.util.*;

import java.io.*;

public class BatchUpdateExample {

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

Driver d= (Driver) ( Class.forName(

“oracle.jdbc.driver.OracleDriver”).newInstance());

Properties p=new Properties ();

p.put(“user”,”scott”);

p.put(“password”,”tiger”);

Connection con=d.connect(“jdbc:oracle:thin:@mysys:1521:javastuff”,p);

Statement st=con.createStatement();

//statement1

st.addBatch(“insert into emp(empno,sal,deptno) values(“+s[0]+”,1000,10)”);

//statement2

st.addBatch(“update emp set sal=2000 where empno=”+s[0]);

//statement3

st.addBatch(“insert into emp(empno,sal,deptno) values(202,1000,10)”);

//statement4

st.addBatch(“insert into emp(empno,sal,deptno) values(203,1000,10)”);

try {

int[] counts=st.executeBatch();

System.out.println(“Batch Executed Successfully”);

for (int i=0;i<counts.length;i++){

System.out.println(“Number of records effected by statement”+(i+1)+”: “+counts[i]);

}//for

}//try

catch(BatchUpdateException e){

System.out.println(“Batch terminated with an abnormal condition”);

int[] counts=e.getUpdateCounts();

System.out.println(“Batch terminated at statement”+ (counts.length+1));

for (int i=0;i<counts.length;i++) {

System.out.println(“Number of records effected by the statement”+ (i+1)+”: “+counts[i]);

}//for

}//catch

con.close();

}//main

}//class

Arrays in JDBC

Array, one of the SQL 99 datatypes. offers you the facility to include an ordered list of values within the column. The java.sql.Array interface to store the values of the array types. To store the Array first we need to create a User-Defined-Type Array. this can be done by creating a UDT as array in database.

package com.Javastuff.jdbc;

 

import java.sql.*;

import java.util.*;

import oracle.sql.*;

 

public class InsertEmpPassportDetails {

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

Driver d= (Driver) ( Class.forName(

“oracle.jdbc.driver.OracleDriver”).newInstance());

Properties p=new Properties ();

p.put(“user”,”scott”);

p.put(“password”,”tiger”);

Connection con=d.connect(

“jdbc:oracle:thin:@Javastuff:1521:sandb”,p);

PreparedStatement ps=con.prepareStatement(“insert into emppassportDetails values(?,?,?)”);

ps.setInt(1,7934);

ps.setString(2,”12345A134″);

String s1[]={“v1″,”v2″,”v3″,”v4″,”v5”};

ArrayDescriptor ad=ArrayDescriptor.createDescriptor(“VISA_NOS”,con);

ARRAY a=new ARRAY(ad,con,s1);

ps.setArray(3,a);

int i=ps.executeUpdate();

System.out.println(“Row Inserted, count : “+i);

con.close();

}//main

}//class

DatabaseMetaData in JDBC

The DatabaseMetaData class is used to determine the capabilities of a JDBC driver and it database during runtime. If a given method of this interface is not supported by the JDBC driver, the method will either throw an SQLException, or in the case of a method that returns a result set, it may return null. Some of the methods take search patterns as its arguments. The pattern values used can be the SQL wildcard characters % and _. Other search arguments accept an empty set (“”) when the argument is not applicable, or null to drop the argument from the search criteria.

This interface is implemented by driver vendors to let users know the capabilities of a Database Management System (DBMS) in combination with the driver based on JDBC driver that is used with it. Different relational DBMSs often support different features, implement features in different ways, and use different data types. In addition, a driver may implement a feature on top of what the DBMS offers. Information returned by methods in this interface applies to the capabilities of a particular driver and a particular DBMS working together.

The JDBC API enables you to uncover metadata about a database using the DatabaseMetaData interfaces. The DatabaseMetaData interface enables you to obtain information about your database’s attributes and make runtime decisions based around that information.

package com.javastuff.jdbc;

import java.sql.*;

import java.util.*;

import java.io.*;

public class DataBaseMetaDataExample {

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

Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

Connection con =

DriverManager.getConnection(“jdbc:odbc:javastuff”, “scott”,”tiger”);

DatabaseMetaData db= con.getMetaData();

System.out.println(“Database name : “+db.getDatabaseProductName());

System.out.println(“Database version : “+db.getDatabaseProductVersion());

System.out.println(“\nDriver Name : “+ db.getDriverName());

System.out.println(“Driver Version : “+ db.getDriverVersion());

con.close();

}//main

}//class

Checked exceptions are exceptions that arise in a correct program, typically due

to user mistakes like entering wrong data or I/O problems

From Sun FAQ Page: Many Collection implementations (including all of the ones provided by the JDK) will have a public clone method, but it would be mistake to require it of all Collections. For example, what does it mean to clone a Collection that’s backed by a terabyte SQL database? Should the method call cause the company to requisition a new disk farm? Similar arguments hold for serializable. If the client doesn’t know the actual type of a Collection, it’s much more flexible and less error prone to have the client decide what type of Collection is desired, create an empty Collection of this type, and use the addAll method to copy the elements of the original collection into the new one. Note on Some Important Terms

  • Synchronized means only one thread can modify a hash table at one point of time. Basically, it means that any thread before performing an update on a hashtable will have to acquire a lock on the object while others will wait for lock to be released.

Fail-fast is relevant from the context of iterators. If an iterator has been created on a collection object and some other thread tries to modify the collection object “structurally”, a concurrent modification exception will be thrown. It is possible for other threads though to invoke “set” method since it doesn’t modify the collection “structurally”. However, if prior to calling “set”, the collection has been modified structurally, “IllegalArgumentException” will be thrown

This can be done by using a simple reflection API hack as demonstrated in below sample code. This example assumes you have a file “c:/Sample.txt” that is not already in class path and at run-time c:/ is added the System classpath and then Sample.txt is made available.

import java.io.File;

import java.io.InputStream;

import java.lang.reflect.Method;

import java.net.URL;

import java.net.URLClassLoader;

 

public class HackJavaClasspath {

 

public static void addURL(URL url) throws Exception {

URLClassLoader cl = (URLClassLoader) ClassLoader

.getSystemClassLoader();

Class clazz = URLClassLoader.class;

 

Method method = clazz.getDeclaredMethod(“addURL”,

new Class[] { URL.class });

method.setAccessible(true);

method.invoke(cl, new Object[] { url });

}

 

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

//Add c: to the classpath

addURL(new File(“c:/”).toURI().toURL());

//Now load the file from new location

InputStream in = Thread.currentThread().getContextClassLoader()

.getResourceAsStream(“Sample.txt”);

System.out.println(in.available());

 

}

}

Running this java class prints the number of bytes available. This indicates the file is available for further processing.

Runtime exceptions are due to programming bugs like out of bond arrays or null

pointer exceptions.

When an exception is thrown in a try block and is caught by a matching catch

block, the exception is considered to have been handled

Yes, the serialization process can be customized. When an object is serialized, objectOutputStream.writeObject (to save this object) is invoked and when an object is read, ObjectInputStream.readObject () is invoked. What most people do not know is that Java Virtual Machine provides you with an option to define these methods as per your needs. Once this is done, these two methods will be invoked by the JVM instead of the application of the default serialization process. Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException;

private void readObjectNoData()throws ObjectStreamException;

Warnings are issued by database to notify user of a problem which may not be very severe. Database warnings do not stop the execution of SQL statements. In JDBC SQLWarning is an exception that provides information on database access warnings. Warnings are silently chained to the object whose method caused it to be reported. Warnings may be retrieved from Connection, Statement, and ResultSet objects.

Handling SQLWarning from connection object

//Retrieving warning from connection object

SQLWarning warning = conn.getWarnings();

//Retrieving next warning from warning object itself

SQLWarning nextWarning = warning.getNextWarning();

//Clear all warnings reported for this Connection object.

conn.clearWarnings();

Handling SQLWarning from Statement object

//Retrieving warning from statement object

stmt.getWarnings();

//Retrieving next warning from warning object itself

SQLWarning nextWarning = warning.getNextWarning();

//Clear all warnings reported for this Statement object.

stmt.clearWarnings();

Handling SQLWarning from ResultSet object

//Retrieving warning from resultset object

rs.getWarnings();

//Retrieving next warning from warning object itself

SQLWarning nextWarning = warning.getNextWarning();

//Clear all warnings reported for this resultset object.

rs.clearWarnings();

The call to getWarnings() method in any of above way retrieves the first warning reported by calls on this object. If there is more than one warning, subsequent warnings will be chained to the first one and can be retrieved by calling the method SQLWarning.getNextWarning on the warning that was retrieved previously. A call to clearWarnings() method clears all warnings reported for this object. After a call to this method, the method getWarnings returns null until a new warning is reported for this object. Trying to callgetWarning() on a connection after it has been closed will cause an SQLException to be thrown. Similarly, trying to retrieve a warning on a statement after it has been closed or on a result set after it has been closed will cause an SQLException to be thrown. Note that closing a statement also closes a result set that it might have produced.

Errors are usually compile time and exceptions can be runtime or checked

There is no catch block that names either the class of exception that has been

thrown or a class of exception that is a parent class of the one that has been thrown,

then the exception is considered to be unhandled, in such condition the execution

leaves the method directly as if no try has been executed

Get the following exception:

Exception in thread “main” java.lang.IllegalThreadStateException

at java.lang.Thread.start(Thread.java:595)

at deadlock.DeadlockTest.main(DeadlockTest.java:38)

If an application has thread leak then with time it will have too many unused threads. Try to find out what type of threads is leaking out.

This can be done using following ways:

  • Give unique and descriptive names to the threads created in application. – Add log entry in all thread at various entry and exit points in threads.
  • Change debugging config levels (debug, info, error etc) and analyze log messages.
  • When you find the class that is leaking out threads check how new threads are instantiated and how they’re closed.
  • Make sure the thread is Guaranteed to close properly by doing following – Handling all Exceptions properly.
  • Make sure the thread is Guaranteed to close properly by doing following
  • Handling all Exceptions properly.
  • releasing all resources (e.g. connections, files etc) before it closes.

This can be fixed a number of ways.

Option 1: Method level synchronization. This is the simplest. As you can see, the increment() method is synchronized, so that the other threads must wait for the thread that already has the lock to execute that method.

import java.util.HashMap;

import java.util.Map;

 

public class Counter {

 

//shared variable or resource

private Integer count = Integer.valueOf(0);

 

private Map<String, Integer> userToNumber = new HashMap<String, Integer>(10);

 

public synchronized void  increment() {

try {

count = count + 1;

Thread.sleep(50);

Thread thread = Thread.currentThread();

userToNumber.put(thread.getName(), count);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

public Integer getCount(String name) {

return userToNumber.get(name);

}

}

Option 2: Even though the Option 1 is simple, it locks the entire method and can adversely impact performance for long running methods as each thread has to execute the entire method one at a time. So, the Option 1 can be improved by providing block level lock. Lock only those operations that are acting on the shared resource and making it non-atomic.

The code below uses an Object, which has its own lock to ensure that two threads cannot execute both the Operation 1 and 2 at the same time because there is only one lock.

import java.util.HashMap;

import java.util.Map;

 

public class Counter {

 

//shared variable or resource

private Integer count = Integer.valueOf(0);

 

private Map<String, Integer> userToNumber = new HashMap<String, Integer>(10);

 

private Object mutex = new Object();   // a lock

 

public void  increment() {

try {

synchronized(mutex) {

count = count + 1;                         //operation 1

Thread.sleep(50);

Thread thread = Thread.currentThread();

userToNumber.put(thread.getName(), count); //operation 2

}

// there could be other operations here that uses the shared resource as read only

 

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

public Integer getCount(String name) {

return userToNumber.get(name);

}

}

Option 3: This is a very trivial, but practical example. The Java 5 introduced locks and locks are better than using just objects for more flexible locking scenarios where Locks can be used in place of synchronized blocks. Locks offer more flexibility than synchronized blocks in that a thread can unlock multiple locks it holds in a different order than the locks were obtained. Here is the code that replaces synchronized with a reentrant lock. Synchronized blocks in Java are reentrant, which means if a Java thread enters a synchronized block of code, and thereby take the lock on the object the block is synchronized on, the thread can enter other Java code blocks synchronized on the same lock object.

For example, here is the demo of reentrant lock.

public class Reentrant{

 

public synchronized method1(){

method2();    //calls another synchronized method on the same object

}

 

public synchronized method2(){

//do something

}

}

Here is the Option 3 example using a ReentrantLock.

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

 

public class Counter {

 

// shared variable or resource

private Integer count = Integer.valueOf(0);

 

private Map<String, Integer> userToNumber = new HashMap<String, Integer>(10);

 

private Lock mutex = new ReentrantLock(); // a lock

 

public void increment() {

try {

mutex.lock();

try {

count = count + 1;

Thread.sleep(50);

Thread thread = Thread.currentThread();

userToNumber.put(thread.getName(), count);

} finally {

mutex.unlock(); // finally block is executed even if an

// exception is thrown

}

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

 

}

 

}

 

public Integer getCount(String name) {

return userToNumber.get(name);

}

 

}

Note that the locks are unlocked in a finally block as it is executed even if an exception is thrown.

The output for the above 3 options will be something like shown below. The order cannot be guaranteed.

But you will get unique numbers assigned for each user.

User-1 value is 1

User-3 value is 2

User-2 value is 3

This exception is thrown when you try to call wait()/notify()/notifyAll() any of these methods for an Object from a point in your program where u are NOT having a lock on that object.(i.e. u r not executing any synchronized block/method of that object and still trying to call wait()/notify()/notifyAll()) wait(), notify() and notifyAll() all throw IllegalMonitorStateException. since This exception is a subclass of RuntimeException so we r not bound to catch it (although u may if u want to). and being a RuntimeException this exception is not mentioned in the signature of wait(), notify(), notifyAll() methods.

The following code snippet changes the Counter class to maintain individual counting as in each user counter will be incremented starting from 1. So, the Counter will no longer be the shared resource. The CountingTask class is also modified to loop through each user 2 times as shown below. Is there anything wrong with the code shown below

The Counter class with individual counts

import java.util.HashMap;

import java.util.Map;

 

public class Counter {

 

 private Map<String, Integer> userToNumber = new HashMap<String, Integer>(10);

 

 public void increment() {

  Thread thread = Thread.currentThread();

  if (!userToNumber.containsKey(thread.getName())) {

   userToNumber.put(thread.getName(), Integer.valueOf(1));  //op1

  } else {

   Integer count = userToNumber.get(thread.getName());

   if (count != null) {

    ++count; // op2: increment it

    userToNumber.put(thread.getName(), count); //op3

   }

  }

}

 

 public Integer getCount(String name) {

  return userToNumber.get(name);

 }

}

 

// The counting task that repeats twice for each user

public class CountingTask implements Runnable {

 

 private Counter counter;

 

 public CountingTask(Counter counter) {

  super();

  this.counter = counter;

 }

 

public void run() {

 

  for (int i = 0; i < 2; i++) {

   counter.increment();

   Thread thread = Thread.currentThread();

   System.out.println(thread.getName() + ” value is “

     + counter.getCount(thread.getName()));

  }

 }

}

If each user will be accessed by only one thread, then the above code is thread-safe because each user will be operating on his/her data.

So, only one thread will access the map entry for User-1, and so on.

But, what happens if User-3 has two threads created as shown below.

The Thread 3 and 4 are User 3.

In this scenario, the above code is not thread safe, and it needs to be made atomic with one of the three options discussed above. It can be quite dangerous to assume that one user will be accessed only by one thread.What if in the future, additional threads are added to improve performance per user?

public class CountingManager

{

public static void main(String[] args) throws InterruptedException

{

 

Counter counter = new Counter(); // create an instance of the Counter

CountingTask task = new CountingTask(counter); // pass the counter to the runnable CountingTask

 

//Create 10 user threads (non-daemon) from the main thread that share the counter object

Thread thread1 = new Thread(task, “User-1”);

Thread thread2 = new Thread(task, “User-2”);

Thread thread3 = new Thread(task, “User-3”); //user 3

Thread thread4 = new Thread(task, “User-3”); //User 3

 

//start the threads

thread1.start();

thread2.start();

thread3.start();

thread4.start();

 

//observe the racing conditions in the output

}

}

If you don’t perform the operations 1 to 3 atomically (i.e. as a unit),

you will get an out put like:

User-1 value is 1

User-1 value is 2

User-3 value is 2

User-3 value is 3

User-3 value is 2

User-3 value is 4

User-2 value is 1

User-2 value is 2

As you can see, the User-3 has the value 2 repeated twice and value 1 is missing. If you apply the one of the options outlined above, you will get an output like:

User-1 value is 1

User-1 value is 2

User-3 value is 1

User-3 value is 2

User-2 value is 1

User-2 value is 2

User-3 value is 3

User-3 value is 4

Hence, the operations 1-3 need to be made atomic if accessed concurrently by multiple threads.Those three operations are

  • storing the initial value
  • incrementing the counter
  • storing the incremented value

In Java, you can use wait(  ) and notifyAll(  ) to communicate between threads. The code below demonstrates that:

 

Note: This a typical example of splitting tasks among threads. A method calls notify/notifyAll( ) as the last thing it does (besides return). Since the printOdd( ) and printEven( ) methods were void, the notifyAll( ) was the last statement. If it were to return some value, the notifyAll( ) would have been placed just before the return statement.

Firstly, create the thread classes and the main method that creates the thread and run it.

package multithreading;

 

public class NumberGenerator extends Thread {

 

private NumberUtility numberUtility;

private int maxNumber;

private boolean isEvenNumber;

 

 

public NumberGenerator(NumberUtility numberUtility, int maxNumber, boolean isEvenNumber) {

this.numberUtility = numberUtility;

this.maxNumber = maxNumber;

this.isEvenNumber = isEvenNumber;

}

 

public void run() {

int i = isEvenNumber == true ? 2 : 1;

while (i <= maxNumber) {

if(isEvenNumber == true) {

numberUtility.printEven(i);

}

else {

numberUtility.printOdd(i);

}

 

i = i + 2;

}

}

 

 

public static void main(String[] args) {

NumberUtility numUtility = new NumberUtility(); //<span id=”IL_AD6″ class=”IL_AD”>single</span> instance shared by oddGen and evenGen threads

final int MAX_NUM = 10;

 

//create 2 threads, one to generate odd numbers and the other to generate even numbers

NumberGenerator oddGen = new NumberGenerator(numUtility, MAX_NUM, false);

NumberGenerator evenGen = new NumberGenerator(numUtility, MAX_NUM, true);

 

oddGen.start();  //start the thread – invokes the run() method on NumberGenerator

evenGen.start(); //start the thread – invokes the run() method on NumberGenerator

 

}

 

}

Next, create the utility class that is used for communicating between the two threads with wait() and notifyAll() methods via synchronized methods.

 

package multithreading;

 

import static java.lang.System.out;

 

public class NumberUtility {

 

boolean oddPrinted = false;

 

public synchronized void printOdd(int number) {

 

while (oddPrinted == true) {

try {

wait();   // waits until notified by even thread

 

} catch (InterruptedException e) {

e.printStackTrace();

}

}

 

out.println(“printOdd() ” + number);

oddPrinted = true;

notifyAll();  //notify all waiting threads

 

}

 

public synchronized void printEven(int number) {

while (oddPrinted == false) {

try {

wait();  //waits until notified by the odd thread

 

} catch (InterruptedException e) {

 

}

}

 

oddPrinted = false;

out.println(“printEven() ” + number);

notifyAll();  //notify all waiting threads

}

}

The output will be something like:

printOdd() 1

printEven() 2

printOdd() 3

printEven() 4

printOdd() 5

printEven() 6

printOdd() 7

printEven() 8

printOdd() 9

printEven() 10

In Unix, a pipe (“|”) operator helps you to redirect output from one command to another.

PipedReader and PipedWriterclasses in java.io package helps you to do the same.

It helps you to redirect the read input into writer seamlessly.

In Unix, two different processes on different address spaces can communicate using pipe, but in java two threads on the JVM can communicate using Piped ByteStream/CharacterStream within the same process

(i.e same address space)

 

 

 

Here is the code snippet. The Writer threads responsible for writing odd and even numbers to the respective pipes.

package multithreading;

 

import java.io.IOException;

import java.io.PipedWriter;

 

public class NumberWriter extends Thread {

 

private PipedWriter writer;

private int maxNumber;

private boolean isEvenNumber;

 

public NumberWriter(PipedWriter writer, int maxNumber, boolean isEvenNumber) {

this.writer = writer;

this.maxNumber = maxNumber;

this.isEvenNumber = isEvenNumber;

}

 

public void run() {

int i = 1;

while (i <= maxNumber) {

try {

if (isEvenNumber && (i % 2) == 0) {

writer.write(i);

} else if (!isEvenNumber && i%2 != 0) {

writer.write(i);

}

++i;

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

public static void main(String[] args) {

final int MAX_NUM = 10;

 

PipedWriter oddNumberWriter = new PipedWriter();

PipedWriter evenNumberWriter = new PipedWriter();

 

NumberWriter oddGen = new NumberWriter(oddNumberWriter, MAX_NUM, false);

NumberWriter evenGen = new NumberWriter(evenNumberWriter, MAX_NUM, true);

NumberReceiver receiver = new NumberReceiver(oddNumberWriter, evenNumberWriter);

 

oddGen.start();

evenGen.start();

receiver.start();

 

}

 

}

 

 

The receiver thread that listens to both odd and even number pipes and computes the sum. If the sum is a multiple of 5, it prints the numbers and the sum.

package multithreading;

 

import java.io.IOException;

import java.io.PipedReader;

import java.io.PipedWriter;

 

public class NumberReceiver extends Thread {

 

private PipedReader oddReader;

private PipedReader evenReader;

 

public NumberReceiver(PipedWriter oddWriter, PipedWriter evenWriter) {

try {

this.oddReader = new PipedReader(oddWriter);

this.evenReader = new PipedReader(evenWriter);

} catch (IOException e) {

e.printStackTrace();

}

}

 

public void run() {

int odd =0, even=0;

 

try {

while (odd != -1) {

odd = oddReader.read();

even = evenReader.read();

 

if ((odd + even) % 5 == 0) {

System.out.println(“match found ” + odd + ” + ” + even + ” = ” + (odd + even));

}

}

 

} catch (IOException e) {

System.exit(1);

}

 

 

}

}

The output will be something like:

match found 7 + 8 = 15

  • Declaring variables in JSP pages are not thread-safe. The declared variables in JSP pages end-up as instance variables in the converted Servlets. <%! Calendar c = Calendar.getInstance(); %>
  • Decalring instance variables in Servlets is not thread safe, as Servlets are inherently multi-threaded and gets accessed by multiple-threads. Same is true for the Actionclasses in the struts framework.
  • Some of the Java standard library classes likeSimpleDateFormat is not thread-safe. Always check the API to see if a particular class is thread-safe. If a particular class or library is not therad-safe, you could do one of three things.

Provide your own wrapper class that decorates the third-party library with proper synchronization.

This is a typical use of the decorator design pattern.

Use an alternative library, which is thread-safe if available.

For example, Joda Time Library.

Use it in a thread-safe manner.

For example, you could use the SimpleDateFormat class as shown below within a ThreadLocal class.

Each thread will have its own instance of the SimpleDateFormat object.

 

public class DateFormatTest

{

//          anonymous inner class. Each thread will have its own copy

 

private final static ThreadLocal<SimpleDateFormat> shortDateFormat

=  new ThreadLocal<SimpleDateFormat>()

{

protected SimpleDateFormat initialValue()

{

return new SimpleDateFormat(“dd/MM/yyyy”);

}

};

 

public Date convert(String strDate)throws ParseException

{

//          get the SimpleDateFormat instance for this thread and parse the date string

 

Date d = shortDateFormat.get().parse(strDate);

return d;

}

}

  • The one that is very popular with the interviewers is writing the singleton classes that are not thread-safe.

Yes, a Non synchronized method can always be called without any problem. In fact Java does not do any check for a non-synchronized method. The Lock object check is performed only for synchronized methods/blocks. In case the method is not declared synchronized Jave will call even if you are playing with shared data. So you have to be careful while doing such thing. The decision of declaring a method as synchronized has to be based on critical section access. If your method does not access a critical section (shared resource or data structure) it need not be declared synchronized. Below is the example which demonstrates this, The Common class has two methods synchronizedMethod1() and method1() MyThread class is calling both the methods in separate threads,

public class Common {

public synchronized void synchronizedMethod1() {

System.out.println(“synchronizedMethod1 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“synchronizedMethod1 done”);

}

public void method1() {

System.out.println(“Method 1 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“Method 1 done”);

}

}

public class MyThread extends Thread {

private int id = 0;

private Common common;

public MyThread(String name, int no, Common object) {

super(name);

common = object;

id = no;

}

public void run() {

System.out.println(“Running Thread” + this.getName());

try {

if (id == 0) {

common.synchronizedMethod1();

} else {

common.method1();

}

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

Common c = new Common();

MyThread t1 = new MyThread(“MyThread-1”, 0, c);

MyThread t2 = new MyThread(“MyThread-2”, 1, c);

t1.start();

t2.start();

}

}  

Here is the output of the program

Running ThreadMyThread-1

synchronizedMethod1 called

Running ThreadMyThread-2

Method 1 called

synchronizedMethod1 done

Method 1 done

This shows that method1() – is called even though the synchronizedMethod1() was in execution.

The code snippets below demonstrates non-atomic operations producing incorrect results with code. The program below uses a shared Counter object, that is shared between three concurrent users (i.e. three threads). The Counter object is responsible for incrementing the counter.

Firstly, the Counter class. The counted values are stored in a HashMap by name (i.e. thread name) as the key for later retrieval.

import java.util.HashMap;

import java.util.Map;

 

public class Counter {

 

//         shared variable or resource

private Integer count = Integer.valueOf(0);

private Map<String, Integer> userToNumber = new HashMap<String, Integer>(10);

 

public void  increment() {

try {

count = count + 1;      //          increment the counter

Thread.sleep(50);      //          to imitate other operations and

//          to make the racing condion to occur more often for the demo

Thread thread = Thread.currentThread();

userToNumber.put(thread.getName(), count);

}

catch (InterruptedException e) {

e.printStackTrace();

}

}

public Integer getCount(String name) {

return userToNumber.get(name);

}

}

Next, the Runnable task where each thread will be entering and executing concurrently.

public class CountingTask implements Runnable

{

private Counter counter;

public CountingTask(Counter counter) {

super();

this.counter = counter;

}

 

public void run() {

counter.increment();

Thread thread = Thread.currentThread();

System.out.println(thread.getName() + ” value is ” + counter.getCount(thread.getName()));

}

}

Finally, the Manager class that creates 3 new threads from the main thread.

public class CountingManager {

 

public static void main(String[] args) throws InterruptedException

{

 

Counter counter = new Counter(); // create an instance of the Counter

CountingTask task = new CountingTask(counter); // pass the counter to the runnable CountingTask

 

//Create 10 user threads (non-daemon) from the main thread that share the counter object

Thread thread1 = new Thread(task, “User-1”);

Thread thread2 = new Thread(task, “User-2”);

Thread thread3 = new Thread(task, “User-3”);

 

//start the threads

thread1.start();

thread2.start();

thread3.start();

 

//observe the racing conditions in the output

}

}

To see the racing condition, inspect the output of the above code:

User-3 value is 3

User-1 value is 3

User-2 value is 3

All three threads or users get assigned the same value of 3 due to racing conditions. We are expecting to see three different count values to be assigned from 1 to 3. What happened here is that when the first thread incremented the count from 0 to 1 and entered into the sleep(50) block, the second and third threads incremented the counts from 1 to 2 and 2 to 3 respectively.

This shows that the 2 operations — the operation that increments the thread and the operation that stores the incremented value in a HashMap are not atomic, and produces incorrect results due to racing conditions.

The example below causesa deadlocksituation bythread-1 waiting for lock2and thread-0 waiting for lock1.

 

package deadlock;

 

public class DeadlockTest extends Thread

{

public static Object lock1 = new Object();

public static Object lock2 = new Object();

public void method1()

{

synchronized (lock1)

{

delay(500);  //some operation

System.out.println(“method1: ” + Thread.currentThread().getName());

synchronized (lock2)

{

System.out.println(“method1 is executing …. “);

}

}

}

public void method2()

{

synchronized (lock2)

{

delay(500);   //some operation

System.out.println(“method1: ” + Thread.currentThread().getName());

synchronized (lock1)

{

System.out.println(“method2 is executing …. “);

}

}

}

public void run()

{

method1();

method2();

}

public static void main(String[] args)

{

DeadlockTest thread1 = new DeadlockTest();

DeadlockTest thread2 = new DeadlockTest();

 

thread1.start();

thread2.start();

}

private</span> void delay(long timeInMillis)

{

try

{

Thread.sleep(timeInMillis);

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

}

The output will be something like:

method1: Thread-0

method1 is executing ….

method2: Thread-0

method1: Thread-1

—deadlock —– can’t proceed further

No. If a object has synchronized instance methods then the Object itself is used a lock object for controlling the synchronization. Therefore all other instance methods need to wait until previous method call is completed. See the below sample code which demonstrate it very clearly. The Class Common has 2 methods called synchronizedMethod1() and synchronizedMethod2() MyThread class is calling both the methods

public class Common {

public synchronized void synchronizedMethod1() {

System.out.println(“synchronizedMethod1 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“synchronizedMethod1 done”);

}

public synchronized void synchronizedMethod2() {

System.out.println(“synchronizedMethod2 called”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“synchronizedMethod2 done”);

}

}

public class MyThread extends Thread {

private int id = 0;

private Common common;

 

public MyThread(String name, int no, Common object) {

super(name);

common = object;

id = no;

}

public void run() {

System.out.println(“Running Thread” + this.getName());

try {

if (id == 0) {

common.synchronizedMethod1();

} else {

common.synchronizedMethod2();

}

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

Common c = new Common();

MyThread t1 = new MyThread(“MyThread-1”, 0, c);

MyThread t2 = new MyThread(“MyThread-2”, 1, c);

t1.start();

t2.start();

}

}