Saturday, June 23, 2012

JDK7: Part 1 - Java 7, The "Dolphin" new features & enhancements.

Java 7 was released in July of 2011 and introduced a number of new features. In the Java SDK documentation, you may see it referred to as Java 1.7, it streamline the development process and has a great and improved enhancements in many areas specially IO and concurrent processing.

In this article I will address a variety of topics involved in JDK 7 as new features and enhancements on two parts.

Part 1 will introduce the core language and JVM enhancements, IO operations from using paths for locating, managing the files & directories and getting there information. Also I will introduce the managing of the files Systems and finally streaming of new IO2.

Part 2 will cover the remaining topics including GUI enhancements and its event handling, Database, security and system enhancements. And finally the great enhancement and huge improvement had done in the threading and concurrency API.

Table of contents:

  1. Language Improvements.
  2. Using Paths to Locate Files and Directories.
  3. Obtaining File and Directory Information.
  4. Files and Directories Management.
  5. Managing Filesystems.
  6. Stream IO in Java 7.
  7. Graphical User Interface (GUI) Improvements.
  8. GUI events handling.
  9. Database, Security, and System Enhancements.
  10. Threading & concurrent processing.
  11. References.

1- Language Improvements.
----------------------------------

Java 7 was released in July of 2011 and introduced a number of new features. In the Java SDK documentation, you may see it referred to as Java 1.7. This topic will focus on those that have been grouped as part of the Project Coin (http://openjdk.java.net/projects/coin/).

Project Coin refers to the small language changes in Java 7 that are designed to make programs more readable by removing extra text when possible. The changes to the language do not involve modifying the Java Virtual Machine (JVM). These new features include:

  • The use of strings in switch statements.
  • The addition of binary literals and the ability to insert underscores into numeric literals
  • The use of a multi-catch block
  • The try-with-resources block
  • Improved type inferences using the diamond operator
  • Improvements in the use of methods with a variable number of arguments

Since the inception of Java, only integer values could be used to control a switch statement. Strings can now be used and can provide a more convenient technique for controlling the execution flow that is based on a string.

Underscores can now be used with literals to improve code readability. These can make a program more readable and maintainable. In addition, binary literals can now be used. Instead of using a hexadecimal literal, for example, the literal bit pattern can be used.

New to Java 7 are the improved try-catch block mechanisms. These include the ability to catch more than one exception from a single catch block, and improvements in how exceptions can be thrown.

Another improvement in exception handling involves the automatic closure of resources. In earlier versions of Java, when multiple resources were opened in a try block, it could be difficult to effectively close the resources, when an exception occurs. Java 7 provides a new technique in using the try-with-resources block to improve exception handling.

To take advantage of this technique, a class representing a resource must implement the new java.lang.AutoCloseable interface. This interface consists of a single method, close which, when implemented, should release resources as needed. Many core Java classes have been augmented to do this.

Java 7 provides the capability to re-throw exceptions in a flexible manner. It provides a more precise way of throwing exceptions, and more flexibility in how they can be handled in a try/catch bock.

When generics were introduced in Java 1.5, it became easier to write code to address a number of similar problems. However, its usage at times could become somewhat verbose. The introduction of the diamond operator has eased this burden.

When a method uses a variable number of generic arguments, sometimes an invalid warning is generated. The @SafeVarargs annotation has been introduced to flag a method as safe. This issue is related to heap pollution.


2- Using Paths to Locate Files and Directories.
--------------------------------------------------------

A filesystem is a way of organizing data on a computer. Normally, it consists of one or more top-level directories, each of which contains a hierarchy of files. The top-level directory is frequently referred to as the root. In addition, the filesystem is stored on a media, which is referred to as the file store.

Java 7 introduces a number of new classes and interfaces to make working with filesystems easier and more efficient. These have largely supplemented older classes found in the java.io package.

In this and subsequent topics, I will explain how a filesystem can be managed using the directory structure, as shown in the following diagram:


The ovals represent a directory/folder, while rectangles represent files. Unix-based systems and Windows systems differ in their support of a root node. Unix systems support a single root node, while Windows systems permit more than one root node. The location of a directory or file is described using a path. The elements, directories and files of the path are separated by either a forward or backward slash. In Unix, a forward slash is used. In Windows, a backward slash is used.

The music files were obtained from http://www.music.com/. The others.txt is intended to hold simple status information, while the users.txt is assumed to hold a list of users. The users.txt file in the music directory is a symbolic link to the actual file in the docs directory as reflected with the red line.

Symbolic links are more common in Unix-based platforms. To create a symbolic link for the users.txt file in the music directory, use the following command in the command console:

mklink users.txt c:\home\docs\users.txt. This requires administrator privileges to execute.

The management of paths as represented by the java.nio.file.Path class. A Path object is used extensively by classes in the java.nio package and is composed of several parts that are as follows:

  • A root which is the base of the path, such as a C drive.
  • A separator used to separate the names that make up directories and files of the path.
  • The names of the intermediate directories.
  • A terminal element, which can be a file or directory.

Also the following are the classes dealing with files and directories:

  • java.nio.file.Paths contains static methods for the creation of a Path object.
  • java.nio.file.Path interface contains numerous methods for working with paths.
  • java.nio.file.FileSystems is the primary class used to access a filesystem.
  • java.nio.file.FileSystem represents a filesystem, such as the /on a UNIX system or the C drive on a Windows platform.
  • java.nio.file.FileStore represents the actual storage device and provides device-specific information.
  • java.nio.file.attribute.FileStoreAttributeView provides access to file information.

To gain access to a file or directory, we will typically use the FileSystems class' getDefault method to retrieve a reference to the filesystem accessible by the JVM. To get access to a specific drive, we can use the getFileSystem method with a Uniform Resource Identifier (URI) object representing the drive or directory of interest.

The FileSystems class provides techniques to create or access a filesystem. FileSystems class supports the creation of Path objects. Once we have reference to a file system object, we can obtain a Path object using any one of several methods:

  • getPath: This uses a system-dependent path to obtain a Path object. The Path object is used to locate and access the file.
  • getPathMatcher: This creates a PathMatcher. It performs various matching type operations on a file.
  • getRootDirectories: This is used to obtain a list of root directories.

The creation and general use of Path objects is introduced in this topic, is used in subsequent recipes and other topics, so be sure to understand the basic processes.

You can still use the older java.io package elements. A path representing a java.io.File object can be created using the File class's toPath method. This is the Interoperability between java.io.File and java.nio.file.Files and can be useful when maintaining older code.

Paths can be either relative or absolute.

Paths can contain redundancies and extraneous elements. Removal of these elements is called normalization. This technique is available to simplify these types of paths.

Paths can be combined to form a new composite path. This is known as resolving a path. This technique can be useful for creating new paths, where parts of the path are available from different sources.

When a reference is needed for a file, that path is sometimes relative to the current location or some other location. The Creating a path between two locations is called relativizing.

Not only are there relative and absolute paths, but there are also other ways of representing a path such as with a java.net.URI object. When a Path object is created, it is not necessary that the actual path exists. For example, the Path may be created to create a new filesystem element.

Paths are system-dependent. That is, a path on one system such as UNIX is different from one found on a Windows system. Comparing two paths found on the same platform may or may not be the same.


3- Obtaining File and Directory Information.
------------------------------------------------------

Many applications need access to file and directory information. This information includes such attributes as whether the file can be executed or not, the size of the file, the owner of the file, and even its content type. In this topic, I will explain the various techniques available for obtaining information regarding a file or directory.

There are five general approaches to obtaining file and directory information using the java.nio.file.Files class that are as follows:

  • Obtaining a single attribute at a time using the Files class' specific methods, such as the isDirectory method.
  • Obtaining a single attribute at a time using the Files class' getAttribute method.
  • Returning a map of attributes using the readAttributes method using a String to specify which attributes to return.
  • Using the readAttributes method with a BasicFileAttributes derived class to return an attribute class for that set of attributes.
  • Using the getFileAttributes method to return a view that provides access to a specific set of attributes

Dynamic access to attributes is supported through several methods and allows the developer to specify an attribute using a String. The Files class' getAttribute method typifies this approach.


Java 7 introduces a number of interfaces that are based on a file view. A view is simply a way of organizing information about a file or directory. For example, the AclFileAttributeView provides methods related to the file's Access Control List (ACL). The FileAttributeView interface is the base interface for other interfaces that provide specific types of file information. Sub-interfaces found in the java.nio.file.attribute package include the following:

  • AclFileAttributeView: This is used to maintain the file's ACL and ownership attributes.
  • BasicFileAttributeView: This is used to access basic information about a file and to set time-related attributes.
  • DosFileAttributeView: This is designed to be used with the legacy Disk Operating System (DOS) file attributes.
  • FileOwnerAttributeView: This is used to maintain the ownership of a file.
  • PosixFileAttributeView: This supports Portable Operating System Interface (POSIX) attributes.
  • UserDefinedFileAttributeView: This supports user-defined attributes for a file The relationships between the views are shown as follows:


The readAttributes method's second parameter specifies the type of attributes to be returned. Three attribute interfaces are supported and their relationship is illustrated in the following figure. These interfaces provide a means of accessing their corresponding view interfaces:


4- Files and Directories Management.
----------------------------------------------

It is often necessary to perform file manipulations such as creating files, manipulating their attributes and contents, or removing them from the filesystem. The addition of the java.lang.object.Files class in Java 7 simplifies this process. This class relies heavily on the use of the new java.nio.file.Path interface, which is discussed in Using Paths to Locate Files and Directories topic. The methods of the class are all static in nature, and generally assign the actual file manipulation operations to the underlying filesystem.

 

Many of the operations described here are atomic in nature, such as those used to create and delete files or directories. Atomic operations will either execute successfully to completion or fail and result in an effective cancellation of the operation. During execution, they are not interrupted from the standpoint of a filesystem. Other concurrent file operations will not impact the operation.

 

There are basic file management methods required for the creation of files, creation of temporary files and and the creation of linked files using symbolic links. Also there are options available for copying, moving and deleting files and directories.

 

You can assign time attributes to a file. Related to this effort are other attributes, such as file ownership and permissions, managing ACL file permissions and Managing POSIX file permissions.


5- Managing Filesystems.
--------------------------------

A filesystem is one or more top-level root directories containing a hierarchy of files. A filesystem is supported by a file store that is the provider for the storage of the files. This topic is concerned with obtaining information about these entities and typical filesystem tasks, such as determining the contents of a directory or monitoring filesystem events.

 

A file store represents a unit of storage. For example, it might represent a device, such as a C drive, a partition of a drive, or a volume. The java.nio.file.FileStore class supports file stores and provides several methods to this end.

A filesystem supports access to a hierarchy of directories and files. It is represented in Java 7 with the java.nio.file.FileSystem class. This includes how to obtain a list of root directories for a filesystem and the underlying file stores.

 

Traversing a directory hierarchy is useful for many applications. The Using the SimpleFileVisitor class to traverse filesystems is the basic approach. This approach is used in the Deleting a directory using the SimpleFileVisitor class and Copying a directory using the SimpleFileVisitor class.

 

When an operation is restricted to a single directory, the java.nio.file.DirectoryStream interface provides a convenient technique for examining each element in the directory as a java.nio.file.Path object. It is very easy to use a for each loop to process these paths.

 

Sometimes we don't need the entire contents of a directory, but rather a subset of its elements. Java 7 provides a few approaches to filtering the contents of a using globbing and Writing your own directory filter. Globbing is a pattern-matching technique that is similar to regular expressions but is easier to use.

 

In the Monitoring file events using WatchEvents we see how Java 7 supports the detection of file creation, modification, and deletion within a directory by external processes. This can be very useful when it is necessary to know when changes to a directory are made.

 

With Java 7, it is now possible to treat the contents of a ZIP file as a filesystem. This makes it easier to manage the contents of a ZIP file and to manipulate the files contained within the ZIP file.


6- Stream IO in Java 7.
---------------------------------

In Java 7, I found that there are numerous improvements to its IO capabilities. Most of these are found in the java.nio package, which has been dubbed as NIO2. In this topic, we will focus on the new support for streaming and channel-based IO. A stream is a contiguous sequence of data. Stream IO acts on a single character at a time, while channel IO works with a buffer for each operation.

 

I start with the new techniques used to work with simple files. These are supported by the Files class and Buffered IO is usually more efficient to be used in reading and writing data.

 

The java.nio.channels package's ByteChannel interface is a channel that can read and write bytes. The SeekableByteChannel interface extends the ByteChannel interface to maintain a position within the channel. The position can be changed using seek type random IO operations.

 

Java 7 has added support for asynchronous channel functionality. The asynchronous nature of these operations is that they do not block. An asynchronous application can continue executing without the need to wait for an IO operation to complete. When the IO completes, a method of the application is called. There are four new java.nio.channels package asynchronous channel classes:

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousChannelGroup

The first two AsynchronousServerSocketChannel and AsynchronousSocketChannel are used together in a server/client environment to managing asynchronous communication using them.

 

The AsynchronousFileChannel class is used for file manipulation operations that need to be performed in an asynchronous manner, the methods supporting the write and read operations.

 

The AsynchronousChannelGroup class provides a means of grouping asynchronous channels together in order to share resources.

 

The java.nio.file package's SecureDirectoryStream class provides support for more secure access to directories. However, the underlying operating system must provide local support for this class.

 

When opening a file, some of these open methods that will use an enumeration argument to specify how the file should be opened. The java.nio.file package's OpenOption interface specifies how the file is opened and the StandardOpenOption enumeration implements this interface. The values of the enumeration are summarized in the following table:

 

Enumeration

Meaning

APPEND

Bytes are written to the end of the file

CREATE

Creates a new file if it does not exist

CREATE_NEW

Creates a new file only if the file does not exist

DELETE_ON_CLOSE

Deletes the file when it is closed

DSYNC

Every update to a file is written synchronously

READ

Open for read access

SPARSE

Sparse file

SYNC

Every update to the file or metadata is written synchronously

TRUNCATE_EXISTING

Truncates the length of a file to 0 when opening a file


The java.nio.channels package's NetworkChannel interface was introduced in Java 7. This represents a channel to a network socket. Several classes including the AsynchronousServerSocketChannel and AsynchronousSocketChannel classes that are discussed in this topic implement it. It has a bind method that binds a socket to a local address, allowing the retrieval and setting of various query socket options. It permits the use of operating system-specific options, which could be used for high performance servers.


The java.nio.channels package's MulticastChannel is also new to Java 7. It is used to support multicast operations for a group. It is implemented by the DatagramChannel class. Methods of this interface support the joining and leaving of members from a group.


The Sockets Direct Protocol (SDP) is a network protocol, which supports stream connections using InfiniBand (IB). The IB technology supports point-to-point bi-directional serial links between high-speed peripherals, such as disks. A significant part of IB is its ability to move data from the memory of one computer directly to the memory of another computer.


SDP is supported in Java 7 on Solaris and Linux operating systems. Several classes in the java.net and java.nio.channels packages support it transparently. However, SDP must be enabled before it can be used.


Details on how to enable IB and then create a SDP configuration file are found at http://download.oracle.com/javase/tutorial/sdp/sockets/index.html.


11- References.
------------------------
  1. http://docs.oracle.com/javase/tutorial/index.html.
  2. Java SE Technical Documentation
  3. Description of Java Conceptual Diagram.
  4. The Java Tutorial
  5. http://tamanmohamed.blogspot.com/2012/03/jdk7-part-1-power-of-java-7-nio2-jsr.html
  6. Java 7 Cookbook book.
  7. Java 7 Recipes a Problem-Solution Approach book.
  8. Beginning Java 7 book.
  9. The Java™ Language Specification (JLS) Java SE 7 Edition.
  10. The Java Virtual Machine Specification Java SE 7 Edition.

Finally thanks for reading, and we will meet in Part 2.


1 comment :

  1. Quite a comprehensive coverage, But I have seen some important API enhancement like new File API are lost in light of popular fork join framework or String with Switch enhancement. Thanks for bringing this.

    ReplyDelete