How do I compress a file in Gzip format?

In this code example we will learn how to compress a file using the gzip compression. By its nature, gzip can only compress a single file, you can not use it for compressing a directory and all the files in that directory.

Classes that you will be using to compress a file in gzip format includes the GZipOutputStream, FileInputStream and FileOutputStream classes. The steps for compressing a file described in the comments of the code snippet below.

package org.kodejava.util.zip;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

public class GZipCompressExample {
    public static void main(String[] args) {
        // GZip input and output file.
        String sourceFile = "data.txt";
        String targetFile = "output.gz";

        try (
                // Create a file input stream of the file that is going to be
                // compressed.
                FileInputStream fis = new FileInputStream(sourceFile);

                // Create a file output stream then write the gzip result into
                // a specified file name.
                FileOutputStream fos = new FileOutputStream(targetFile);

                // Create a gzip output stream object with file output stream
                // as the argument.
                GZIPOutputStream gzos = new GZIPOutputStream(fos)) {

            // Define buffer and temporary variable for iterating the file
            // input stream.
            byte[] buffer = new byte[1024];
            int length;

            // Read all the content of the file input stream and write it
            // to the gzip output stream object.
            while ((length = fis.read(buffer)) > 0) {
                gzos.write(buffer, 0, length);
            }

            // Finish file compressing and close all streams.
            gzos.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Creating a simple project using Maven

In this post you will learn how to create a simple project, a Hello World project using Maven. If you haven’t installed Maven in your machine you can read Introduction to Apache Maven posted earlier in this blog. In this post you will see what the basic configuration for creating a maven project. Such as the basic of pom.xml file and how maven structure the directory of our project files.

At this time we won’t use any special IDE such as Eclipse, Netbeans or IntelliJ to create our project. We’ll just work using a simple text editor and the command prompt. Let us begin.

Step 1 – Create a project directory and the pom.xml file.

  • Create a directory where you will place the project files. As an example I’ll create my project in D:\Projects\HelloWorld.
  • Create a file called pom.xml in the HelloWorld directory. POM stands for Project Object Model, and it represents a Maven project.
  • Type the following information in the pom.xml file.
<project>
    <groupId>org.kodejava</groupId>
    <artifactId>HelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <modelVersion>4.0.0</modelVersion>
</project>
  • At this point we have our pom.xml file created. What you’ve seen above is the simplest example of a pom file. And here is a brief description of the pom file above:
    • groupId: the unique id of a Maven project. Typically, it uses your company name domain in reverse order just like how you would create a package for your Java project. For example here I use org.kodejava.
    • artifactId: is the name of the project, we’ll be using HelloWorld.
    • version: is the version number of our project.
    • packaging: the project artifact type. In this case we will ask Maven to package our example as a jar file.
    • modelVersion: is the version of the POM file we are using for this project.

Maven works by applying a concept called convention over configuration. This will apply for example on how the directory of a project is structured. All Maven project will use the same directory for organising the files in the project. There is a directory for Java source codes, unit testing codes, configuration files, etc. This will make easier for developer to jump from one Maven project to the other projects. Now let us continue to the next step.

Step 2 – Create the HelloWorld class.

  • Create a directory for Java source code in the project root directory. Actually you’ll create three directories. These directories are src\main\java.
  • Create a file HellWorld.java under the java directory you’ve created above.
  • Type the following code for the HelloWorld class.
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
  • Now we have our class created we can start to use maven to build our project. But before we do let see what you should have after finishing these steps. You should see that you have a project structure that similar the screen capture below:

Maven HelloWorld

Steps 3 – Compiling the Project.

At this time we have our first Maven project created, and we are ready to build it. To build this basic project we don’t have to add anything to Maven. It already comes with a predefined sets of build related task such as clean, compile, test, package, etc.

  • Open a Command Prompt and go to your project directory. You should be in the HelloWorld directory where you can see the pom.xml file.
  • To compile your project type mvn compile in the command prompt.
D:\Projects\HelloWorld>mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building HelloWorld 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] Compiling 1 source file to D:\Projects\HelloWorld\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.405s
[INFO] Finished at: Tue Sep 24 10:18:10 CST 2013
[INFO] Final Memory: 7M/23M
[INFO] ------------------------------------------------------------------------
D:\Projects\HelloWorld>
  • What you see above is the typical result of a success build. You might see longer message such as information about the artifact downloaded by Maven during the compile process.
  • If you list the project directory you’ll see a new directory called targetclasses is created. And inside the classes directory you’ll find your HelloWorld.class file.
  • To run the class cd to targetclasses and type java HelloWorld.

Steps 4 – Clean and Package the Project.

  • Now if you want to clean your previous built project you can use mvn clean. Make sure you are executing this command from the project root directory where the pom.xml file is located.
  • Executing this command will give you the similar output like this.
D:\Projects\HelloWorld>mvn clean
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building HelloWorld 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ HelloWorld ---
[INFO] Deleting D:\Projects\HelloWorld\target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.353s
[INFO] Finished at: Tue Sep 24 10:29:16 CST 2013
[INFO] Final Memory: 4M/15M
[INFO] ------------------------------------------------------------------------
D:\Projects\HelloWorld>
  • As you can see it deleted the previously created target directory.
  • In the pom.xml file we have defined the packaging of our project as jar file. So let’s create it now.
  • To package a Maven project type mvn package command.
D:\Projects\HelloWorld>mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building HelloWorld 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] Compiling 1 source file to D:\Projects\HelloWorld\target\classes
[INFO] skip non existing resourceDirectory D:\Projects\HelloWorld\src\test\resources
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ HelloWorld ---
[INFO] No sources to compile
[INFO] --- maven-surefire-plugin:2.7.2:test (default-test) @ HelloWorld ---
[INFO] No tests to run.
[INFO] Surefire report directory: D:\Projects\HelloWorld\target\surefire-reports
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
There are no tests to run.
Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ HelloWorld ---
[INFO] Building jar: D:\Projects\HelloWorld\target\HelloWorld-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.040s
[INFO] Finished at: Tue Sep 24 10:32:41 CST 2013
[INFO] Final Memory: 8M/20M
[INFO] ------------------------------------------------------------------------
D:\Projects\HelloWorld>
  • The mvn package gives you a longer console output. From the output above you can see that executing the package command made Maven to compile the Java source code, unit test source code (we don’t have it at this time). It also runs the unit test and finally build the jar file.
  • The jar file is created under the target directory and named HelloWorld-1.0-SNAPSHOT.jar. The name comes from the artifactId, version and packaging information defined in the pom.xml file.

That are all the steps that you need to create and manage a simple project using Maven. We start by creating a pom.xml file and then create a directory structure for storing our classes file. And then we learn how to compile, clean and package our Maven project. In the next Maven post we’ll learn more on Maven dependency management and starting to use an IDE to set up our Maven project.

Thank your for reading and see you on the next Maven post.

Introduction to JUnit

In this post we will start to learn about JUnit Framework. JUnit is a framework for unit testing Java applications. It was developed by Kent Back and Erich Gamma to help developers to create a better applications. JUnit has become the standard tool used by developers when it comes to unit testing.

Every day, when you create an application from the smallest one, that consist of a single class to a project of a large application, your development workflow will always be the same. You will begin by writing a small code, compile it, run the code and finally test it. And you will mostly find that things doesn’t work as expected at first. So you’ll go back to your favorite IDE, check what the error was, and you will repeat the process, code, compile, run and test, until you get the result that you want.

We can do this steps manually. For example when you have a console application you will typically run the code, check the result printed out on the console screen to find out if the program return the correct result. When you find the error you will fix it and re-run the code again and again. This kind of test seems like a time-consuming activity, tiresome and even make you bored. And instead of testing the code you are testing your ability to test. Because you have to check whether the output printed in the console is correct or not.

Here is a simple example of a very simple calculator that know how to add two numbers and how you are testing it using a simple main class in a console application.

package org.kodejava.junit;

public class Calculator {
    public static int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int a = 10;
        int b = 15;
        int c = Calculator.add(a, b);

        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);

        if (c == 25) {
            System.out.println("Test success!");
        } else {
            System.out.println("Test failed!");
        }
    }
}
Testing your ability to test.

Testing your ability to test.

To make life easier JUnit framework comes with great help to overcome these problems. You can tell JUnit framework to test your code by creating a unit tests. You will create a class that test your code, you’ll define your testing criteria in this unit testing class. You can execute these unit testing, and it will report whether the tests pass or fail. And you can run it as many times as you’ll like to see if the test still pass after you modified parts of your code.

Now, let see how JUnit can help us to test the previous calculator code. Before creating the unit test class we need to download the JUnit library from the website at JUnit, follow the link to download page and download the jars. There are two main jar files that you need to download, the junit.jar and hamcrest-core.jar. When you are using and IDE, the JUnit usually installed as part of the IDE such as NetBeans, Eclipse or IntelliJ IDEA.

Let’s write the unit testing code.

package org.kodejava.junit;

import org.junit.Test;
import static org.junit.Assert.*;

public class CalculatorTest {
    @Test
    public void addTwoNumbersTest() {
        int a = 10;
        int b = 15;
        assertEquals(25, Calculator.add(a, b));
    }
}

From this code snippet what you can see is:

  • We create a class called CalculatorTest. We usually name the unit test class with the same name with the class under test but suffix it with Test.
  • We create a test method called addTwoNumberTest(). You can name your test method as descriptive as possible. This will have you understand what the method is trying to test.
  • To make a method a unit test method we add the @Test annotation to it. This annotation will tell the JUnit framework that the annotated method is a part of the unit testing it should execute on our behalf.
  • In the test method body we use the assertEquals() method to check the test result. In this case we expect 25 is returned when the Calculaor.add() method add two numbers, the a + b.

After you create the unit testing class, let’s compile it and this JUnit test from the command prompt. Remember to have also the class under test, which is the Calculator class beside your unit testing class. To execute JUnit test you can type the following command.

java -cp .;junit-4.13.2.jar org.junit.runner.JUnitCore org.kodejava.junit.CalculatorTest

I am intentionally place the junit.jar file in the root of my work directory so that I can make the -cp option short. The classpath options tell Java where to look the required class files.

Executing JUnit Test

Executing JUnit Test

That is all for the bit of introduction to JUnit. In the coming post I will write more about JUnit and how to use other available annotation, so you can write a better test.

How do I create a generic Map object?

In this example of Java Generics you will see how to create a generic Map object. Creating a generic Map means that you can define the type of the key and the type of the value of object stored in the Map. The declaration and the instantiation of a generic Map is only different to other type of collection such as List and Set is that we to define two types. One type for the key and the other type for the value.

The syntax for creating a generic Map is as follows:

Map<K, V> map = new Map<K, V>();

Where K is the type of map key and V is the type of the value stored in the map. If you want a map to hold a value of reference to String object and using an Integer as the key, you will write the declaration and instantiation like the snippet below.

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

To make it simpler, you can use the diamond operator too.

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

When you want to add some elements to the map you can use the same put() method. But you don’t have to worry that you put a wrong type of object into the map. Because the Java compiler will check it to see if you are storing a correct type. Generic will catch the bug that should not happen at runtime because the code is already validated at compile time.

Map <Integer, String> map = new HashMap<>();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");

//map.put("4", new Date()); // Compile time error!  

String a = map.get(1);
String b = map.get(2);
String c = map.get(3);

The get() method will return a value from the map that correspond with the given key. Because the map know that it store values of string, it will return a string. So you don’t need to cast the return value from the map’s get() method. You might wonder why we can put keys like 1, 2, 3. Doesn’t it supposed to be type of Integer? If you remember the auto boxing feature then you’ll understand this. Behind the screen Java will convert the primitive int to Integer.

Now, after we know how to add elements and read it back from the map. Let iterate the contents of the map. A map will have two collections that you can iterate, the keys and the values. The code snippet below will demonstrate it for you. The first snippet show you how the iterate the map using the key collections while the second iterates the values of the map.

Iterate key collections.

Iterator keyIterator = map.keySet().iterator();
while (keyIterator.hasNext()) {
    Integer key = keyIterator.next();
    String value = map.get(key);
    System.out.println("key = " + key + "; value = " + value);
}

When iterating a map using the key collection you will get the key set of the map and check the hasNext() to see if it has next key. After that you can get the key using the next() method. To get the value you call the get() method and pass the key as the argument.

Iterates value collections.

Iterator valueIterator = map.values().iterator();
while(valueIterator.hasNext()) {
    System.out.println("value = " + valueIterator.next());
}

If you want to iterate the value and ignoring the keys you can get the value collections from the map. To validate if it still holds more entries you call the hasNext() method. To obtain the value simply call the next() method from the iterator.

Notice that when using generic you don’t need to do any casting when working with generic map. Everything is added to map and read from the map is according the type of the key and the value of the map. Beside using the Iterator you can also use the for-each loop to iterate the map. Here are the version of the code above written using the for-each loop.

for (Integer key : map.keySet()) {
    String value = map.get(key);
    System.out.println("key = " + key + "; value = " + value);
}

for (String s : map.values()) {
    System.out.println("value = " + s);
}

You can choose either way that match your coding style. Both method of iterating the map object will produce the same result.

How do I create a generic Set?

In another post of Java Generics you have seen how to create a generic collection using List in this example you will learn how to make a generic Set. Making a Set generic means that we want it to only hold objects of the defined type. We can declare and instantiate a generic Set like the following code.

Set<String> colors = new HashSet<>();

We use the angle brackets to define the type. We need also to define the type in the instantiation part, but using the diamond operator remove the duplicate and Java will infer the type itself. This declaration and instantiation will give you a Set object that holds a reference to String objects. If you tried to ask it to hold other type of object such as Date or Integer you will get a compiled time error.

Set<String> colors = new HashSet<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");

//colors.add(new Date()); // Compile time error!

The code for adding items to a set is look the same with the old way we code. But again, one thing you will get here for free is that the compiler will check to see if you add the correct type to the Set. If we remove the remark on the last line from the snippet above we will get a compiled time error. Because we are trying to store a Date into a Set of type String.

Now, let see how we can iterate the contents of the Set. First we’ll do it using the Iterator. And here is the code snippet.

Iterator iterator = colors.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

When using a generic Set it will know that the iterator.next() will return a type of String so that you don’t have use the cast operator. Which of course will make you code looks cleaner and more readable. We can also using the for-each loop when iterating the Set as can be seen in the following example.

for (String color : colors) {
    System.out.println(color);
}