Reading a Text File in Java

Java has an extensive API for file handling. The following code illustrates how Java File API can be used to read text files. This example shows line by line reading of the file content. This example also assumes that a text file with the name input.txt is present in the C:\ drive. If you are using a Linux system, replace the path with something like \home\tom\input.txt.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {
    
    public static void main(String[] args) {
        
        try {
            FileReader fr = new FileReader("c:\\input.txt");
            BufferedReader reader = new BufferedReader(fr);
            String line;
            while((line=reader.readLine())!=null) {
                System.out.println(line);
            }
        }catch(IOException ex) {
            ex.printStackTrace();
        }
        
    }
}

The above example reads lines from c:\input.txt file and outputs the lines on the console. Note the following important points illustrated by this file reading program in Java,

  • File operations can throw checked IOException. Hence you need to explicitly handle them.
  • When you use forward slash in path names, you need to escape its special meaning using an additional forward slash.
  • The class FileReader enables character by character reading of text files. However it has no facilities for reading lines.
  • Java uses decorator pattern extensively in File API. In this example we use the BufferedReader decorator class over FileReader. The BufferedReader internally buffers the reading of characters and is also aware of line breaks. Even when a single character is read, BufferedReader internally reads a block of characters from the file system. Hence whenever you request the next character, it is served from the internal buffer not from file system. This makes BufferedReader very efficient compared to FileReader.
  • The readLine() method returns null if BufferedReader encounters end of the file stream.

Struts 2 NetBeans Tutorial

Introduction

Struts 2 is an excellent MVC Web application framework for developing enterprise Java web applications. It enables rapid development of Web applications and handles most of the plumbing required in large Web applications. This tutorial shows how NetBeans IDE can be used to build Struts 2 applications.

Usually Struts2 applications are developed as Maven projects. However in this tutorial I will be demonstrating how to setup the Struts 2 project from scratch as it helps a beginner in understanding the "nuts & bolts" of Struts 2 development.

Pre-requisites

Following tools are required to start Struts 2 web application development using NetBeans,

  • Java SDK - Download and install Java SDK from Oracle site. For this tutorial, I used Java 6, update 26.
  • NetBeans - Download and install NetBeans IDE from here.  Download either the "Java EE" edition or the "All" edition since we need the bundled Tomcat server for running Struts 2 applications. For this tutorial, I used NetBeans 7.1.1.
  • Struts 2 Library Files - Download and extract Struts 2 binary distribution files from here.  I recommend downloading the "Full Distribution" zip file containing all dependency jar files. However the "Essential Dependencies Only" zip file (which is much smaller than full distribution) is also sufficient for the sample application we are going to build. For this tutorial, I used Struts 2.3.1.2.

 

Creating a Struts 2 Application in NetBeans

A Struts 2 application is an ordinary Java Web application with a set of additional libraries. From NetBeans IDE Click on File => New Project. From the New Project window, select Java Web Application and click on Next as shown below,

Creating a new Web application in NetBeans 7

Enter the Project Name as Struts2Demo and select a folder for your project as shown below and click on Next.

Creating a Struts 2 application in NetBeans

Select the server as Apache Tomcat and leave the defaults for other options as shown below. Click on Finish to create the Web application.

Configuring Tomcat for NetBeans Application

By default, NetBeans creates simple index.jsp as part of the Web application which prints "Hello World!" on the browser window. Select the menu Run => Run Main Project (F6) to see the application up and running on Tomcat. The default URL for accessing the application is http://localhost:8084/Struts2Demo/.

The default project structure of the Web application in NetBeans is shown below,

Web application project structure in NetBeans

Adding Struts 2 Libraries to NetBeans Web Application

Before we can convert our simple Web application to a Struts2 application, we need to add the necessary Struts2 libraries to the NetBeans project. The minimum set of Struts2 libraries needed for our tutorial application is given below (note that the version numbers may be different if you are using a different version of Struts2),

  • struts2-core-2.3.1.2.jar - This contains all the Struts2 core classes
  • ognl-3.0.4.jar - OGNL library for using OGNL expression language
  • xwork-core-2.3.1.2.jar - Struts 2 uses XWork MVC library
  • freemarker-2.3.18.jar - UI templates are written in freemarker
  • javassist-3.11.0.GA.jar - Essential dependency of Struts 2
  • commons-io-2.0.1.jar - Essential dependency of Struts 2
  • commons-filleupload-1.2.2.jar - Essential dependency of Struts 2
  • commons-lang-2.5.jar - Essential dependency of Struts 2

From the NetBeans project, right click on Libraries and then click on Add JAR/Folder option. Add all the jars given in the above list from the downloaded Struts2 zip file. After adding all the jars the Libraries section of the NetBeans project should look like the following.

Struts 2 libraries in NetBeans

Configuring Struts 2 in a Web application

The next step in configuring Struts2 Web application is to enable the Struts2 MVC framework in the HTTP request processing. For this we will first configure a Struts2 class (org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter) as a servlet filter by modifying the web.xml. If you don't have web.xml under the Configuration Files section of your NetBeans, you can add it by selecting the menu File => New File => Web => Standard Deployment Descriptor (web.xml) as shown below.

Adding web.xml in NetBeans project

The modified web.xml is given below,

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    
    <display-name>Struts2 Demo App</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

The above configuration in web.xml ensures that all the requests to the Web application will be routed through the Struts 2 StrutsPrepareAndExecuteFilter class. This will act as a single controller dispatching requests to Struts 2 request processors (action classes) based on the request properties.

Converting Hello World Web Application to Struts 2 MVC Web Application

MVC stands for Model-View-Controller and it is a design paradigm which helps in building and maintaining large Web applications. The simplest definition is -  A user request is handled by a controller which in turn gets data from model and forwards it to the view for display.

Let us modify the "Hello World!" application to use Struts 2 MVC architecture to output the "Hello World!" message. The overall architecture of our Hello World Struts 2 MVC application is given below,

Struts 2 application architecture

This means that we need the following components,

  • Model - A class which supplies the data needed for the application. In this demo app, the data supplied is the "Hello World!" message. We will write a simple Message class (Message.java) to return the message.
  • View - A view element which displays the data. In this demo app, we will write a JSP file (message.jsp) which will display the message returned by the Model class.
  • Controller - A controller class which will respond to user URL request. The controller will coordinate the actions of Model and the View. We will write a Struts 2 action class (HelloWorld.java) for this.
  • Struts 2 Configuration - Struts 2 needs to be told about various components of the application. This can be configured in an xml file (struts.xml) or we can use a combination of standard naming conventions and annotations. This tutorial will stick to the traditional way of configuring Struts 2 using struts.xml. For the first time user, conventions and annotations may seem like magic!

For a simple application like "Hello World!" this may seem like an overkill. However for large enterprise Web applications such separation of concerns is very essential for the robustness, reliability, extensibility and maintainability of the application.

Let us first create our model class which holds the "Hello World!" message. In real applications, these model objects will correspond to persistent data. In this simple example we will be directly using the model object from the controller. However in real applications, we will create a business layer which will return the data. Note that the Message class is organized under model java package.

Message.java (model)

package model;

public class Message {
    private String message = "Hello World!";

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Next we will create an action class (controller) which will respond to the user request. The controller in this case will create/retrieve the message and would pass it along to the view.

Typically action classes handling user requests extend from ActionSupport class. The request processing will be done by the overridden execute() method which is automatically called by the framework. Note that the HelloWorld.java (action class) is organized under the controller java package.

HelloWorld.java (controller action class)

package controller;

import com.opensymphony.xwork2.ActionSupport;
import model.Message;

public class HelloWorld extends ActionSupport {
    private Message message;
    
    @Override
    public String execute() {
        setMessage(new Message()); // get data from model
        return SUCCESS;
    }

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }
    
}
 

We will now create the user interface. In this demo example we will use the JSP technology for rendering the user interface. Struts 2 supports other view technologies such as freemarker templates and velocity templates.

message.jsp (View)

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <title><s:property value="message.message" /></title>
    </head>
    <body>
        <h1><s:property value="message.message" /></h1>
    </body>
</html>

Note the use of custom tags in the JSP. These custom tags are provided by Struts 2. The Struts 2 custom tags use the OGNL expressions to refer to the data exposed by the controller class. This is achieved by the Struts 2 framework by automatically exposing the member variables of the controller class to the tag libraries.

In the above example, Struts 2 property tag refers to the value message.message. The framework automatically translates this to the following call on the controller (action class) by convention.

HelloWorld.getMessage().getMessage()

Since we have already prepared the Message object in the HelloWorld controller, we get the "Hello World!" message printed on the screen.

Finally we need to inform Struts 2 framework about our controllers, action classes and view files. This can be configured in struts.xml. This file needs to be located at the root of the source tree (it needs to be in the classpath).

struts.xml (Struts 2 configuration)

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="struts2demo" extends="struts-default">
        <action name="HelloWorld" class="controller.HelloWorld">
            <result>/message.jsp</result>
        </action>
        <!-- Add your actions here -->
    </package>
</struts>

We have specified an action named HelloWorld and indicated which class file needs to be invoked for the action request. By convention, a URL request to HelloWorld.action is mapped to the action name HelloWorld. Also we have configured a result which points to our view component (message.jsp). Struts 2 framework will forward the request to message.jsp when it encounters return SUCCESS in the controller class (HelloWorld.java).

The complete structure of the NetBeans Struts 2 project should look like the following,

Files in HelloWorld Struts 2 application

Run the project from NetBeans. To see the application in action, enter the following URL in the browser,

http://localhost:8084/Struts2Demo/HelloWorld.action

If everything went well, you should see the following screen!

image

Troubleshooting Struts 2 Application Errors

Following are some of the common errors encountered by beginners when working with the above sample program.

java.lang.IllegalStateException: Must have the StrutsPrepareFilter execute before this one

This is due to the use of a wrong filter in the web.xml. Some of the obsolete Struts2 documentation uses org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter as the filter class in web.xml. This is no longer a valid filter class, change this to org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.

java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils

This error indicates that you don't have the commons io library in the Web application library folder. Add commons-io-2.0.1.jar to the libraries folder in NetBeans.

java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils

This error indicates that common lang dependent library is missing. Add commons-lang-2.5.jar to the libraries folder in NetBeans.

java.lang.NoClassDefFoundError: org/apache/commons/fileupload/RequestContext

This error indicates that common file upload dependent library is missing in the project. Add commons-fileupload-1.2.2.jar to the application library folder.

java.lang.ClassNotFoundException: javassist.ClassPool

This error indicates that Javassist library is missing in the project. Add javassist-3.11.0.GA.jar to the application library folder.

java.lang.ClassNotFoundException: ognl.NullHandler

This error indicates that OGNL library is missing in the project. Add ognl-3.0.4.jar to the application library folder.

java.lang.ClassNotFoundException: freemarker.template.TemplateException

This error indicates that freemarker library is missing in the project. Add freemarker-2.3.18.jar to the Web application library folder.

Download NetBeans Struts 2 Application

You can download the above NetBeans Struts 2 demo application from here. Please note that to keep the download size small, I have removed all the library files from the project. You will need to download Struts 2 libraries separately and add them to the project before you can run the application.

If you have questions or feedback, please let me know by commenting below. I will try to answer them here.

Creating a Random BigInteger in Java

Java provides a custom class named BigInteger for handling very large integers (numbers which require more than 64 bits). BigInteger provides a constructor using which you can create a random BigInteger value.

public BigInteger(int numBits, Random rnd)

Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2^numBits - 1), inclusive. The uniformity of the distribution assumes that a fair source of random bits is provided in rnd. Note that this constructor always constructs a non-negative BigInteger.

Random BigInteger Example in Java

The following random BigInteger example program creates a value between 0 and 15,

import java.math.BigInteger;
import java.util.Random;

public class RandomBigInteger {

    public static void main(String[] args) {
        BigInteger result = getRandomBigInteger();
        System.out.println(result);
    }
    public static BigInteger getRandomBigInteger() {
        Random rand = new Random();
        BigInteger result = new BigInteger(4, rand); // (2^4-1) = 15 is the maximum value
        return result;
    }
    
}

This works only if the maximum value of the random number you need is (2^n - 1). What if you need to generate random BigInteger between 0 and x where x can be any value?

The easiest solution is to generate random BigInteger between 0 and (2^n - 1) where n is the bit length for x and then ignore values whenever it is bigger than x.

For example, Assume you want to generate random BigInteger values between 0 and 13. The bit length for 13 is 4. Hence find a random number between 0 and 15 and then ignore the value if it is above 13.

import java.math.BigInteger;
import java.util.Random;

public class RandomBigInteger {

    public static void main(String[] args) {
        BigInteger result = getRandomBigInteger();
        System.out.println(result);
    }
    public static BigInteger getRandomBigInteger() {
        Random rand = new Random();
        BigInteger upperLimit = new BigInteger("13");
        BigInteger result;
        do {
            result = new BigInteger(upperLimit.bitLength(), rand); // (2^4-1) = 15 is the maximum value
        }while(result.compareTo(upperLimit) >= 0);   // exclusive of 13
        return result;
    }
    
}

The obvious drawback of this approach is that sometimes the loop will execute twice in turn invoking the random number generator twice. So if the random number generator passed is computationally intensive, this will affect the performance when generating a large number of random BigIntegers.

Using BigInteger in Java

For handling numbers, Java provides built-in types such as int and long. However these types are not useful for very large numbers. When you do mathematical operations with int or long types and if the resulting values are very large, the type variables will overflow causing errors in the program.

Java provides a custom class named BigInteger for handling very large integers (which is bigger than 64 bit values). This class can handle very large integers and the size of the integer is only limited by the available memory of the JVM. However BigInteger should only be used if it is absolutely necessary as using BigInteger is less intuitive compared to built-in types (since Java doesn't support operator overloading) and there is always a performance hit associated with its use. BigInteger operations are substantially slower than built-in integer types. Also the memory space taken per BigInteger is substantially high (averages about 80 bytes on a 64-bit JVM) compared to built-in types.

Another important aspect of BigInteger class is that it is immutable. This means that you cannot change the stored value of a BigInteger object, instead you need to assign the changed value to a new variable.

Java BigInteger Example

The following BigInteger example shows how a Java BigInteger can be created and how various arithmetic operations can be performed on it,

import java.math.BigInteger;

public class BigIntegerDemo {

    public static void main(String[] args) {
        
        BigInteger b1 = new BigInteger("987654321987654321000000000");
        BigInteger b2 = new BigInteger("987654321987654321000000000");
        
        BigInteger product = b1.multiply(b2);
        BigInteger division = b1.divide(b2);
        
        System.out.println("product = " + product);
        System.out.println("division = " + division);  // prints 1
    
    }
}

 

Computing Factorial Using BigInteger

Computation of factorial is a good example of numbers getting very large even for small inputs. We can use BigInteger to calculate factorial even for large numbers!

import java.math.BigInteger;
public class BigIntegerFactorial {

    public static void main(String[] args) {
        calculateFactorial(50);
    }
    public static void calculateFactorial(int n) {
        
        BigInteger result = BigInteger.ONE;
        for (int i=1; i<=n; i++) {
            result = result.multiply(BigInteger.valueOf(i));
        }
        System.out.println(n + "! = " + result);
    }
    
}

The factorial output for an input value of 50 is,

50! = 30414093201713378043612608166064768844377641568960512000000000000

Creating an Inline Array in Java

The usual way of creating an array in Java is given below. In this example, we create a String array containing primary color names,

public class InlineArrays {

    public static void main(String[] args) {
        String[] colors = {"red","green","blue"};
        printColors(colors);
    }
    public static void printColors(String[] colors) {
        for (String c : colors) {
            System.out.println(c);
        }
                
    }
}

The problem with this approach is that it is unnecessarily verbose. Also there is no need to create a temporary array variable to pass a constant list of values.

Java also provides an inline form of array creation which doesn't need a temporary variable to be created. You can use the inline array form directly as a parameter to a method. Here is the above code example written using inline Java arrays,

public class InlineArrays {

    public static void main(String[] args) {
        printColors(new String[]{"red","green","blue"} );
    }
    public static void printColors(String[] colors) {
        for (String c : colors) {
            System.out.println(c);
        }
                
    }
}

Still the above usage is not as concise as we want it to be. Alternatively you can also use the Varargs feature introduced in Java 5. Whenever Varargs is used, the successive arguments to the method is automatically converted to array members. This is the most concise way of creating an array inline! The above code example can be written as follows,

public class InlineArrays {

    public static void main(String[] args) {
        printColors("red","green","blue");
    }
    public static void printColors(String... colors) {
        for (String c : colors) {
            System.out.println(c);
        }
    }
}

Note the use of ... immediately after the String type in printColors() method definition. This instructs the compiler to automatically convert one or more String arguments into array members of the variable colors. Inside the method you can treat colors as an array.