Default and static methods in interfaces in Java 8

Before Java 8 interfaces could only contain static fields (usually simple constants) and abstract methods. Java 8 provided the ability to define concrete (default and static) methods in interfaces. This new language feature is used extensively in Java core packages.

Static methods

Static method in interface looks the same like in a normal class:

public interface Checker {
    ...
    public static boolean isNull(Object obj) {
        return obj == null;
    }
    ...

The main reason to add static methods to interfaces is to keep related utility methods in one place so that they can be easily used by subclasses, default methods in subinterfaces or by users of this interface.

Default methods

Default method looks like a typical class method but is defined inside an interface and contains default specifier. Let’s look at Collection.removeIf() default method:

default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

Default method can access everything that is defined within this interface or is inherited by this interface, including:

  • reference to this
  • all abstract methods defined in this or super-interfaces
  • all default or static methods defined in this or super-interfaces
  • all static fields defined in this or super-interfaces

Default methods allow adding new functionality to existing interfaces without breaking all existing implementations – they preserve backwards compatibility. A class, that implements an interface with a default method, gets the default implementation from the interface but it can still override the default implementation.

Default and static methods in functional interfaces

The functional interface can contain multiple default and static methods and still be functional. In fact, default and static methods are not abstract and are not counted within the limit of exactly one abstract method. Here is an example:

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
    ....
    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }
    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(true, comparator);
    }
    ....

Extending interfaces which contain default methods

If we create a new interface which extends an interface which contains a default method, we have 3 possibilities:

  • Not mention the default method in the new interface. This way the new interface will inherit the default method from parent.
  • Override the default method by redefining it in the new interface and providing new method body. All subclasses and subinterfaces will use new definition of the default method.
  • Declare the default method as abstract in the new interface. This way the default method must be overridden in subclasses or subinterfaces of the new interface.

Default method ambiguity

Sometimes we may want to implement two interfaces which contain default methods with the same method signature (name, parameters, and so on):

public interface InterfaceOne { 
    default void doSomething() { 
        ...
    } 
}
public interface InterfaceTwo {
    default void doSomething() {
        ...
    }
}
public class MyClass implements InterfaceOne, InterfaceTwo  {
}

In this rare case the compilation will fail because Java compiler does not know which implementation of the default method it should choose for the class. To resolve this issue we have to explicitly redefine/redeclare the default method in the class. We have two possibilities here.

The first one is to simply override the default method in the class and provide new method body:

public class MyClass implements InterfaceOne, InterfaceTwo  {
    public void doSomething() {
        // some code
        InterfaceOne.super.doSomething();
    }
}

Please, note that we are not using default keyword anymore. We can also use following syntax:

InterfaceOne.super.doSomething();

to call default implementation from one of the implemented interfaces.

Alternatively, we can declare the default method in the class as abstract:

public abstract class MyClass implements InterfaceOne, InterfaceTwo  {
        public abstract void doSomething();
    }

As a result the class must be made abstract also. This way we can somehow “postpone” the problem because the concrete subclass will have to redefine this default method.

Conclusion

Many static and default methods have been added to existing interfaces since Java 8 to simplify their usage and promote code reuse. Some of these interfaces include: Iterator, Iterable, Comparator, Collection.

Advertisements
Posted in Java | Tagged | 1 Comment

Database schema creation in JPA using SQL scripts

Recent versions of JPA provide a feature to automatically create the database objects (like tables, sequences or indexes), load initial data into database on application deployment; and also remove them after the application is undeployed.

All that is needed is to define several properties in persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="mainPU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/orcl</jta-data-source>
    <class>com.example.periodictable.Element</class>
    <class>com.example.periodictable.ElementCategory</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
      <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
      
      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
      <property name="javax.persistence.schema-generation.create-source" value="script"/>
      <property name="javax.persistence.schema-generation.create-script-source" value="dbscripts/create.sql"/>
      <property name="javax.persistence.schema-generation.drop-source" value="script"/>
      <property name="javax.persistence.schema-generation.drop-script-source" value="dbscripts/drop.sql"/>
      <property name="javax.persistence.sql-load-script-source" value="dbscripts/load.sql"/>
      
      <property name="hibernate.hbm2ddl.import_files_sql_extractor" value="org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor" />
      <property name="hibernate.show_sql" value="true"/>

    </properties>
  </persistence-unit>
</persistence>

Property javax.persistence.schema-generation.database.action defines which action should be taken on database when the application is deployed:

  • none – Takes no action on database. Nothing will be created or dropped.
  • create – JPA provider will create the database schema on application deployment.
  • drop – JPA provider will drop the database schema on application deployment.
  • drop-and-create – JPA provider will first drop the old database schema and then will create the database schema on application deployment.

If property javax.persistence.schema-generation.database.action is not specified, then none is assumed by default. In practice drop-and-create is very useful in simple, test applications and none in real production applications in which the database schema is created elsewhere.

Property javax.persistence.schema-generation.create-source informs JPA provider what should be used as a source of database schema:

  • metadata – JPA provider will use entity metadata (e.g. annotations) to generate the database schema. This is the default.
  • script – JPA provider will run provided SQL script to create database schema. The script should create tables, indexes, sequences and other necessary database artifacts.
  • metadata-then-script – The combination of metadata and then script in that order.
  • script-then-metadata – The combination of script and then metadata in that order.

Finally, property javax.persistence.schema-generation.create-script-source specifies the location of SQL script to run on application deployment. The location can be a file URL but usually is a relative path to the SQL script packaged into application JAR/WAR.

Properties javax.persistence.schema-generation.drop-source and javax.persistence.schema-generation.drop-script-source have similar values and meaning as their create* counterparts but of course these are used to drop database schema.

There is also one additional property javax.persistence.sql-load-script-source which can be used to load the initial data into the database tables. This SQL script is run after the database schema was created.

Hibernate

Hibernate requires (by default) that the SQL script contains maximum one line per statement. In short it means that the SQL statement cannot be split into multiple lines for better readability which is a common thing for CREATE TABLE commands. This inconvenience can be resolved by specifying following Hibernate specific property:

<property name="hibernate.hbm2ddl.import_files_sql_extractor" value="org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor" />

Conclusion

The above properties are very useful for simple, test applications which does not require the database data to survive the application undeployment. In production applications property javax.persistence.schema-generation.database.action should be set to none to prevent the loss data from the database in case the application is temporarily undeployed.

The sample application using these properties is available at

Posted in Hibernate, Java, Java EE, JPA | Tagged , , , | Leave a comment

Reading text file line by line in Java

Reading text files from hard disk is quite common task in software development practice. Usually we are interested in processing it line by line. In this article I would like to present few popular ways how to do it easily using Java IO.

Reading whole file into memory

Reading a text file can be as simple as calling single Files.readAllLines() method:

Path path = Paths.get(fileName);
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
for (String line : lines) {
   System.out.println(line);
}

This method reads the whole file with given path and stores all its lines into an array of String. The rest of the code just prepares the path and prints the read lines.

While it may seem like a perfect method, it has one significant drawback. If the file being read is large, the created array will be very long. As a result memory usage of the application and the whole JVM will grow significantly which can reduce the performance of the application or in worse case kill the application with infamous OutOfMemoryError.

Therefore, usage of this method must be done with care and only in cases where the input file is small.

Reading file using BufferedReader

If you are going to read large file, you can resort to using BufferedReader class:

try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
    while (true) {
        String line = reader.readLine();
        if (line == null) {
           break;
        }
    System.out.println(line);
    }
}

First, we are creating a FileReader instance to access the given file. Because FileReader provides only very basic set of operations, we are wrapping it inside BufferedReader which has more convenient and richer interface. Finally, we call BufferedReader.readLine() method to read each line separately as long as this method returns non-null. Try-with-resources block ensures that the file is always closed at the end.

If using Java 7 or later, creation of BufferedReader can be simplified using Files class:

Path path = Paths.get(fileName);
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
    while (true) {
        String line = reader.readLine();
        if (line == null) {
           break;
        }
    System.out.println(line);
    }
}

Reading file using Java 8 streams

Java 8 brought new streams feature into the standard library. The Files class was also extended with new Files.lines() method which opens the file with given path and creates a stream with all the lines of the file. Then the stream of lines can be processed as any other stream of String including filter, map/transform and aggregate operations. In our case we print the lines only:

Path path = Paths.get(fileName);
try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) {
    lines.forEachOrdered(System.out::println);
}

This method has the advantage over the first presented method because the file is not read into memory at once but lazily.

Conclusion

Usage of BufferedReader is the most popular and versatile method to read a text file. If you are sure that the file is small, you can use Files.readAllLines() method to simplify the source code. The last method utilizing the streams API is very promising but requires Java 8 runtime environment which is still not an option in many cases (e.g. legacy systems, compatibility, long-running projects).

As always the source code of the example is available at GitHub.

Posted in Java | Tagged , | Leave a comment

Iterating through Java list backwards

The most natural method of iterating through a list in Java is to start from the first element of the list and then move forward until the last one is reached. While this is the most common, it is sometimes necessary to do it otherwise – start from the last element and move in reverse direction. In this post I would like to show 4 different ways to do it easily.

This short class creates a simple list and calls 4 methods to print it in reverse order:

package com.example.iteratelistreverse;

import com.google.common.collect.Lists;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.commons.collections.iterators.ReverseListIterator;

public class Main {

    public static void main(String[] args) throws IOException {
        List<String> list = new ArrayList<>();
        list.add("First");
        list.add("Second");
        list.add("Third");
        list.add("Fourth");
        list.add("Fifth");

        iterateIndexedAccess(list);
        iterateListIterator(list);
        iterateReverseListIterator(list);
        iterateListsReverse(list);
    }

    private static void iterateIndexedAccess(List<String> list) {
        System.out.print("\nFor loop with random access:\n");
        for (int i = list.size() - 1; i >= 0; i--) {
            System.out.println(list.get(i));
        }
    }

    private static void iterateListIterator(List<String> list) {
        System.out.print("\nList iterator:\n");
        ListIterator<String> it = list.listIterator(list.size());
        while (it.hasPrevious()) {
            System.out.println(it.previous());
        }
    }

    private static void iterateReverseListIterator(List<String> list) {
        System.out.print("\nApache ReverseListIterator:\n");
        Iterator<String> it = new ReverseListIterator(list);
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

    private static void iterateListsReverse(List<String> list) {
        System.out.print("\nGuava List.reverse:\n");
        for (String v : Lists.reverse(list)) {
            System.out.println(v);
        }
    }

}

Method iterateIndexedAccess() shows the most common solution. In this method we are using the indexed access to the elements of the list which is very easy and obvious. It has also very good performance assuming that the instance of the list supports fast random access. It is the case for very popular ArrayList class.

However, other classes may not support fast random access. One of the examples is LinkedList class. For every List.get() method call this class has to iterate from the beginning (or alternatively from the end) of the list to find the element at given index which makes it very slow for large lists.

Method iterateListIterator() overcomes this problem by using a list iterator which can move forward and backward using ListIterator.next() and ListIterator.previous() calls respectively. In our example we are starting from the position after the last element and are moving to the previous element on every loop iteration.

Method iterateReverseListIterator() is quite specific because it creates an iterator which pretends that it is normal iterator (forward iterator). In fact it starts from the last element of the list and moves to the previous one on every call to Iterator.next() method. This solution uses ReverseListIterator class from Apache Commons library.

The last way uses method Lists.reverse() from Guava library to create a reversed view of the given list. Once we have the view, which is in fact instance of Iterable interface, we can go over it using enhanced loop.

As usual you can find the source code of this example at GitHub.

Posted in Guava, Java | Tagged , | 1 Comment

Usage of serialVersionUID in Java serialization

Java run-time associates with each serializable class a special version number known as serialVersionUID. This number is later used during deserialization process to verify if the application which performed the serialization and the application which is doing the deserialization have loaded and use compatible Java classes (with respect to serialization). If the receiver has loaded a class which has the same name but different serialVersionUID, the Java run-time will report a problem by throwing an exception of type InvalidClassException.

Generally speaking this kind of mechanism allows us to detect and report any compatibility problems during deserialization process as early as possible. If this check was missing, the deserialization process would likely finish without raising any exception but the created object would contain invalid data. This can easily lead to unpredictable behavior and can later cause errors which root cause is hard to track.

Defining serialVersionUID

A serializable class can specify its own serialVersionUID value explicitly by declaring a static, final field of name serialVersionUID and of type long:

private static final long serialVersionUID = 4038305141805077716L;

The access modifier does not really matter but private is commonly used.

If serial version is not explicitly declared, it will be automatically generated by compiler and stored in the class file. The compiler calculates default serialVersionUID value based on several aspects of the class like its name, its all public and protected members and so on.

The default serialVersionUID calculation may vary between compilers so it may give different results in different environments. To ensure a consistent serialVersionUID value, it is strongly recommended to explicitly declare its value.

Many IDE for Java have a feature which detects if the class should declare serialVersionUID and can report it as a warning. In case of the Eclipse the warning is following:

The serializable class Person does not declare a static final serialVersionUID field of type long

Adding serialVersionUID to existing classes

If you create a new class, you can choose any arbitrary value for its serialVersionUID because there are no serialized objects of this class yet stored anywhere.

However, if you already have an old class to which you would like to add explicit serial version value, you have be careful. The best idea is to choose a value which would be automatically generated by the compiler.

Oracle JDK provides a program serialver which shows the following basic window when started with -show option from command line:
serialver
When you enter a full name of the existing class and click Show button, it will output its default generated serialVersionUID below. You can just copy-paste this line into Java class file.

Additionally, Eclipse provides a nice context tool which can simplify adding serialVersionUID:

serialver-eclipse

Managing explicit serialVersionUID

The serialVersionUID represents a class version and has to be managed. If you make a change to the existing class which makes it incompatible with the previous version (e.g. changing base class, modifying the types of the fields or removing fields), it is also necessary to modify (e.g. increment) its serialVersionUID value.

On the other hand, adding new fields to the class does not necessarily make it incompatible. Additionally, you may manage to keep the class backward compatible by customizing serialization procedure using readObject() and writeObject() methods.

Example

Let’s consider a simple application serializing and deserializing objects of Person class:

package com.example.serialversionuid;

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 4038305141805077716L;
	
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Person{" + "firstName=" + firstName + ", lastName=" + lastName + '}';
    }
    
}

with the main class:

package com.example.serialversionuid;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Main {
    
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        if (args.length != 2) {
            System.err.println("Usage: serialversionuid read|write FILE");
            return;
        }
        final String operation = args[0];
        final String file = args[1];
        
        
        if (operation.equals("read")) {
            try (ObjectInputStream is = new ObjectInputStream(new FileInputStream(file))) {
                Person person = (Person) is.readObject();
                System.out.println("Read person: " + person);
            }
        } else if (operation.equals("write")) {
            Person person = new Person("James", "Bond");
            try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file))) {
                os.writeObject(person);
            }
        }
    }
    
}

When the serialVersionUID is unchanged we can serialize and deserialize objects of Person class without problems:

$ java -jar serialversionuid-1.0-SNAPSHOT.jar write data.ser
$ java -jar serialversionuid-1.0-SNAPSHOT.jar read data.ser
Read person: Person{firstName=James, lastName=Bond}

However, if you change serialVersionUID in Person class, rebuild the jar file and try to read data.ser file again, the InvalidClassException exception appears:

$ java -jar serialversionuid-1.0-SNAPSHOT.jar read data.ser
Exception in thread "main" java.io.InvalidClassException: com.example.serialversionuid.Person; local class incompatible: stream classdesc serialVersionUID = 4038305141805077716, local class serialVersionUID = 4038305141805077717
        at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
        at com.example.serialversionuid.Main.main(Main.java:22)

As you can easily notice, the Java run-time reports incompatibility between classes used to serialize data and deserialize it later.

Conclusion

Field serialVersionUID is often forgotten and ignored. In most cases not declaring it does not cause any problems. However, if your application exchanges serialized objects over network with another applications or stores serialized data on disk for long time, the importance of proper management of serialVersionUID becomes crucial.

The source code for the example is available at GitHub.

Posted in Java | Tagged | Leave a comment

Creating executable jar file with Maven

Building an executable jar file with maven-jar-plugin is fairly easy. However, it has one disadvantage that the Maven dependencies are not packaged together inside the resulting jar file but have to be stored separately on the file system and added to the class path. Often it is not an issue but sometimes you may want to create a single self-contained jar file which does not depend on anything external. Below you can find an example how to do it.

Consider we have a very simple application with main method:

package com.example.runnablejar;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.codec.digest.DigestUtils;

public class Main {
    
    public static void main(String[] args) throws IOException  {
        if (args.length == 0) {
            System.err.println("Usage: cryptohash file1 ...");
            return;
        }
        
        for (String arg : args) {
            Path file = Paths.get(arg);
            calculateSha256CommonsIO2(file);
        }
    }
        
    private static void calculateSha256CommonsIO2(Path path) throws IOException {
        try (InputStream is = Files.newInputStream(path)) {
            String hashString = DigestUtils.sha256Hex(is);
            System.out.printf("SHA256(%s) = %s%n", path, hashString);
        }
    }

}

This application uses Apache Commons Codec library which is distributed as a separate jar file. Storing this jar file inside our application jar file would not work because it would not be present on the class path.

To overcome this issue we can use maven-assembly-plugin in POM file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>runnablejar</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>runnablejar</name>

    <build>
        <plugins>      
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>           
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.5.2</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <appendAssemblyId>false</appendAssemblyId>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                            <archive>
                                <manifest>
                                    <mainClass>com.example.runnablejar.Main</mainClass>
                                </manifest>
                            </archive>
                        </configuration>
                    </execution>
                </executions>
            </plugin>        
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
            <type>jar</type>
        </dependency>
    </dependencies>
</project>

Looking from the high level perspective the Apache Commons Codec jar will be merged together with our application jar and the new MANIFEST.MF file will be added:

$ jar tf runnablejar-1.0-SNAPSHOT.jar 
META-INF/
META-INF/MANIFEST.MF
(...)
org/apache/commons/codec/digest/DigestUtils.class
(...)
com/
com/example/
com/example/runnablejar/
com/example/runnablejar/Main.class
(...)

The final application can be run using following command:

$ java -jar runnablejar-1.0-SNAPSHOT.jar

without manually downloading any dependencies and without configuring class path.

As usual you can find the source code of the example at GitHub.

Posted in Java, Maven | Tagged , | 4 Comments

Customizing HTML file input style

Styling an HTML file input control is very cumbersome and the number of available options is quite limited. Moreover, each web browser renders this control differently which makes it difficult to have consistent view of the application between browsers. Here is how the HTML file input looks in Mozilla Firefox:
file-input-img0

In most cases it is impossible to style the HTML file input control with CSS to obtain the wanted results. One of the easiest ways to overcome this issue is to place the HTML file input control visually on top of the other element (e.g. image or button) and make the HTML file input control transparent by setting opacity to zero. Because the HTML file input is on top, it will receive the click event and will open the dialog for choosing the file.

No JavaScript code is necessary, only HTML:

<div class="file-input-container">
   <div>Upload</div>
   <input id="file-input1" type="file"></input>
</div>

and a bit of CSS:

.file-input-container {
  position: relative;
  width: 10em;
  height: 2em;
 
  background: #8ac007;
  border: 2px solid black;
}

.file-input-container > div {
  text-align: center;
  margin-top: 0.5em;
}

.file-input-container > input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
   
  filter: alpha(opacity=0);
  opacity: 0;
}

After the change the button for choosing the file will look more or less like this:
file-input-img1

The provided example is easy to tune. For example you can completely remove child div element and set the background CSS property on parent div.

Posted in HTML | Tagged , | 1 Comment