Search This Blog

Loading...

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.


Saturday, June 9, 2012

JavaOne2012: My Java SE7 NIO.2 JavaOne 2012 sessions


The following JavaOne 2012 sessions has been accepted:

Session ID: CON2718
Session Title: The Power of Java 7 NIO.2
Venue / Room: Hilton San Francisco - Golden Gate 3/4/5
Date and Time: 1/10/2012, 15:00 - 16:00

Session ID: HOL2846
Session Title: The Power of Java 7 NIO.2 by Example
Venue / Room: Hilton San Francisco - Franciscan A/B/C/D
Date and Time: 1/10/2012, 16:30 - 18:30

So enroll soon to the session(s) and see you in San Francisco!

My session @ #JavaOne CON2718 and HOL2846 are full.


Wednesday, June 6, 2012

ADF: How to use an af:popup during long running tasks?

For long-running tasks in your application, a pop-up message window can be raised to alert the users that the specific task may take a while.

This can be accomplished using a combination of ADF Faces components (af:popup and af:dialog) and some JavaScript code.

In this recipe, we will initiate a long-running task in a managed bean, and raise a pop-up for the duration of the task to alert us to the fact that this operation may take a while. We will hide the pop-up once the task completes.

Getting ready
----------------
You will need to create a skeleton Fusion Web Application (ADF) workspace before you proceed with this recipe.

How to do it
--------------

  1. Create a new JSF page called longRunningTask.jsf based on any of the quick start layouts.

  2. Drop a Button (af:commandButton) component from the Component Palette to the page.
    You may need to surround the button with an af:toolbar component. Using the Property Inspector, change the button's Text property to Long Running Task and set its PartialSubmit property to true.

  3. Create an action listener for the button by selecting Edit… from the Property Menu next to the ActionListener property in the Property Inspector. Create a new managed bean called LongRunningTaskBean and a new method called longRunningTask.

  4. Edit the LongRunningTaskBean Java class and add the following code to the longRunningTask() method:

  5. Return to the longRunningTask.jsf page editor. Right-click on the af:commandButton in the Structure window and select Insert Inside af:commandButton | ADF Faces….

    From the Insert ADF Faces Item dialog, select Client Listener. In the Insert Client Listener dialog, enter longRunningTask for the Method field and select action for the Type field.

  6. Add an af:resource to the af:document tag.
    Make sure that the af:resource type attribute is set to javascript and add the following JavaScript code inside it:

  7. Finally, add a Popup (af:popup) ADF Faces component to the page with an embedded Dialog (af:dialog) component in it.
    Ensure that the pop-up identifier is set to longRunningPopup and that its ContentDelivery attribute is set to immediate.
    Also add an af:outputText component to the dialog with some text indicating a long running process.
    Your pop-up should look similar to the following:

Here is the complete code for the backing bean:

And jsf page:

How it works
--------------
In steps 1 and 2, we created a JSF page called longRunningTask.jsf and added a button component to it. When pressed, the button will initiate a long-running task through an action listener. The action listener is added to the button in steps 3 and 4. It is defined to a method called longRunningTask() in a managed bean. The implementation of longRunningTask() simply waits for 5 seconds (step 4). We have also ensured (in step 2) that the button component's partialSubmit property is set to true. This will enable us to call the clientListener method that is added in steps 5 and 6.

In steps 5 and 6, we defined a clientListener for the button component. The client listener is implemented by the longRunningTask() JavaScript method, added to the page in step 6. The longRunningTask() JavaScript method adds a busy state listener for the pop-up component (the pop-up itself is added to the page in step 7) by calling addBusyStateListener() and prevents any user input by calling preventUserInput() on the JavaScript event. The busy state listener is implemented by the JavaScript method busyStateListener(). In it, we hide the pop-up and remove the busy state listener once the event completes.

Finally, in step 7, we added the longRunningPopup pop-up to the page. The pop-up is raised by the busyStateListener() as long as the event is busy (for 5 seconds). We made sure that the pop-up's contentDelivery attribute was set to immediate to deliver the pop-up content immediately once the page is loaded.

To test the recipe, right-click on the longRunningTask.jsf page in the Application Navigator and select Run or Debug from the context menu. When you click on the button, the pop-up is raised for the duration of the long-running task (the action listener in the managed bean). The pop-up is hidden once the long-running task completes.



Saturday, June 2, 2012

JDK7: ProcessBuilder and how redirecting input and output from operating system's processes.

The java.lang.ProcessBuilder class has several new methods added into JDK7 that are useful for redirecting the input and output of external processes executed from a Java application. The nested ProcessBuilder.Redirect class has been introduced to provide these additional redirect capabilities.

To demonstrate this process, we are going to send command-line arguments from a text file to a DOS prompt and record the output in another text file.

Getting ready
----------------
In order to control input and output from external processes, you must:
  1. Create a new ProcessBuilder object.
  2. Direct the input and output of the process to the appropriate locations.
  3. Execute the process via the start method.

How to do it
---------------
1. First, create a new console application. Create three new file instances to represent the three files involved in our process execution: input, output, and errors as follows:

2. Create the file Commands.txt using the path specified for the file and enter the following text:
C:
dir
mkdir "Test Directory"
dir
3. Make sure that there is a carriage return after the last line.

4. Next, create a new instance of a ProcessBuilder, passing the string "cmd" to the constructor to specify the external process that we want to launch, which is the operating system command window. Call the redirectInput, redirectOutput, and redirectError methods with no arguments and print out the default locations:

5. Then we want to call the overloaded form of the previous methods, passing the respective file to each one. Once again, call the no argument form of each method executed using the toString method to verify that the IO sources have been changed:

6. Finally, call the start method to execute the process as follows:

7. Run the application. You should see output similar to the following:

8. Examine each of the text files. Your output file should have text similar to this:

9. Execute the program again and examine the contents of your error log. Because your test directory had already been created with the first process execution, you should now see the following error message:

How it works
---------------
We created three files to handle the input and output of our process. When we created the instance of the ProcessBuilder object, we specified the application to launch to be the command window. The information required to perform actions within the application was stored in our input file.

When we first called the redirectInput, redirectOutput, and redirectError methods, we did not pass any arguments. These methods all return a ProcessBuilder. Redirect object, which we printed. This object represents the default IO source, which in all three cases was Redirect.PIPE, one of the ProcessBuilder.Redirect.Type enumerations. A pipe takes the output of one source and sends it to another.

The second form of the methods that we used involved passing a java.io.File instance to the redirectInput, redirectOutput, and redirectError methods. These methods return a ProcessBuilder object as well, but they also have the function of setting the IO source. In our example, we then called the no argument form of each method once more to verify that the IO had been redirected.

The first time the program was executed, your error log should have been empty, assuming you used valid file paths for each File object, and you have write permissions on your computer. The second execution was intended to display how the capture of errors can be directed to a separate file.

If the redirectError method is not invoked, the errors will inherit the standard location and will be displayed in your IDE's output window. See the There's More... section for information about inheriting standard IO locations.

It is important to note that the start method must be called after the redirect methods. Starting the process before redirecting input or output will cause the process to disregard your redirects and the application will execute using the standard IO locations.

There's more
---------------
In this section, we will examine the use of the ProcessBuilder.Redirect class and the inheritIO method.

Using the ProcessBuilder.Redirect class

The ProcessBuilder.Redirect class provides another way to specify how the IO data is redirected. Using the previous example, add a new line prior to calling the start method:
pb.redirectError(Redirect.appendTo(errors));
This form of the redirectError method allows you to specify that the errors should be appended to the error log text file rather than overwritten. If you execute the application with this change, you will see two instances of the error when the process tries to create the Test Directory directory again:
A subdirectory or file Test Directory already exists.
A subdirectory or file Test Directory already exists.
This is an example of using the overloaded form of the redirectError method, passing a ProcessBuilder.Redirect object instead of a file. All three methods, redirectError, redirectInput, and redirectOutput, have this overloaded form.

The ProcessBuilder.Redirect class has two special values, namely, Redirect. PIPE and Redirect.INHERIT. Redirect.PIPE is the default way external process IO is handled, and simply means that the Java process will be connected to the external process via a pipe. The Redirect.INHERIT value means that the external process will have the same input or output location as the current Java process. You can also redirect the input or output of data using the Redirect.to and Redirect.from methods.

Using the inheritIO method to inherit the default IO locations

If you execute an external process from a Java application, you can set the location of the source and destination data to be the same as that of the current Java process. The ProcessBuilder class' inheritIO method is a convenient way to accomplish this. If you have a ProcessBuilder object pb, executing the following code:
pb.inheritIO()
Then it has the same effect as executing the following three statements together:
pb.redirectInput(Redirect.INHERIT)
pb.redirectOutput(Redirect.INHERIT)
pb.redirectError(Redirect.INHERIT)
In both cases, the input, output, and error data will be located in the same places as the current Java process' input, output, and error data.

References:
---------------
1.Class ProcessBuilder.
2.Java 7 New Features (by Richard M. Reese, Jennifer L. Reese)