Dave Bristor's Sun Weblog
Monday Dec 11, 2006
Notable changes in the Java SE 6 Core Libraries
This blog summarizes notable changes to the core libraries in Java SE 6. Think of Java's "core libraries" as lang, io, util, and so on: the stuff of which all Java programs are comprised. For good measure, throw in jar, zip, regular expressions, concurrency, and reflection too.
There's lots more information about Java SE 6's features and compatibility with earlier releases. The platform overview describes the entire Java platform briefly, with links to more detailed guides. And of course, you can download the Java SE 6 release itself at java.sun.com.
Changes in I/O
Reading passwords without echoing their text
New to Java SE 6 is the ability to read text from a terminal without having it echo on the screen, throughjava.io.Console:
import java.io.Console;
...
char[] password = System.console().readPassword("password: ");
// use password
...
// clear password
java.util.Arrays.fill(password, '\0');
A few things are worth noting:
System.console()will return null if either standard input or standard output is not a terminal.readPassword()returns an array, so that you can null it out as shown.readPassword()uses the character set of the terminal device, which might not be that ofCharset.defaultCharset().
Display of the Critical Message Box
Chances are you've seen a dialog on Microsoft Windows presenting a critical message such as
Abort, Retry, Ignore
In the java.io.File class, any method which accesses removable media such as a floppy drive could cause a dialog with that message to appear. This could be a real problem if you're accessing the system remotely!
So we've changed the functionality here, so that by default for the JVM (including native code) and all processes it launches, the dialog doesn't appear. In a case like this:
new File("A:\\tmp.txt").exists();
if there's no floppy in the A: drive, exists() returns
false.
Interruptible I/O
What does this do?
public class Interrupt {
public static void main(String[] args) {
Thread.currentThread().interrupt();
System.out.format("Hello?");
}
}
Brownie points if you answered "it depends".
On Microsoft Windows and Linux operating systems,
it will print Hello?.
On the Solaris Operating System, it will hang.
That's because I/O is truly interruptible on Solaris only: once the interrupt
flag is set, you won't get anything written to stdout nor stderr.
Note that you can turn it off, by running java with
-XX:-UseVMInterruptibleIO.
This will be the default behavior in future releases of the JDK, for better cross-platform compatibility.
Finding out about disk space
We've added some new method tojava.io.File so you can find out how much disk space is available:
Note that the returned values are only estimates at the time of the call. They don't take into account any background I/O activity (by other processes, etc.)
A few notes are in order
-
getUsableSpace()takes quotas into account only on Microsoft Windows. - Each returns the result as a
long. The return values don't imply anything about access controls, i.e. the space might not be writable. - A return value of zero could mean that there's no space, or it could mean that the partition doesn't exist.
Changing access modes
In Java SE 6,java.io.File provides methods to change access of files:
Each returns true if the operation succeeded.
Microsoft Windows devices are no longer considered files
Prior to Java SE 6,File.isFile() returned true
for Microsoft Windows devices such as CON,
NUL, and LPT. Now it returns false.
File.toURL is now deprecated
Creating aURL from some files can result in an illegal URL. Consider a file named "%-2": really, those characters should be escaped. The correct way to do this is to use toURI() as a go-between:
URL u = File.toURI("%-2").toURL()
Long path names on Microsoft Windows
Java SE 6 supports long path names on Microsoft Windows. Each path name element is limited to 260 characters, which is the platform limitation.Other noteworthy changes to java.io.File
- 6348207: File.length() reports a length of 0 for special files such as pagefile.sys.
-
6198547: File.createNewFile() on an existing directory incorrectly throws IOException. Now it returns
falseon all platforms. - 6395581: File.listFiles() is unable to read nfs-mounted directory. Now it returns the correct results.
-
4809375: File.deleteOnExit() should be implemented with shutdown hooks.
Prior to Java SE 6, each invocation of
deleteOnExit()added the file to a list: in particular, a file could be added multiple times and during JVM shutdown, deletion was attempted for eachFilein the list. In Java SE 6, instead of a list,Fileobjects are added to aLinkedHashSet, guaranteeing that each is deleted only once.
Improved selector scalability on Linux
Linux 2.6 kernel providesepoll(4),
which is more scalable than poll(2).
The JDK detects the platform on which it is running,
and so for Linux 2.6 or later kernels, will use epoll(4)
in its
SelectorProvider.
This should scale well when there are thousands of selectable channels
registered with a selector.
Multiple locks on the same file
What does this code do?
public class FileLock {
public static void main(String[] args) throws Throwable {
new FileOutputStream("foo").getChannel().lock();
new FileOutputStream("foo").getChannel().lock();
}
}
Prior to Java SE 6, this code would deadlock on Microsoft Windows,
and return two locks
on Linux and Solaris.
Now, on all of those platforms, the second lock attempt throws an
OverlappingFileLockException, as should have been the case all along since the
behavior of
lock()
is specified that way.
Changes in collections
Performance improved in java.util.HashMap
We were able to improve the performance hashing function used byjava.util.HashMap by about 5%.
A side effect is that the order of the results returned by
iterating over
values()
has changed from the previous release.
Of course, as per the specification of
iterator(),
clients should not depend on the order from an iterator!
Performance improved in copying arrays
We've added new methods tojava.util.Arrays to copy arrays and
sub-arrays:
(The links above are to the int methods, but there are methods for
each primitve type as well as type-parameterized methods for objects.)
These methods efficiently resize, truncate, or copy subarrays of all types.
They simplify your code a bit too. Before Java SE 6, you might write:
int[] newarray = new int[oldArray.length];
System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
Now you can instead write this:
int[] newarray = Arrays.copyOf(oldArray, oldArray.length);
Not only is the code slightly simpler, but there's a performance benefit: The
old way created an array and initialized its values to zero,
then overwrite those zeroes with values from oldArray.
By providing a means to do this in one step, we avoid the zero
initialization.
Finally, the new methods will truncate or pad the new array as required.
Bidirectional navigable collections
We've added some new interfaces to enhance Maps and Sets: These extend their related Sorted classes with navigation methods reporting closest matches (e.g.higher) and allow for traversal in either
ascending or descending order.
We've retrofitted the related implementations
TreeMap,
TreeSet,
and added the new concurrent classes
ConcurrentSkipListMap, and
ConcurrentSkipListSet.
Double-Ended Queues
To theQueue
interface in Java SE 5, we added the
Deque
and
BlockingDeque
interfaces.
We updated
LinkedList to implement
Deque since it had everything needed to do so.
We also added new classes
ArrayDeque, which is an efficient implementation of
Deque,
and the concurrent implementation
LinkedBlockingDeque.
Changes in jar and zip
Timestamps on files extracted by jar
Prior to Java SE 6, the date and time of files extracted by thejar command were the current time.
Other de/compression tools use the time noted in the archive file itself. So
for Java SE 6, we changed jar to conform with other tools
if the old behavior is needed, run the JVM with
sun.tools.jar.useExtractionTime=true
Number of open ZIP files
We removed a limitation on the number of concurrently open ZIP files on Microsoft Windows. The maximum used to be 2036, but now it's whatever the platform will support.Number of entries in a ZIP file
The ZIP file format has a 2-byte field to record the number of entries in the file, artificially imposing a 64k limit. Our implementation now ignores that field, and instead just counts the entries. Prior to this change, you could count the entries withZipInputStream
or
ZipFile
, but get differing results if there were more than 64k entries in the
file.
Long Zip File Names on Microsoft Windows
We now use the same support for long file names in ZIP files as we use in the java.io package.Other changes
Support for plugable service providers
We've addedjava.util.ServiceLoader
as the standard way for clients to load plugable code.
It maintains a (clearable) cache of loaded services.
Array syntax checking
Final quiz: what does this do?
public class LoadArray {
public static void main(String[] args) throws Throwable {
String name = (new String[0]).getClass().getName();
LoadArray.class.getClassLoader().loadClass(name);
}
}
The key observations are that name is the name of an array class,
and that we're using the single-argument overload of
loadClass().
In earlier releases, this was allowed, but in Java SE 6,
throws a ClassNotFoundException.
It really is a bug:
loadClass() only works for binary names,
and the Java Language Specification, Third Edition, Chapter 13
defines binary names for classes and interfaces, not arrays.
Notable changes in Runtime.exec()
We had a number of bugs all related to attempts to predict whether an exec would succeed. In Java SE 6, we instead exec whatever is given, and communicate over a pipe with the exec'd process. If it fails for any reason, such as in these bugs, we can detect the failure:- 4052517: Runtime.exec won't execute programs belonging to other groups on Unix
- 4811767: Runtime.exec should throw IOException when workdir does not exist (Unix)
- 5033302: Can't execute Solaris NFS programs with uid>64k on Linux-amd64
Posted at 09:29AM Dec 11, 2006 by daveb in Sun | Comments[3]
How come this blog doesn't show up on http://planetjdk.org?
Dmitri
Posted by Dmitri Trembovetski on December 11, 2006 at 03:21 PM PST #
Posted by Bharath Ravi Kumar on December 11, 2006 at 11:18 PM PST #
Posted by Dave Bristor on December 12, 2006 at 09:37 AM PST #