Running Spring Boot Application on Jetty Server

Follow these instructions to create a simple spring boot application using Spring Tool Suite(STS). The steps are similar for eclipse IDE.

Running Spring Boot App on Jetty Server

The default embedded application server used by spring boot is tomcat. When a spring boot starter project is created using the spring-boot-starter-web dependency, it includes an embedded tomcat instance as well. To use Jetty as the embedded server, add a dependency to the spring-boot-starter-jetty project by modifying the build.gradle file. We will also remove the spring-boot-starter-tomcat dependency from the spring-boot-starter-web dependency since it is no longer needed. Here is the modified build.gradle file,

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'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'   
    }
    compile('org.springframework.boot:spring-boot-starter-jetty')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

To verify the changed dependencies, run the dependencies gradle task. All the dependencies of the project will be printed on the console.

gradle dependencies

Configuring Embedded Jetty Server

It is possible to change various parameters of jetty server by specifying them in the application.properties file located in src/main/resources folder.

# modify the default port on which Jetty listens for requests
server.port = 9090

# modify the default context path
server.context-path= /hello

# Number of acceptor threads to use.
server.jetty.acceptors= 5

# Maximum size in bytes of the HTTP post or put content.
server.jetty.max-http-post-size=1000000

# Number of selector threads to use.
server.jetty.selectors=10 

See this link for a full list of server properties configurable in spring boot.

Right click the build.gradle from IDE and click on Gradle => Refresh Gradle Project. Run the application using the STS IDE or use the gradle bootRun task from command line. Browse the URL http://localhost:9090/hello to access the spring boot application.

Following is the spring boot entry point class used in the above example. The home method prints "Hello World!" on the browser window.

package com.quickprogrammingtips.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
@Controller
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
}

Checking IMEI Number Using Java Programs

IMEI number (International Mobile Equipment Identity) is a unique number used to identify mobile phones. IMEI is used by mobile networks to uniquely identify a device and hence the IMEI number is used to block stolen devices.

IMEI number is composed of 15 decimal digits including a check digit. The last digit in the IMEI number is a check digit computed using Luhn algorithm. The check digit is used to protect against data entry errors in IMEI numbers when entered in devices.

Following algorithm is used to find the check digit in an IMEI number.

  • Given the 14 digits of IMEI number, start from the right.
  • Find the double of every other digit.
  • Find the sum of all digits in the number using doubled numbers for every other digit as computed above.
  • Multiply the sum by 9 and then divide by 10. The remainder is the check digit.

Here is an example illustrating computation of IMEI check digit,

  • 14 digits of an IMEI number = 42015420343761
  • Sum digits (double of every other digit from right) =  4+4+0+2+5+8+2+0+3+8+3+14+6+2 = 4+4+0+2+5+8+2+0+3+8+3+5+6+2 = 52.
  • Multiply with 9 = 52 * 9 = 468
  • Divide by 10 and find the remainder = 468 % 10 = 8
  • The check digit is 8. This is the number which when added with 52 makes it divisible by 10.
  • The full IMEI number is 420154203437618.

Problem: Find the check digit from first 14 digits of an IMEI number using Java

The following Java program computes the last check digit of an IMEI number given the first 14 digits. This program can be used to compute and verify IMEI numbers.

import java.util.Scanner;

// IMEI Java check digit generator example source code
public class IMEICheckDigitGenerator {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.print("Please enter first 14 digits of IMEI number: ");
        String input = s.nextLine();
        
        int checkDigit = getCheckDigit(input);
        
        System.out.println("Check digit: "+checkDigit);
        System.out.println("IMEI Number: "+input+checkDigit);
        s.close();
    }
    
    // Returns check digit for 14 digit IMEI prefix
    public static int getCheckDigit(String imeiPrefix) {
        int sum = 0;
        for(int i = 13;i>=0;i=i-1) {
            String sDigit = imeiPrefix.substring(i,i+1);
            int digit = Integer.valueOf(sDigit);
            if(i%2==0) {
                sum = sum + digit;
            }else {
                sum = sum + sumOfDigits(digit*2);
            }
        }
        sum = sum * 9;
        return sum%10; // Return check digit        
    }
    
    // Calculate sum of digits for a number
    public static int sumOfDigits(int number) {
        int sum=0;
        while(number > 0) {
            sum += number%10;
            number = number/10;
        }
        return sum;
    }
}

Following is a sample output of the above program,

Please enter first 14 digits of IMEI number: 42015420343761
Check digit: 8
IMEI Number: 420154203437618

Problem: Check whether the given 15 digit number is a valid IMEI number using Java

The following java program verifies whether a given IMEI number is valid or not. It uses the last check digit for validation.

import java.util.Scanner;

// Java program to check whether an IMEI number is valid
public class IMEIValidatorInJava {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.print("Please enter a 15 digit IMEI number: ");
        String input = s.nextLine();
        
        int computedCheckDigit = getCheckDigit(input.substring(0,14));
        int checkDigitInSource = Integer.valueOf(input.substring(14));
        
        if(computedCheckDigit == checkDigitInSource) {
            System.out.println(input+" is a valid IMEI number!");
        }else {
            System.out.println(input+" is NOT a valid IMEI number!");
            System.out.println("Check digit computed: "+computedCheckDigit);
        }
        
        s.close();
    }
    
    // Returns check digit for 14 digit IMEI prefix
    public static int getCheckDigit(String imeiPrefix) {
        int sum = 0;
        for(int i = 13;i>=0;i=i-1) {
            String sDigit = imeiPrefix.substring(i,i+1);
            int digit = Integer.valueOf(sDigit);
            if(i%2==0) {
                sum = sum + digit;
            }else {
                sum = sum + sumOfDigits(digit*2);
            }
        }
        sum = sum * 9;
        return sum%10; // Return check digit        
    }
    
    // Calculate sum of digits for a number
    public static int sumOfDigits(int number) {
        int sum=0;
        while(number > 0) {
            sum += number%10;
            number = number/10;
        }
        return sum;
    }
}

Following is a sample output from the program,

Please enter a 15 digit IMEI number: 914859533683732
914859533683732 is NOT a valid IMEI number!
Check digit computed: 0

How to Calculate CRC32 Checksum in Java

Cyclic Redundancy Check (CRC) is an error detection technique commonly used to detect any changes to raw data. CRC checksum is a short fixed length data derived from a larger block of data. If there is a change in original raw data, the computed CRC checksum will differ from the CRC checksum received from the source. This technique is used to detect data errors when a file is read from a storage system. Each file stored in the file system also has the checksum stored along with the content. If the checksum is different when calculated on the file content, we know that the file on the disk is corrupted.

There are differences between CRC checksums and common hash functions such as MD5 and SHA1. CRC checksums are simpler and faster to compute. However they are not cryptographically secure. Hence CRC checksums are used in data error detection while hash functions are used in encryption algorithms.

CRC32 algorithm returns a 32-bit checksum value from the input data. It is very easy to calculate CRC32 checksum of a given string in Java. The following example program generates CRC32 checksum using the built-in class java.util.zip.CRC32.

Java Source Code for CRC32 Checksum Calculation

import java.util.zip.CRC32;

// Calculates CRC32 checksum for a string
public class CRC32Generator {

    public static void main(String[] args) {
        String input = "Hello World!";
        CRC32 crc = new CRC32();
        crc.update(input.getBytes());
        System.out.println("input:"+input);
        System.out.println("CRC32:"+crc.getValue());
    }
}

Here is the output of the program,

input:Hello World!
CRC32:472456355

How to Check Pronic Number in Java

A pronic number is a product of two consecutive integers. Pronic numbers can be expressed in the form n(n+1). For example, 6 is a pronic number since it is the product of two consecutive integers 2 and 3.  These numbers are also known as oblong numbers or heteromecic numbers. Following are the first 10 pronic numbers,

0, 2, 6, 12, 20, 30, 42, 56, 72, 90.

Pronic numbers have some interesting properties. All pronic numbers are even integers and the n-th pronic number is the some of the first n even integers.

Problem: Write a java program to check whether a given number is a pronic number

We know that a pronic number is of the form n(n+1). Hence if we find the square root of a pronic number and then round it to the lower integer, we will get n. If we multiply it with the next integer and if the result is same as the original number we know that the given number is a pronic number! The following Java program uses the above logic to check whether a given number is pronic or not.

import java.util.Scanner;

// Java pronic number checker example
public class PronicNumberChecker {

    // Check whether a given number is pronic or not
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.print("Please enter a number: ");
        long number = s.nextLong();
        
        long n = (long)Math.sqrt(number);
        if(n*(n+1)==number) {
            System.out.println(number+" is a pronic number");
        }else {
            System.out.println(number+" is NOT a pronic number");
        }
        s.close();
    }
}

Here is a sample output of the program,

Please enter a number: 30
30 is a pronic number

Problem: Write a java program to generate first n pronic numbers

Generating first n pronic numbers is trivial. We iterate from 0 till n-1 and compute the product of the current number with the next number. The following Java program generates the first n pronic numbers.

import java.util.Scanner;

// Java example program to generate pronic number sequence
public class PronicNumberGenerator {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.print("How many pronic numbers you need? ");
        long n = s.nextLong();
        
        // Print first n pronic numbers
        for(long i =0;i<n;i++) {
            System.out.print(i*(i+1));
            if(i!=n-1) {
                System.out.print(",");
            }
        }
        
        s.close();
    }
}

Here is the sample output of the program,

How many pronic numbers you need? 10
0,2,6,12,20,30,42,56,72,90

How to Write a MapReduce Program in Java

This tutorial provides a step by step tutorial on writing your first hadoop mapreduce program in java. This tutorial uses gradle build system for the mapreduce java project. This program requires a running hadoop installation.

Quick Introduction to MapReduce

MapReduce is a programming framework which enables processing of very large sets of data using a cluster of commodity hardware. It works by distributing the processing logic across a large number machines each of which will apply the logic locally to a subset of the data. The final result is consolidated and written to the distributed file system.

There are mainly 2 components of a mapreduce program. The mapper and the reducer. The mapper operates on the data to produce a set of intermediate key/value pairs. This data is then fed to a reducer with the values grouped on the basis of the key. The reducer computes the final result operating on the grouped values.

Problem Statement for the MapReduce Program

Problem Statement: Using mapreduce framework, find the frequency of characters in a very large file (running into a few terabytes!). The output consists of two columns - The ASCII character and the number of occurrences of the character in the input file.

We solve this problem using three classes - mapper, reducer and the driver. The driver is the entry point for the mapreduce program. Hadoop mapreduce will use the configured mapper and reducer to compute the desired output.

Prerequisites for Java MapReduce Program

  • Java 1.8 or above
  • Gradle 3.x or above

Creating the MapReduce Java Project in Gradle

Run the following command on console to create a simple Java project in gradle. Ensure that gradle and java is already installed on the system.

gradle init --type java-application

This creates an initial set of files for the Java gradle project. Delete App.java and AppTest.java from the new project (contained in src/main/java and src/test/java folders).

Configuring the MapReduce Gradle Build

Replace the build.gradle in the project with the following,

apply plugin: 'java-library'
apply plugin: 'application'

mainClassName = "AlphaCounter"

jar {
    manifest { attributes 'Main-Class': "$mainClassName" }
}
repositories { jcenter() }

dependencies { compile 'org.apache.hadoop:hadoop-client:2.7.3' }

Writing the Mapper Class

Copy the following class to the src/main/java folder. This is the mapper class for our mapreduce program. The mapreduce framework will pass each line of data as the value variable to the map function. Our program will convert it into a key/value pair where each character becomes a key and the value is set as 1.

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

// A mapper class converting each line of input into a key/value pair
// Each character is turned to a key with value as 1
public class AlphaMapper extends Mapper<Object, Text, Text, LongWritable> {
    private final static LongWritable one = new LongWritable(1);
    private Text character = new Text();

    @Override
    public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        String v = value.toString();
        for (int i = 0; i < v.length(); i++) {
            character.set(v.substring(i, i + 1));
            context.write(character, one);
        }
    }
}

Writing the Reducer Class

Now copy the following reducer function to src/main/java folder. The mapreduce program will collect all the values for a specific key (a character and its occurrence count in our example) and pass it to the reduce function. Our function computes the total number of occurrences by adding up all the values.

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

// Calculate occurrences of a character
public class AlphaReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
    private LongWritable result = new LongWritable();

    public void reduce(Text key, Iterable<LongWritable> values, Context context)
            throws IOException, InterruptedException {
        long sum = 0;
        for (LongWritable val : values) {
            sum += val.get();
        }
        result.set(sum);
        context.write(key, result);
    }
}

Writing the MapReduce Entry point Class

Finally copy the main entry point class for our mapreduce program. This sets up the mapreduce job including the name of mapper and reducer classes.

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

// The driver program for mapreduce job.
public class AlphaCounter extends Configured implements Tool {

    public static void main(String[] args) throws Exception {
        int res = ToolRunner.run(new Configuration(), new AlphaCounter(), args);
        System.exit(res);
    }

    @Override
    public int run(String[] args) throws Exception {

        Configuration conf = this.getConf();

        // Create job
        Job job = Job.getInstance(conf, "Alpha Counter Job");
        job.setJarByClass(AlphaCounter.class);

        job.setMapperClass(AlphaMapper.class);
        job.setReducerClass(AlphaReducer.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        FileInputFormat.addInputPath(job, new Path(args[0]));
        job.setInputFormatClass(TextInputFormat.class);

        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        job.setOutputFormatClass(TextOutputFormat.class);

        return job.waitForCompletion(true) ? 0 : 1;
    }
}

Running the Java MapReduce Program

Run the following command from the project folder to create a jar file for our project,

gradle jar

Copy the jar created to the hadoop home folder. Open a command window and navigate to the hadoop home folder.

First create a simple text file with the content "Hello World" and save it as input.txt. Upload the file to HDFS file system using the following command. This will copy the file to hdfs home folder.

bin/hdfs dfs -put input.txt .

Finally run the mapreduce program from the command line,

bin/hadoop jar mapreducedemo.jar ./input.txt output

Viewing the MapReduce Output

Run the following command to view the output of the mapreduce program,

bin/hdfs dfs -cat output/*

The console output consists of every character in "Hello World" and the number of occurrences of each character as shown below.

     1
H    1
W    1
d    1
e    1
l    3
o    2
r    1

Using a Reducer Program as Combiner

It is possible in mapreduce to configure the reducer as a combiner. A combiner is run locally immediately after execution of the mapper function. Since it is run locally, it substantially improves the performance of the mapreduce program and reduces the data items to be processed in the final reducer stage. Note that combiner can only be used in functions which are commutative and associative.

Add the following line to AlphaCounter.java to configure the reducer as the combiner,

job.setCombinerClass(AlphaReducer.class);