Wednesday, May 25, 2016

Convert InputStream to String in Java

Sometimes in Java world it is necessary to convert an InputStream to a String for further processing. There are several ways to do it, but here is a fantastic trick I recently discovered in this article:
final String text = new Scanner(inputStream)
        .useDelimiter("\\A").next();
The idea behind this trick is regex \A. It matches the beginning of input. Since there is only one beginning of input the whole contents of the stream is returned as the first (and the last) token.

There is a problem with the code above. It would throw an exception if the provided stream is empty. However this is easy to fix:
final Scanner scanner = new Scanner(inputStream)
        .useDelimiter("\\A");
final String text = scanner.hasNext() ? scanner.next() : "";
If a specific charset must be used it could be passed as the second argument to the Scanner constructor:
final Scanner scanner = new Scanner(inputStream, "ISO-8859-1")
        .useDelimiter("\\A");
final String text = scanner.hasNext() ? scanner.next() : "";
That's all there is to it.
Thanks for reading!

Friday, April 22, 2016

Create a GUID in Java

Some software development tasks need a way to generate unique identifiers. I saw several homegrown solutions, but Java 5 makes the process a breeze. It contains class UUID which can generate type 4 (pseudo randomly generated) unique identifiers. Here is a simple example:
package net.softwaregeek;

import java.util.UUID;

public class UUIDMain {
    public static void main(final String[] args) {
        System.out.println(UUID.randomUUID());
    }
}
The code is self-explanatory. It generates a unique identifier and prints it to console. Class UUID contains several other useful methods which I encourage you to explore on your own.

Thursday, April 7, 2016

Change Editor for Git Commit Messages

Git is a very powerful tool especially when used from a console. Obviously committing changes is a pretty common task which includes editing commit messages. If a message is short it is easy to specify it via -m option:
$ git commit -m "my commit message"
But what if you have a long list of changes and you need a descriptive well-formatted commit message? It would be cool to write it in your favorite text editor, wouldn't it? Is there a way to tell Git which editor to use? Yes, it is. According to the docs for git-commit:

"The editor used to edit the commit log message will be chosen from the GIT_EDITOR environment variable, the core.editor configuration variable, the VISUAL environment variable, or the EDITOR environment variable (in that order)."

I'm a Vim fan and I stick to the core.editor configuration variable. So, here is my preferred way to configure commit message editor:
$ git config --global core.editor "vim"
Now I can omit -m option and enjoy editing commit messages in Vim :)

Wednesday, April 6, 2016

Rename a Remote Branch in Git

In the previous post I described how to rename a local branch in Git. Now let's take a look how to rename a remote branch. The process is a bit more complicated than with a local one and consists of the following steps:
  1. Create a new local auxiliary branch with the desired name.
  2. Push newly created local branch to the remote repository.
  3. Delete the original branch from the remote repository.
  4. Delete an auxiliary local branch (optional).
Let's take a look at a simple example. Suppose I have a Git repository which contains a couple of remote branches in it:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Suppose that branch release-v1.0 was created by mistake and I actually want it to be named release-v1.1. Let's perform the first step and create an auxiliary branch:
$ git branch release-v1.1 origin/release-v1.0
Let's see what we have locally and remotely:
$ git branch
* master
  release-v1.1
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Now it is time to push our new local branch to the remote repository:
$ git push origin release-v1.1
The above command creates a new remote branch named after the local one created on the previous step:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
  origin/release-v1.1
Let's delete the old remote branch:
$ git push origin :release-v1.0
Now we have the following remote branches:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Optionally we can get rid of the auxiliary local branch:
$ git branch -d release-v1.1
Let's take a look at the final result:
$ git branch
* master
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Here are all the commands in one place for convenience:
$ git branch release-v1.1 origin/release-v1.0
$ git push origin release-v1.1
$ git push origin :release-v1.0
$ git branch -d release-v1.1

Rename a Local Branch in Git

From time to time I have typos crept in the names of Git branches I create. Certainly it is possible to delete a branch and create a new one with corrected name. However Git allows for combining two steps into a single one. Here is a simple way to rename a local branch:
git branch -m <old-branch-name> <new-branch-name>
If a branch which should be renamed is the current one then the command above can be further simplified to the following:
git branch -m <new-branch-name>
If a branch named <new-branch-name> already exists -M option (which is actually just a shortcut for -m -f) can be used to force rename:
git branch -M <old-branch-name> <new-branch-name>
Type in the following command to get more information:
git help branch

Monday, April 4, 2016

How to Avoid Null Checks in Java

I suppose every Java developer wrote checks similar to the following many times:
if (obj != null) {
    // ...
    obj.doSomething();
    // ...
}
Sometimes such code seems reasonable and its usage can be justified. However more often than not there are better ways to code which allow for avoiding null checks altogether. In this article I want to present several helpful approaches which can make life of a Java developer easier in this regard. All of them use core Java only. Let's get started.

Using Assertions

Assertions were introduced in Java starting from version 1.4. However it looks like they are still underused. Here is an example which checks via assertions whether an argument belongs into required numerical range:
package net.softwaregeek;

public class Main {
    public static void main(final String[] args) {
        doSomething(-300);
        // ...
    }

    private static void doSomething(final int arg) {
        assert (arg > -100) && (arg < 100);
        // ...
    }
}
In the above example arg is out of range hence AssertionError will be thrown:
Exception in thread "main" java.lang.AssertionError
 at net.softwaregeek.Main.doSomething(Main.java:9)
 at net.softwaregeek.Main.main(Main.java:5)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
In order to add some details to the AssertionError a message can be attached to the assertion. It should be separated by colon from the assertion condition:
package net.softwaregeek;

public class Main {
    public static void main(final String[] args) {
        doSomething(-300);
        // ...
    }

    private static void doSomething(final int arg) {
        assert (arg > -100) && (arg < 100) : "arg is out of range";
        // ...
    }
}
This time stack trace contains descriptive error message:
Exception in thread "main" java.lang.AssertionError: arg is out of range
 at net.softwaregeek.Main.doSomething(Main.java:10)
 at net.softwaregeek.Main.main(Main.java:5)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Going back to null checks, the code similar to the following can be used to avoid them:
private void doSomething(final Date date) {
    assert (date != null) : "date cannot be null";
    // ...
}
Parentheses are optional, but in my opinion they improve readability by emphasizing the assertion condition, so I'll keep them.

The last but not the least: assertions are disabled by default. In order to enable them -ea option should be given to the JVM. Assertions can be enabled/disabled globally or per class/package. Take a look here for more information.

I intentionally used private methods in the above examples to emphasize an important point. Since assertions are disabled by default and can be selectively turned on/off it makes sense to use them for testing purposes or in private methods in the environments which you can control. In a production environment assertions can be disabled and they will be ignored by JVM. Hence they don't work well for checking invariants of public methods. More details on this can be found in Item 38 of Joshua Bloch's Effective Java book. Let's take a look at the next option.

Using Objects.requireNonNull()

A lot of improvements and enhancements were introduced in Java 7. One of them is Objects utility class. Among other goodies it contains methods that streamline null checks. Here they are:
public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}
As you can see the difference between the latter and the former is an error message which is passed to the exception constructor. So the code similar to the following can be used to make sure the object in question is not null:
public void doSomething(final Date date) {
    Objects.requireNonNull(date, "date cannot be null");
    // ...
}
Looks good, but we can do even better...

Using Optional Type

In Java 8 class Optional was introduced. The idea behind it is known for a long time in the functional programming world. An instance of Optional<T> is either a wrapper for an object of type T or for no object at all. Let's take a look at several usage examples:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        str.ifPresent(System.out::println);
    }
}
The above example demonstrates Optional#ifPresent method. It takes an implementation of Consumer interface and performs provided action if the Optional instance wraps an object.

If return value is needed then Optional#map method can be used. It takes a Function implementation and returns an Optional instance. Here is an example:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("   Hello World   "));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        Optional<String> trimmed = str.map(String::trim);
        trimmed.ifPresent(System.out::println);
    }
}
Another useful method is Optional#orElse. It returns wrapped object if it exists. Otherwise default value (passed as argument) is returned:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        System.out.println(str.orElse("default value"));
    }
}
Making a default value might take a lot of computational work. In this case it makes sense to delay default value computation until it is really needed. This can be done via Optional#orElseGet method. It takes a Supplier implementation as a parameter which will be invoked only in the case an instance of Optional doesn't wrap some object:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        System.out.println(str.orElseGet(() -> {
            double result = 0;
            // do some time-consuming calculation
            return String.valueOf(result);
        }));
    }
}
There are other helpful methods implemented in the Optional class. Take a look at documentation for complete details. One final note: make sure the code you write with Optional objects does not resemble the code with null checks:
private static void doSomething(final Optional<String> str) {
    if (str.isPresent()) {
        final String value = str.get();
        // do something with value
    }
}
The code above neglects the true power and beauty of Optional objects. Such coding patterns should be avoided.

Conclusion

The idea of null reference might rarely be in handy (e.g. when coding some low-level stuff in C), but most often it should be avoided. Tony Hoare - the inventor of null reference - said the following about it: "I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years."

I hope this article will help you to avoid a lot of billion-dollar mistakes :)

Thank you for reading!
Andrii

Monday, March 28, 2016

Create Web Application with Maven (Tomcat, WAR File)

This post is a step-by-step tutorial which shows how to create a simple Java webapp project using Maven - a popular Java build tool. The project will be packaged into a WAR file and deployed to a local Tomcat web server. The following technologies will be used:

  • Java 8 (1.8.0_66)
  • Tomcat 8 (8.0.32)
  • Apache Maven 3 (3.3.9)

This tutorial assumes that Java 8 and Apache Maven 3 have been already installed and properly configured. However, Tomcat 8 installation is discussed to a certain extent.

Generating Project Skeleton

The first thing we need to do is to create a web project from Maven template. This can be done with the following Maven command:
mvn archetype:generate -DgroupId={app-package} 
    -DartifactId={app-name} 
    -DarchetypeArtifactId=maven-archetype-webapp 
    -DinteractiveMode=false
Ok, now let's replace placeholders with some real values and generate a sample web project:
mvn archetype:generate -DgroupId=net.softwaregeek 
    -DartifactId=sample-web-app 
    -DarchetypeArtifactId=maven-archetype-webapp 
    -DinteractiveMode=false
If the command is executed successfully the following folder structure is created:
sample-web-app/
├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp
Maven enforces a certain project structure. I won't drill down into its details here. Please visit official guide to learn more about the Maven standard directory layout.

Installing Tomcat

Tomcat installation is an easy task. This section is included for completeness. If you have already configured a Tomcat instance feel free to skip to the next part.

As mentioned previously this tutorial leverages Tomcat 8.0.32. It can be downloaded from here. For Linux/OS X users I'd suggest using tar.gz archive. For Windows users a 32-bit or 64-bit zip archive probably works best. Choose the one appropriate for your system. When archive has been downloaded, unpack it to the folder of the name you like. Basically that's all. There are several configuration options available, but I won't discuss them as they are not relevant for this tutorial.

Tomcat requires either JAVA_HOME or JRE_HOME environment variable to be set in order to work properly. If you have JDK installed use the former one and set its value to the path where JDK resides. If you have only JRE use the latter one and set its value to the path of JRE installation. I assume you know how to set environment variables in your system, so I won't describe that process.

Let's verify our Tomcat installation. Throughout this tutorial I will use name $CATALINA_HOME to reference the folder where Tomcat was installed. In order to start the web server, open terminal application, navigate to the folder $CATALINA_HOME/bin and type in the following command:
./startup.sh
Windows users should leverage *.bat files and remove the prefix which explicitly references the current directory (./). So the command looks like this:
startup.bat
From now on I will use Bourne shell files (*.sh) because my development environment is based on OS X. Windows users, just keep the difference in mind and modify commands appropriately.

Now open a browser and type in the following in the address bar:
http://localhost:8080/
If everything went well you should see Tomcat management console. Congratulations! You have Tomcat instance up and running. In order to stop it, open terminal application, navigate to the folder $CATALINA_HOME/bin and type in the following command:
./shutdown.sh

Deploying to a Local Tomcat Instance

Now it is time to build our project and deploy it to the local Tomcat web server. Open terminal application, navigate to the sample-web-app folder (or whatever you named it) and type in the following command:
mvn package
If everything went fine, you should see a bunch of output, ending with something like this:
[INFO] ----------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------
[INFO] Total time: 0.905 s
[INFO] Finished at: 2016-03-22T17:14:41+02:00
[INFO] Final Memory: 12M/309M
[INFO] ----------------------------------------------------------------
Folder structure of the project now looks like the following:
sample-web-app/
├── pom.xml
├── src
│   └── main
│       ├── resources
│       └── webapp
│           ├── WEB-INF
│           │   └── web.xml
│           └── index.jsp
└── target
    ├── classes
    ├── maven-archiver
    │   └── pom.properties
    ├── sample-web-app
    │   ├── META-INF
    │   ├── WEB-INF
    │   │   ├── classes
    │   │   └── web.xml
    │   └── index.jsp
    └── sample-web-app.war
As you can see a directory named "target" is created by Maven. This is the place where Maven stores results of a build. There can be lots of files generated in the build process. The most interesting one is our web application archive (WAR file):
sample-web-app/target/sample-web-app.war
Let's take it and deploy to the previously configured local Tomcat instance. There are multiple ways to deploy a web application to the Tomcat web server. Here I will describe how to do it via web application manager. Start up your Tomcat web server, open a browser and navigate to the following page:
http://localhost:8080/
You should see a Tomcat management console:

Click "Manager App" button. An authentication pop-up window will be shown where you should type in login/password of a Tomcat administrator. If you are not sure where to get these values please read this post which explains the details.

After successful authentication Tomcat Web Application Manager should be opened:

Scroll down to the "WAR file to deploy" section and click "Choose file" button. In the appeared dialog select the WAR file which was created earlier as part of a build process. Finally click "Deploy" button. You might need to wait for a while. If everything went well you should see "sample-web-app" application listed in the "Applications" section with "Running" column value set to "true".

Now navigate to the following page to see "Hello World!" response from your application:
http://localhost:8080/sample-web-app/
Congratulations! You have "sample-web-app" application deployed to a local Tomcat web server! Now it is time to write some Java code.

Simple Servlet Example

Let's customize a little our web application by adding a simple servlet which handles GET requests and returns current date and time:
package net.softwaregeek;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@WebServlet("/datetime")
public class DateTimeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().println(new Date());
    }
}
Take the above code and save it in the following file:
sample-web-app/src/main/java/net/softwaregeek/DateTimeServlet.java
The code is simple enough, but let's take a brief look at it anyways. Annotation @WebServlet specifies a path to access our servlet. It is relative to the application context. In our case, application context is /sample-web-app, hence servlet will be accessible at /sample-web-app/datetime. In principal, servlets are not tied to the HTTP protocol, but HTTP servlets are the most widespread, so extending HttpServlet is a good option for DateTimeServlet class. By overriding doGet method servlet declares it will respond to GET requests. The body of the overridden method simply gets the current timestamp and returns it as the response.

In order to compile DateTimeServlet we need a dependency on Servlet API. Add the following lines to the pom.xml ("dependencies" section):
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
Now go to sample-web-app folder and build the project as you did earlier using the following Maven command:
mvn package
When deploying the project again as was described earlier to the same Tomcat instance you might get an error similar to the following:
FAIL - War file "sample-web-app.war" already exists on server
In order to fix this the previous version of the application should be undeployed first. Find sample-web-app in the "Applications" section and click "Undeploy" button in the corresponding row:

Now deploy fresh build of the sample-web-app application and navigate to the following path in your browser:
http://localhost:8080/sample-web-app/datetime
You should see a page with text similar to the following:
Mon Mar 28 14:56:24 EEST 2016
It means sample-web-app application is up and running. Also DateTimeServlet is deployed and returns current date and time as expected.

Conclusion

In this tutorial a simple web application was generated via Maven build tool. Then a local Tomcat instance was installed and the application was built and deployed to that instance. A simple HTTP servlet which responds to GET requests and returns current timestamp was developed in order to customize the application a little. This tutorial is very basic and I hope it will encourage your further exploration!

Thank you for reading!
Andrii