How to Create a Custom Java Exception

Java programming language uses special exception classes to handle program errors and exceptional events in the system. Java organizes exceptions into 3 basic types - Exception, Error and RuntimeException.

The Exception and Error classes are root level classes. The Exception class and its derived classes indicates internal application errors. The Error class and its derived classes indicates serious external errors encountered in an application such as a hard disk failure or memory failure.

One special derived class of Exception is the RuntimeException. RuntimeException and its derived classes are used for internal application errors that cannot be recovered from. For example, when an operation is attempted on a null object it throws NullPointerException which is derived from RuntimeException.

Exception classes and its derived classes are known as checked exceptions since programmers must handle them in the code. RuntimeException and its derived classes are known as unchecked exceptions since handling them is optional. Error and its derived classed are also unchecked exceptions.

How to Write Your Own Custom Java Exceptions

If you are building a large Java application, it is important to define your own custom classes for error conditions in your applications. Exceptions in Java are a controversial topic and the following sections are based on my own opinion.

When you build your own Java exceptions start with two root level Exceptions. These high level exceptions will indicate recoverable logical errors and non recoverable system errors. I usually name them as AppLogicalException and AppSystemException. AppLogicalException extends from Exception and hence is a checked exception and AppSystemException extends from RuntimeException and hence is an unchecked exception. All exceptions in your application depending on whether they are recoverable should be derived from one of these classes.

Following are examples for custom Java exceptions. As as example I have added an additional parameter called error code. This is purely optional and is only required if you are going to use the same exception class for closely related errors. In this case error code can be used for identifying a specific sub type.

// AppSystemException.java
// Base exception class for all application non recoverable errors
public class AppSystemException extends RuntimeException {
    
    // special code for use where message is not suitable
    private int errorCode;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
    
    public AppSystemException(int errorCode) {
        this.errorCode = errorCode;
    }
    
    public AppSystemException(int errorCode, Throwable t) {
        super(t);
        this.errorCode = errorCode;
    }
    
    public AppSystemException(int errorCode, String message, Throwable t) {
        super(message, t);
        this.errorCode = errorCode;
    }
}

// AppLogicalException.java
// Base exception class for all application recoverable errors
public class AppLogicalException extends Exception {

    // special code for use where message is not suitable
    private int errorCode;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public AppLogicalException(int errorCode) {
        this.errorCode = errorCode;
    }

    public AppLogicalException(int errorCode, Throwable t) {
        super(t);
        this.errorCode = errorCode;
    }

    public AppLogicalException(int errorCode, String message, Throwable t) {
        super(message, t);
        this.errorCode = errorCode;
    }
}

How to Implement Bubble Sort in Java

Bubble sort is one of the simplest and easy to understand sort algorithm. It works by comparing each pair of adjacent elements in a list and swapping them if they are in wrong order. This swapping process is repeated for the entire set of elements again and again until no swaps are detected. At this point the whole list is sorted.

Since we may need to go through the entire list again and again, the worst case timing of the bubble sort is proportional to n*n where n is the number of elements in the list. Clearly bubble sort is an inefficient algorithm.

Understanding Bubble Sort

Bubble sort is easy to understand if explained with an example. Assume that we are given this list of numbers - [4,2,5,1]. The bubble sort works by going through the list and comparing the adjacent elements. Let us say we want the numbers to be sorted in the ascending order.

Pass 1 - We go through the entire list comparing adjacent elements and swapping them if needed, Initial - [4,2,5,1]
After first comparison - [2,4,5,1]
After second comparison - [2,4,5,1]
After third comparison - [2,4,1,5]

We start the next pass since there are no more elements to compare and we have detected a swap in the previous pass.

Pass 2 - We again through the entire list we have after the first pass,
Initial - [2,4,1,5]
After first comparison - [2,4,1,5]
After second comparison - [2,1,4,5]
After third comparison - [2,1,4,5]

We start the next pass since there are no more elements to compare and we have detected a swap in the previous pass.

Pass 3 - We again through the entire list we have after the second pass,
Initial - [2,1,4,5]
After first comparison - [1,2,4,5]
After second comparison - [1,2,4,5]
After third comparison - [1,2,4,5]

We start the next pass since there are no more elements to compare and we have detected a swap in the previous pass.

Pass 4 - We again through the entire list we have after the third pass,
Initial - [1,2,4,5]
After first comparison - [1,2,4,5]
After second comparison - [1,2,4,5]
After third comparison - [1,2,4,5]

This time we detected no swaps. This means that the list is sorted!

How to Implement Bubble Sort in Java

Following Java example program is a non optimized implementation of bubble sort. I have used the data set mentioned above for the program. The program has two implementations of bubble sort. The first one simply does the bubble sort and the second one shows the bubble sort iterations in the console. Also note that this Java example does in place sorting of the array destroying the original input.

import java.util.Arrays;

// Sorts a list of numbers using bubble sort
public class BubbleSortInJava {

    public static void main(String[] args) {
        int[] input = new int[] { 4, 2, 5, 1 };

        System.out.println("input:" + getArrayAsString(input));
        performBubbleSort(input);
        System.out.println("output:" + getArrayAsString(input));

        // Let us run the bubble sort in an animation for better understanding!
        input = new int[] { 4, 2, 5, 1 };
        System.out.println("Starting the sorting animation");
        performBubbleSortWithAnimation(input);
    }

    // Java example - Bubble sort
    // Please see the tutorial for more details of the algorithm   
    private static int[] performBubbleSort(int[] input) {
        int size = input.length;
        boolean swapped = false;
        do {
            swapped = false;
            for (int i = 1; i < size; i++) {
                if (input[i - 1] > input[i]) {
                    int temp = input[i];
                    input[i] = input[i - 1];
                    input[i - 1] = temp;
                    swapped = true;
                }
            }

        } while (swapped);
        return input;
    }

    // Convert an array to displayable string
    private static String getArrayAsString(int[] values) {
        return Arrays.toString(values);
    }

    // Perform bubble sort and display each step in the console
    private static int[] performBubbleSortWithAnimation(int[] input) {
        int size = input.length;
        boolean swapped = false;
        int phase = 1;
        do {
            swapped = false;
            System.out.println("phase " + phase + "-initial-" + getArrayAsString(input) + "   ");
            for (int i = 1; i < size; i++) {
                try {
                    Thread.sleep(1000);
                } catch (Exception ex) {
                }
                if (input[i - 1] > input[i]) {
                    int temp = input[i];
                    input[i] = input[i - 1];
                    input[i - 1] = temp;
                    swapped = true;
                }
                System.out.println("phase " + phase + "-comparison " + i + "-" + getArrayAsString(input) + "   ");
            }
            phase++;
        } while (swapped);
        return input;
    }
}

There are a number of variations of the Bubble sort which optimizes the sorting process. However if you are looking for an efficient algorithm, you should look at a different algorithm such as quick sort.

Spring Boot Crud Application Tutorial with MongoDB

Welcome to this quick tutorial on creating a spring boot crud application with MongoDB database. This tutorial assumes that you are familiar with Java web applications, spring framework, MongoDB and gradle build system. This tutorial also uses spring tool suite(STS) as the IDE. If you are not familiar with STS, check out getting started with spring boot and STS tutorial.

Spring boot makes things so easy that sometimes it might seem like magic! High productivity and concise code is achieved through spring boot  starter projects and auto configuration of components. Let us get started on our first spring boot crud application.

Step 1: Create a spring boot project from a starter project using spring tool suite. Follow the instructions in this spring boot tutorial. Delete the HomeController.java from the project if you have created it following the above tutorial.

Step 2: Install and run a MongoDB instance locally. This tutorial uses a MongoDB database for persisting the data. Download the community edition from here and extract the zip to a folder of your choice. Add the bin folder in the operating system path. Then create a folder where you want MongoDB to keep its data file. Use the following command to run MongoDB from console,

mongod --dbpath <your path to datafiles>

You can connect to the running MongoDB instance using the following command,

mongo

In the mongo console, type the following command to see databases. You should see "test" database in the list.

show dbs

Following are some of the useful commands in mongo console,

Switch to "test" database,

use test

Show tables in the current database,

show collections

Print all records in the customer collection (after the collection is created from the application),

db.customer.find()

Step 3: Replace the build.gradle with the following file. This file has two additional dependencies. The library spring-boot-starter-data-rest is used for enabling REST endpoints for data repositories and spring-boot-starter-data-mongodb is used for MongoDB connectivity. Spring boot auto configuration wires them all together and assumes that you are connecting to a local Mongo instance at the default port. No further configuration is required!

buildscript {
    ext { 
        springBootVersion = '1.5.2.RELEASE'
    }
    repositories {
        mavenCentral() 
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    } 
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'demoapp'
    version = '0.0.1-SNAPSHOT'
}

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile("org.springframework.boot:spring-boot-starter-data-mongodb")	

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Step 4: Create a Java object representation for MongoDB table. In this tutorial we will create a simple crud for customer data. Following is a Java bean representing a single customer record in the mongo customer table. Please note that you don't need to create this collection/table in mongo, it will be automatically created during the first insert.

package com.quickprogrammingtips.demoapps;

import org.springframework.data.annotation.Id;

// Java bean representation of Mongo customer table
public class Customer {
    @Id private String id;
    private String name;
    private String email;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

Step 5: Create a repository class for customer object. A spring repository is an interface which allows us to access our database tables. By extending our repository from MongoRepository, we are indicating that we are using a mongo collection. Annotate it using @RepositoryRestResource so that it is exposed as a REST endpoint automatically. Note that we specified the mongo collection name (collectionResourceRel) and the REST url path (path) in the annotation. Even @RepositoryRestResource is optional if you just want default collection to url path mapping!

package com.quickprogrammingtips.demoapps;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerRepository extends MongoRepository<Customer, String>{

}

The actual implementation of the above interface is automatically created by spring boot. If you need access to this repository in your classes you can inject in using the @Autowired annotation. In our example even that is not necessary since the REST controller for the repository is auto created by spring boot!

Step 6: Run the spring boot application from IDE. Right click the project and click on Run As => Spring Boot App. If all goes well, your application and its REST endpoints will be up and running on http://localhost:8080.

Step 7: Access the crud features from the following links. To POST data, you can use browser extensions such as postman or use the curl command line tool.

  • GET http://localhost:8080/customer - Queries all customers. The data is returned in json format.
  • GET http://localhost:8080/customer/<object_id> - Queries the customer corresponding to the mongo object id specified. You can find the object id from the db directly.
  • POST http://localhost:8080/customer  - Saves the customer record json specified in the post body.
  • DELETE http://localhost:8080/customer/<object_id>  - Deletes the customer record corresponding to the mongo object id specified.

For example, the following curl command creates a new customer record is database. Login to mongo console to verify that the records are inserted in the database.

curl -i -X POST -H "Content-Type:application/json" -d '{"name":"qpt","email":"quickprogrammer@gmail.com"}' localhost:8080/customer

The following curl command deletes a customer record,

curl -i -X DELETE http://localhost:8080/customer/58bba27b82127c348722df0f

Voila! Now you have a complete crud application with a few lines of code. This implementation is also suitable for building microservices using spring boot.

Customizing Spring Boot Application

Ok. All this auto configuration is cool. But what if I want to use my own configuration? For example, what if I want to connect to a remote MongoDB instance. Luckily spring boot allows us to override defaults whenever needed. Here are some examples of configuring spring boot,

How to Configure MongoDB in Spring Boot

If you want to connect to a non local mongo database instance, you can specify the configuration in the application.properties located at src/main/resources. In the following url, user:password@ is the optional login credentials for the mongodb. The last part of the url(test) indicates the name of the database.

spring.data.mongodb.uri=mongodb://user:password@192.168.1.5:27017/test

 

How to Implement a Custom Query REST Endpoint?

In the above example, what if you want search for customers with a specific email id? You can implement custom searches by adding findBy methods on the column. Check out the following updated CustomerRepository with a custom search on email column added. Such methods are automatically mapped to the /customer/search endpoint. Also note that the @Param annotation indicates the name of the http query parameter used for search.

package com.quickprogrammingtips.demoapps;
import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

@RepositoryRestResource(collectionResourceRel = "customer", path = "customer")
public interface CustomerRepository extends MongoRepository<Customer, String>{
    List<Customer> findByEmail(@Param("mail") String mail);
}

Invoke the following endpoint to find the list of search queries available,

http://localhost:8080/customer/search

Invoke the following endpoint to find all the customers with a specified email,

http://localhost:8080/customer/search/findByEmail?mail=quickprogrammer@gmail.com

How to Disable Spring Boot Banner

When you start a spring boot application, the spring logo is printed on the console using ascii art. In spring boot terminology this is known as the boot startup banner. In default configuration, the startup banner is the first output printed on the console.

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

When you are running your application in the production, you may want to turn off spring boot banner. There are a number of ways to disable spring boot banner.

Disable Spring Boot Banner Using banner-mode Property

You can disable spring boot banner using the spring.main.banner-mode property.  This property can take 3 values,

  • off - Turn off spring boot banner display
  • console - Print banner using System.out on the console
  • log - Print banner using the configured log file

So how do you set the value for spring.main.banner-mode property? Spring boot offers a number of options,

  • Pass it as a parameter to the Java command,
java -Dspring.main.banner-mode=off  -jar app.jar
  • Set the property in the application.properties inside the resources folder of the spring boot project,

spring.main.banner-mode=off

  • Set the property in the application.yaml if you are using YAML files,

spring:

  main:

    banner-mode:"off"

Disable Spring Boot Banner Programmatically Using SpringApplication.setBannerMode

Spring boot also has an option to disable boot banner programmatically. You can use setBannerMode method of SpringApplication class. This requires minor changes to the main method of your spring boot application class as given below,

package com.example;

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SimplespringappApplication {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(SimplespringappApplication.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }
}

It is also possible to supply your own banner by adding a file named banner.txt in the classpath.

How to Parse a CSV file in Java

A CSV file is a simple text file used to store tabular data. Each line is a record of data and consists of fields separated by commas. The main advantage of CSV file format is that it is portable and human readable. Files using proprietary formats such as Microsoft excel files can be exported to CSV files for portability. The following Java program parses simple CSV files,

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;

// Sample Java program to read simple CSV files
public class SimpleCSVReader {

    public static void main(String[] args) throws Exception {
        // Replace FileReader parameter with the actual path
        BufferedReader reader = new BufferedReader(new FileReader("input.csv"));
        String line;
        while ((line=reader.readLine()) != null) {
            String[] fields = line.split(",");
            // Print the columns in array form
            System.out.println(Arrays.toString(fields));
        }
        reader.close();
    }

}

Sometimes the fields in the CSV file may contain commas. In order to distinguish commas in data fields from field separators, the fields are usually surrounded by quotes. The above program won't work with such complex CSV files. The following Java program shows how the Apache Commons CSV library can be used to parse such complex CSV files.

You can download Apache Commons CSV library from here. Extract the zip file and then ensure that the jar file commons-csv-1.4.jar is in the classpath. For example, you can use the following commands to compile and run the program if the jar file is present in the same folder containing the Java file ApacheCSVReader.java. Note that the commands are slightly different depending on your operating system.

To compile in linux/mac,

javac -cp "commons-csv-1.4.jar:." ApacheCSVReader.java

To compile in Windows,

javac -cp "commons-csv-1.4.jar;." ApacheCSVReader.java

To run in linux/mac,

java -cp "commons-csv-1.4.jar:." ApacheCSVReader

To run in Windows,

java -cp "commons-csv-1.4.jar;." ApacheCSVReader
import java.io.FileReader;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;

// Java program to parse CSV files using Apache CSV Reader
// Can read CSV files with commas in quoted fields
public class ApacheCSVReader {

    public static void main(String[] args) throws Exception {
        FileReader in = new FileReader("input.csv");
        Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in);
        for (CSVRecord record : records) {
            for (String s : record) {
                System.out.print(s + "|");
            }
            System.out.println();
        }
    }
}

To test the above program, you can use the following sample CSV file (input.csv). Ensure that it is saved in the same folder where Java class files are stored.

India,Sri Lanka, Nepal
"Hi, There","Another message","Greeting"
200, 400,600