In this article, we are going to look at IllegalStateException in java, its meaning and the reason why it occurs.

IllegalStateException resides in java.lang package and it is an unchecked exception since it is a child class of RuntimeException.

This exception is heavily used in java api and when this exception is thrown, it means that a method is called at inappropriate time or the current state of the application does not permit the requested operation.
Java docs for this exception state

Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.

Scenarios
Practical examples for this exception would be

  • Trying to launch a program when the computer restart is in progress.
  • Attempting to start a car when it it already started.
  • Trying to write to a socket which is closed.
  • Adding a shutdown hook when a shutdown is in progress.

In short, IllegalStateException should arise when performing an operation does not make any sense.
Examples in Java api
Following are some of the common places where an IllegalStateException is thrown in java.
Collections
1. Calling remove() on an empty iterator.
2. Trying to add element to a queue that is full.
3. Calling getKey() and getValue() on an entry that has been removed from the map.
4. Trying to modify the value of an element with iterator after removing that element.
Concurrency
1. Calling start() on an already started thread or calling start() more than once.
2. Thrown by forEach() method of java.util.concurrent.ConcurrentMap when an entry has been removed from the map.
Input/Output
1. Invoking methods such as next(), nextLine(), hasNext() on a java scanner object after it is closed.
2. Reading token from StreamTokenizer when reader is null or there is no input to read.
3. Reading an entry from the zip when the zip has been closed.

& many more…

IllegalStateException example
Suppose there is a list of objects and you want to convert this list to a map using java 8 streams. This can be done using below code.

Object[] obj1 = {1,"Object 1"};
Object[] obj2 = {2,"Object 2"};
Object[] obj3 = {3,"Object 3"};

List<Object[]> objects = List.of(obj1, obj2,obj3);

Map<Object, Object> map = objects.
                          stream().
                          collect(
                          Collectors.toMap(obj->obj[0], obj -> obj[1])
                          );

In this example, there is a list whose each element is an Object array. When this list is converted to a map, first element of list element becomes the key and second element becomes the value and the resultant map is

{1=Object 1, 2=Object 2, 3=Object 3}

So far so good.
But, if any two items of the list have same first element(which acts as the key in map), then toMap() method will throw an IllegalStateException.
Thus, if list elements are modified as

Object[] obj1 = {1,"Object 1"};
Object[] obj2 = {1,"Object 2"};
Object[] obj3 = {3,"Object 3"};

then toMap() will throw below error

Exception in thread “main” java.lang.IllegalStateException: Duplicate key 1 (attempted merging values Object 1 and Object 2)

Resolving IllegalStateException
As clear from the discussion, this exception is caused by calling methods at the wrong place.

Thus, the first way is to ensure that the methods are invoked in appropriate context.

Secondly, the exception can be handled by enclosing the code that may result in IllegalStateException between try-catch block.

Hope the article was informative.