Prepare yourself for what's new and different in the forthcoming JDK 1.2 release
Core Java continues to grow and grow, but you'll be ready for the new release -- with JavaWorld's detailed analysis of all the additions
Summary
The newest JDK release from Sun offers significant enhancements over
earlier versions. From the addition of the Java 2D API to performance
and stability enhancements to the pluggable VM architecture, John Zukowski's
detailed analysis of changes and additions will get you up and running with
JDK 1.2 in no time. (7,000 words)
By John Zukowski
oon,
Sun Microsystems will be releasing the FCS (first customer
ship) version of JDK 1.2 for Windows NT 4.0, Windows 95/98, and Sun
Solaris 2.5.1/2.6 for both Intel x86 and SPARC. This is the first
non-beta version of the 1.2 Java Development Kit (JDK) and Java
Runtime Environment (JRE). According to Gina Centoni, group manager
for the Java Platform at Sun, "the release is scheduled for the end
of November."
With this release of the JDK comes a slew of changes that should keep
Java technology developers, book authors, and trainers (not to mention
Java technology magazine authors and editors) busy upgrading our
knowledge sets, books, and training materials (and articles) for some
time to come. While some pieces of the new version (most notably Swing)
have been available for more than a year now, significant changes have
crept into the latest beta version of the software, 1.2 beta 4. We'll
bring you up to speed with these changes now, so you'll be ready to
make the most of them when JDK 1.2 hits the street.
And, if the hype is true, this is one package you'll want to be
prepared for. "JDK 1.2 is the most significant delivery of Java
technology thus far," Centoni says. "Based on customer feedback, it
provides a completed platform that includes essential features for
development of solutions in the Enterprise." According to Dr.Simon
Moores, president of The Java Forum, "The new 1.2 features represent an
evolutionary step from a cool programming language to a
serious preparatory technology, capable of supporting the wired
infrastructure of the early twenty-first century."
Centoni specified several key features that contribute to the merit of JDK 1.2:
- The addition of the Java 2D API
- Significant enhancements to the security model
- The pluggable VM architecture that will support the HotSpot VM
- Advancements to the Java Foundation Classes
- Enhancements designed to improve performance and stability
The changes offered in the 1.2 JDK fit into about four categories. We'll
look into each of these categories in some detail, demonstrate the
new capabilities, and prepare you to take advantage of them.
- Development and runtime environment changes
- Standard tool changes
- Standard library enhancements
- Standard library expansion
We'll also look at a number of non-Core Java packages, and point out
JDK 1.1/JDK 1.2 compatibility issues you should be aware of.
Development and runtime environment changes
Developers will run across the first set of changes quickly. The basic
environment configuration has changed. Most of the worry related to
modifying the CLASSPATH environment variable is gone, both
for development and runtime (end-user) environments. And you can
forget about the classes.zip file that stored all the Java
class files. That, too, is gone. The jre command also is
gone, as it was just an alternate way of starting something with
java .
CLASSPATH settings
What's this? No more setting of CLASSPATH ? No more
classes.zip file? Here's the scoop: With JDK 1.1, initial installation required
you to add the bin directory under the JDK installation directory to your PATH
environment variable. That isn't a problem and hasn't changed with JDK 1.2, assuming you
want the compiler and other tools in your path. It's the next step that's changed.
With JDK 1.1, if you wanted to expand upon the core set of libraries the JDK
had available to you at compile time or runtime, you had to worry about the
CLASSPATH environment variable. When unset, the default variable setting
contained the classes.zip file from the JDK distribution and
a period (.) to signify the current directory as the
location of class files. As long as you didn't need to add
packages of classes to your toolkit, you didn't need to make any
changes. But as soon as you needed to add one new location you had to set
the CLASSPATH and remember to include
the default settings. This caused much confusion, as you couldn't
simply append something to the old setting. Also, some people thought
they needed to unzip classes.zip, because that's
standard when you run across a zip file.
To help alleviate this confusion, Sun made two big changes.
- The system class files no longer are specified by the
CLASSPATH environment variable. Their
location is, instead, specified automatically by the runtime environment.
(Look up the sun.boot.class.path property or change it with
-Xbootclasspath:paths/files .)
- The system classes no longer reside in a zip file.
They're now in Java Archive (jar) files. The runtime classes are now found in the
file rt.jar in the jre/lib directory, while
the JDK-support tool classes are found in the tools.jar
file in the lib directory. The other two jar files that
ship with the JDK are the i18n.jar file, which includes
internationalization support classes (like in the
java.text.resources subpackage), and the
jaws.jar file, which includes some other support classes
(which provide capabilities including JavaScript integration with
Netscape's JSObject , plus JSException classes
and browser plug-in interoperability).
Extensions framework
While JDK 1.2 clears up the configuration of CLASSPATH for
the system classes, it also eliminates the need to add anything else
to the CLASSPATH . How this happens is based on the new Java
Extensions Framework, introduced with JDK 1.2. Just place a jar file
in the lib/ext directory, under the Java runtime directory
(specifically jre/lib/ext with the JRE), and you've just
installed the library. No more setting the CLASSPATH . If you
don't want to place classes in a jar file, you can place them
in the classes directory (also under the Java
runtime directory (specifically jre/classes), although it's
nonexistent by default).
The second part of the extension framework is for downloadable
extensions. If you wish to use a library within an applet, you can
place a special Class-Path: line in the manifest file of the
applet's jar file. This addition eliminates the need to either manage one huge
jar file for the applet or specify multiple jar files with an
<APPLET> tag. Such changes should make the support
staff's job much easier when your development efforts move to the
deliverable stage.
Of course, if you still want to, you can use CLASSPATH
for adding non-system libraries and specify multiple jar files with
the <APPLET> tag. It just isn't necessary.
Just-in-time compilation
To help speed up performance, Sun's JREs come with a just-in-time (JIT)
compiler for both Windows and Solaris. By default, each is enabled and
should speed performance considerably, depending on your application.
To disable the JIT, set the System property java.compiler
to NONE . (The -nojit option is no longer
valid.) Disabling allows you to see source code line numbers when an
unexpected exception is thrown. To find out which version of the JIT
compiler you're using, set the JAVA_COMPCMD environment
variable to FORCE_SIGNON .
Native threads in Solaris
Prior to JDK 1.2, Java technology users on multiprocessor Solaris boxes
couldn't take advantage of the multiple processors within a single Java program.
Now, with the addition of native-thread support, you can use either the original
(and still default) "green" threads or the newer native threads. Set your
threads choice with the command-line options -native and
-green or the environment variable THREADS_FLAG .
Deprecated thread methods
With the 1.2 JDK, several methods of the Thread and
ThreadGroup classes have become deprecated. This means they
should be avoided. (In fact, they should have been avoided starting
with the 1.0 JDK, but their use was sometimes necessary with
JDK 1.0 because interrupt() didn't function properly.)
The deprecated methods are stop() , suspend() , and
resume() in both classes, as well as
countStackFrames() in Thread and
allowThreadSuspension() in ThreadGroup .
The first three methods (stop() , suspend() , and
resume() ) should be avoided because they aren't safe.
They have a tendency to either leave objects in an improper state,
for example when stop() is called at a bad time, or leave a
system in a deadlocked state, for example when suspend() holds an
object with an unreleased lock. If you happen to be using these
methods now, Sun's online Java tutorial describes how best to update
your designs.
Other
In addition to the previously mentioned runtime environment changes,
developers (and users) will notice several areas of performance
enhancements for behind-the-scenes activities. Locks for
synchronization will occur much faster with monitor speedups, speed of
memory allocation and garbage collection has been improved, and loaded
classes will boast a smaller footprint (based on memory compression
due to the sharing of constant strings across class files).
According to Patrick Vermont, director of Apptivity product
management at Progress Software, "Anything and everything to improve
performance is critically important for Java adoption to continue.
Performance improvements from both the [pending] HotSpot compiler and
the new garbage collection algorithms are extremely welcome. It feels
like Sun is really investing in making 1.2 a solid platform. [This is]
important for Java to spread up into large organizations and to be used
for mission-critical applications."
One handy thing that may no longer be in place when JDK 1.2 is finally
released is support for the _JAVA_LAUNCHER_DEBUG environment
variable. When set, this causes your Java runtime
environment to generate numerous debug messages at startup, which is a big help
in the resolution of configuration problems.
Standard tool changes
Now that you've seen some of the basic environment changes and
performance improvements, let's start digging into real
development-related changes. In the area of tools, there are three
primary changes. These are related to the JDK 1.1 javakey ,
jar , and javadoc tools.
Security/signing tools
In the 1.1 JDK, all security-related code-signing tasks (including key
and certificate management) rely on the javakey tool. In the
1.2 JDK, this single overworked tool has been replaced by two, and a
third tool supports a new JDK 1.2 security capability. The upshot:
First, your key database from JDK 1.1 has been renamed keystore
and moved to the user's home directory, and the original file is no longer valid.
Second, the JDK 1.2 key database is now password protected. The basic process
of signing code remains the same, except you now use keytool
and jarsigner where just javakey was used before.
The third tool, policytool , actually has a graphical interface, unlike
almost all the other tools. The policytool supports JDK
1.2's new policy-based access-control capabilities. We'll talk about
these more below.
New jar command options
The familiar jar command, used to create jar
files, has two added command-line options. Many developers have been
eagerly awaiting the first option -- an update feature. The
-u option allows you to either add or replace files to a
pre-existing jar, so you no longer need to re-create the entire jar
file from scratch. For example, to update just the
Sugar.class file in the cookie.jar file, you would
enter the following command:
jar uf cookie.jar Sugar.class
The second new jar command option, -C , lets you change
directories as you're creating (or updating) a jar file. For
instance, if you want to jar files from three different
directories, you can either copy everything into one target
directory and jar everything, or leave everything where it is and jar
the pieces together, as shown here:
jar cf cookie.jar -C first first/*.class -C ../second second/*.class
-C ../third third/*.class
Doclets
The third tool seeing significant changes in the move to JDK 1.2 is
javadoc . The command still just generates API documentation.
The differences lie in the default output format and how it goes
about generating the output. First, the output no longer
contains images, so you don't have to constantly copy the
images subdirectory over from another set of output. Second,
if you don't like the output, you can create a program called a
doclet to reformat the output. This requires the use of the
com.sun.tools.doclets and com.sun.javadoc packages
to customize output. Once you've created your doclet , you use it with
the new -doclet option of javadoc . For instance,
you can automatically generate your own copy of Java in a
Nutshell-like appendices for any set of Java source files. Try
the sample doclet included in the Resources
section below. Be sure to run it from the root directory in which you unjarred
the src.jar file that comes with the JDK. Just compile the source and
execute the following command: javadoc -doclet SampleDoc java.net , (or
substitute whichever package you wish to document). An output sample for the
SampleDoc doclet is also included in the Resources.
Another javadoc change has to do with the directory structure
created for the output files. Instead of one huge directory of all
output files, the different packages are each placed in their own tree.
There are many other @ -commands added, too. See the
javadoc enhancement link in the Resources.
Standard library enhancements
Now that we've seen what's new and different with the various
tools, let's start looking at what's different with the existing
classes. There are at least 11 different areas where the
capabilities of the existing Core classes have changed.
Audio enhancements
First up is improved audio support, with no API changes. You can now
play several different audio file formats, in addition to the
familiar au files. With the help of a new sound engine in JDK 1.2,
you can also play audio file formats of aiff, wav, rmf, and midi, too.
This should reduce the need to convert Windows wav files to au
format just to play them within Java programs. Also, there is finally
support in the Core Java API for playing sound files in applications. No
more digging into the sun.audio package or creating a
meaningless AppletContext ; just call the new
newAudioClip() method of Applet to get an
AudioClip to play in an application.
File object enhancements
Developers will welcome the vast improvements to the File
class. With JDK 1.2, most of the routines that used to return String
objects to represent a filename (in JDK 1.1) will return another
File that you can more easily work with. For instance, you
can quickly sum up the size of the files in a directory with the following:
File aFile = new File (...);
long size=0;
File files[] = aFile.listFiles();
for (int i=0, n=files.length; i < n; i++)
size += files[i].length();
Previously, you had to make sure you properly created a File for
each filename returned from list() :
File aFile = new File (...);
long size=0;
String files[] = aFile.list();
for (int i=0, n=files.length; i < n; i++)
size += new File (aFile, files[i]).length();
The listFiles() method also accepts an optional
FileFilter besides the FilenameFilter of
list() . The two filters work the same, but the new
FileFilter works with a File object, instead
of the File and String of the
FilenameFilter .
You can also now use the File class to create temporary
files with createTempFile() and to create a simple
file-locking protocol with createNewFile() and
deleteOnExit() . In addition, you can easily convert a
File object to a URL with toURL() , find out if
an existing file is hidden with isHidden() , and make a
file read-only with setReadOnly() . Note that the
File class doesn't let you turn a read-only file into a
writable file.
Number decoding
Expected in the FCS JDK 1.2 release, but not currently in the beta 4
release, are two parsing methods missing from earlier JDK versions.
With methods like parseInt() in the Integer class
and parseByte() in the Byte class, it seemed
obvious to have parseFloat() and parseDouble()
methods in the Float and Double classes,
respectively. This omission should be corrected by the time JDK 1.2
is released, simplifying the procedure to something like:
float f = Float.parseFloat ("3.1415");
double d = Double.parseDouble ("2.718281");
Security/policies
The JDK 1.2 security enhancements are substantial. Steve Burnett, a
crypto engineer at RSA Data Security Inc., thinks the Java
Cryptography Architecture (JCA) 1.2 capabilities are a big
improvement over 1.1: "The JDK 1.1 JCA had some deficiencies, making
real-world applications using digital signatures difficult to write.
With the new JCA, there are no more missing pieces. In addition to
the cryptography, the new JCA offers certificate functionality. Many
cryptographic applications rely on digital certificates to facilitate
communication. Developers can call on the new cert library in the JCA
to perform much of the needed functionality."
Besides the previously mentioned changes to command-line tools, the
JDK 1.2 security architecture uses a permissions model for breaking
out of the Java sandbox. Now, whenever you need to do a privileged
operation, instead of signing code and enabling everything, you grant
individual fine-grained permissions for specific operations. You
use the policytool program to grant or refuse permissions
based on data, such as who signed a given class and where it's loaded
from. When it comes time to execute the privilege code block, the
new access controller consults the policy database to see if the
code has permissions.
In addition to the policy-based access control, JDK 1.2 includes
many cryptographic services that go beyond the
MessageDigest , Signature , and
KeyPairGenerator capabilities of JDK 1.1. These include an
X.509 version 3 implementation of a new Certificate interface,
as well as additional support for managing the KeyStore and key
factory support for converting between different key representations.
Besides the JCA, there's a Java Cryptography Extension (JCE)
available, which extends the 1.2 JDK to include more capabilities, like
encryption. However, due to US export restrictions, it's not
part of the JDK.
One interesting thing you can do in JDK 1.2 is set applications
to run with the same security manager as applets. Simply set the
java.security.manager System property from the
command line and everything goes through the access controller.
java -Djava.security.manager MyClass
JDBC 2.0
First introduced at JavaOne '98, the JDBC 2.0 API of JDK 1.2 greatly
expands on the earlier JDBC capabilities. Probably the most important
feature here is the ability to have true cursors when examining a
result set, allowing you to move forward and backward and modify
entries. The JDBC 2.0 API also is the first API to support the SQL3
datatypes to be adopted with the next SQL standard; these include
blobs (Binary Large Objects), clobs (Character Large Objects), and
user-defined datatypes (UDTs). Just remember not to mix up the
java.sql.Array class with java.lang.reflect.Array .
To take advantage of the JDBC 2.0 capabilities, you must get new JDBC
drivers. The older drivers will continue to work, but without the
more advanced capabilities. Speaking of drivers, there happens to be
an improved ODBC-JDBC driver with JDK 1.2, also.
Networking enhancements
As I reported in Java Tip 46: Use Java 1.2's
Authenticator class (JavaWorld, February 1998), the
networking classes have been improved to more easily support accessing
password-protected URLs. Previously, in order to access password-protected
URLs, you had to encode the Authorization property for the
URLConnection . This has gotten much easier in JDK 1.2.
The one change reported since February's Tip is a security-related modification.
In the early beta versions of JDK
1.2, a password was placed in a String object and then
passed along to the Authenticator . With the latest JDK 1.2
version, the password is now placed in a byte array. This allows you to
clear out the password immediately after using it, instead of having to
wait for the garbage collector to dispose of the password string.
Other new classes in the java.net package include the
following:
JarURLConnection class, which lets you access specific
files within jar files with URL strings like
jar:http://www.javaworld.com/aJar.jar!/filename.txt
URLDecoder class, which complements the existing
URLEncoder class
URLClassLoader , used for loading classes from URLs instead of files
Serialization enhancements/versioning
Serialization capabilities have evolved somewhat through the
different beta releases. Assuming the beta 4 capabilities live on with
the FCS version, the added functionality lets you customize
serialization at a much lower level than previously possible. The
magic happens within the two methods writeReplace() and
readResolve() , which work somewhat like
writeObject() and readObject() : if they exist they're
called; if not, the default behavior is invoked.
In addition, JDK 1.2 boasts a new serialization protocol. If you're
always serializing within one version of the JRE, this doesn't matter
to you. However, if you have different clients with different
versions of the JRE, things could get tricky. By default, JRE 1.2
writes with the new format, and JRE 1.1 environments write with the
old protocol. Starting with JRE 1.1.6, both protocols are readable in
JRE 1.1 environments. Also, both protocols are readable under JRE 1.2. If
you wish to set a version to use when writing in JRE 1.2, you
can call the ObjectOutputStream.useProtocolVersion() method.
Reflection enhancements
The improved JDK 1.2 reflection capabilities allow you to bypass
access control checks when -- and only when -- using reflected methods.
These allow capabilities like object persistence, debuggers, and
other privileged tasks. By default, this option is
disabled. You must specifically request that a class supports this,
and changing it requires a pass through the security access
controller, so untrusted beings cannot disable these capabilities
unless they become trusted. To enable this option, you call the
setAccessible() method of Field , Method ,
or Constructor , which is inherited from AccessibleObject .
AWT enhancements
User interface developers have focused on improvements offered by
Swing, but let's not overlook changes within AWT proper. The most
notable change relates to supporting internationalization efforts
with a new ComponentOrientation class. A side effect of
this class is the addition of new constants and behavior to the
BorderLayout and FlowLayout layout managers. This
affects programs only if left-to-right layout is inappropriate for
your application's locale.
Additional AWT-related changes include the following:
- A constant has been added to
KeyEvent to support the euro
(pan-European currency, to debut January '99)
- A constructor that initializes all settings has been added to
GridBagConstraints
to ease IDE development with GridBagLayout
- A
setState() method that allows you to programmatically iconify and
deiconify a frame has been added to Frame
JavaBeans enhancements
The JavaBeans enhancements in JDK 1.2 do not include Enterprise JavaBeans
(EJB). EJB is a separate architecture that is not part of JDK 1.2.
Sun defines 1.2 JavaBeans improvements as part of the Glasgow
specification; they still aren't finalized. The drag and drop
capabilities described below comprise one of the JavaBeans
enhancements. The other new key JavaBeans capabilities come from the
Runtime Containment and Services Protocol, which includes the
classes in the java.beans.beancontext package. With this
containment protocol, beans can more happily exist within other
beans, and they're enabled to glean information about their surrounding
environment. One thing that should be simplified is the
interrogation and employment of available services from an environment
(i.e., InfoBus). Also, you now
load support files not only through the ClassLoader , but with
the BeanContextSupport class, and JDK 1.2 provides better
support for initializing beans as applets through the
java.beans.AppletInitializer interface.
RMI enhancements
The 1.2 RMI enhancements are very handy. RMI with JDK
1.1 required the RMI server that generated the instance of the remote object
to be running. RMI in JDK 1.2 allows these remote
objects to be activated only when needed and suspended when not in use.
This may reduce the memory requirements of servers considerably, as
remote objects need only be active when necessary.
Standard library expansion
In addition to changes in existing libraries and classes, numerous new
capabilities have been added to JDK 1.2. This has caused the number
of standard packages shipping with JDK 1.2 to grow to more than 70
(versus the 23 packages in JDK 1.1).
Collections/sorting
The Core Java 1.2 packages finally add additional data structure
support to the Java libraries, beyond arrays, vectors, and hashtables.
Developers no longer have to look to ObjectSpace's Generic
Collection Library for Java as the source of data collection classes.
Sun's library represents a small, yet rich collection of about 25
classes that let you work easily with different groups of data, while
somewhat hiding the underlying data structure implementation. (All
the collection classes are found in the java.util package.)
By default, accessing any of the new collection data structures is
unsynchronized, unlike JDK 1.0 and 1.1. If you don't need
synchronized access, you don't have to use it. However, when you must
access something synchronized, you can do so easily with a call to a
method of the Collections class. And, you can even make a
collection read-only after you've stored everything in it, thus potentially
boosting performance and security.
In addition to providing new generic data structures, Sun added support
for performing tasks like sorting. You can now very easily sort an
array with one easy call:
Arrays.sort (anArray);
In order for array sorting to work, there is only one requirement:
the type of object in the array must implement the Comparable
interface. All the key system classes with a natural ordering,
like String , already implement the interface. For your own
classes, you can either have them implement the Comparable
interface, or you can define a separate class that acts as a
Comparator to define your own ordering. Providing your own
comparator works well when the default ordering is insufficient, i.e., for
case-insensitive sorting of strings:
class CaseInsensitiveSort implements Comparator {
public int compare (Object arg1, Object arg2) {
String lc1 = arg1.toString().toLowerCase();
String lc2 = arg2.toString().toLowerCase();
return lc1.compareTo (lc2);
}
}
Then, to sort the array, just use the following:
Arrays.sort (anArray, new CaseInsensitiveSort());
The above functionality already exists in the Comparator
stored in the String.CASE_INSENSITIVE_ORDER class variable.
JavaWorld contributor Dan Becker provides a detailed overview of the
Java Collections framework in his article
"Getting started with the
Java Collections framework" in this month's issue of JavaWorld.
Weak references
JDK 1.2 adds the concept of reference objects to the set of tools
developers can use to better manage memory. A reference object, or
weak reference, is a reference to an object in memory. It has one
catch though. The automatic garbage collector doesn't count this
reference as a reference to the object. Thus, that object can be
garbage-collected if no non-weak objects refer to it. The
WeakHashMap collections class, introduced in beta 4,
represents a hashtable where the keys are weak references. When the
system needs more memory, the map size may shrink at will, with no
notification to you. With phantom references, one type of weak
reference, you can even perform post-finalization cleanup,
after an object has been garbage collected. All this provides
you with more direct control over storage reclamation strategies.
CORBA
New in JDK 1.2 is an object request broker (ORB) to support
interoperability between the Common Object Request Broker
Architecture (CORBA) and a JRE, through Java IDL (Interface Definition
Language). CORBA is similar to RMI for distributed object
applications. But while RMI requires Java technology at both ends and
a wire in the middle, CORBA has no such restriction and works between
disparate computing languages and platforms. The CORBA support in JDK
1.2 makes future developments with Enterprise JavaBeans much easier,
as CORBA is the most likely candidate for communication between Java
environments and existing application services.
To use CORBA within a Java program, you create an IDL file that
defines the interfaces to use for communication, similar to RMI.
Then, after running this file through the idltojava command
(available separately from the JDK), you get a set of classes that
provide the stub and skeleton for communication. After defining your
specific implementation, you're off and running. It really is very
easy to use. And if you include CORBA services within an applet, you
can take advantage of the ORB that comes with Netscape Communicator.
One added command available to run your CORBA applications is the
tnameserv program, which acts as a naming service, looking
up service locations upon request.
Read more on Java 1.2's distributed object technologies in
Bryan Morgan's "Java 1.2
extends Java's distributed object capabilities."
Thread local variables
JDK 1.2 adds support for static variables with different values
based on which thread a class (or set of classes) is running in.
These thread local variables work great for storing session
identifiers and sharing them within a ThreadGroup . These
types of variables are supported by the two classes
ThreadLocal and InheritableThreadLocal , and are
found in the java.lang package.
Version identification
With the package versioning support added to JDK 1.2, sometimes you
can find out the name and version of packages. I say sometimes
because a package isn't known to the system until a class is loaded
from that package. So this doesn't look at all the packages in the
CLASSPATH variable, just the loaded packages. For instance,
the following three lines list all the packages known to a program:
Package p[] = Package.getPackages();
for (int i=0, n=p.length;i < n;i++)
System.out.println (p[i]);
If you added a line like JButton jb = new JButton("Ack"); as
the first line, the number of packages returned would expand
significantly.
Versioning properties are set through the manifest
file of the jar containing the classes. Currently, the Java Core packages
do not provide version numbers, only names.
Floating point extension proposal
Two new keywords were added to JDK 1.2 with the beta 4 release:
strictfp and widefp . These keywords let you
specify the IEEE 754-standard strictness that a method or class uses
when calculating intermediate results. Currently, these options are not
used by the JVM, but you can place them in your
code. The strictfp keyword acts like the current
float behavior, while widefp is an
extended-precision format, which may be faster. Here's how to flag a
method to use the wide format:
widefp void doCalc (float x, float y) {...}
These keywords will not be added officially until the Proposal for
Extension of Java Floating Point in JDK 1.2 is approved through
Sun's Java standardization process. If rejected, the keywords
will disappear, going the way of the private protected access modifier,
which briefly appeared in a Java 1.0 release.
Java Foundation Classes
The Java Foundation Classes (JFC) encompass a large set of changes in
JDK 1.2. JFC also includes the existing JDK 1.1.x Abstract Windowing
Toolkit (AWT) capabilities. The 1.2 features of JFC are Swing, Drag
and Drop, Accessibility, Java 2D, and the Input Method
framework.
Swing
Swing is very likely the single JDK 1.2 addition that has received the most
attention, probably because it's usable in JDK 1.1,
too. Swing is a new set of Java components, providing a richer set of
widgets than the original AWT controls. Instead of a small set of
components that follow the lowest common denominator approach (if
something isn't available on every Java runtime platform, it isn't
available on any of them), the Swing component set is huge. By
itself, Swing is larger than the original JDK 1.0. It offers
everything from grid controls and labelled sliders to HTML rendering
components, and more. The components are so flexible that you can
change practically everything without changing anything. For
instance, you can change the look and feel of your application
without changing your event-handling code. You can even remove all
event-handling code and deal with everything through the
Model/View/Controller (MVC) architecture of the flexible Swing
components.
In my experience, using the Swing components since last August has
been a continual struggle. They tend to work best when doing
everything by hand. While they were designed as JavaBean components, they were
not initially created to be designable within drag and drop GUI
environments like JBuilder or Visual Café. As the IDE vendors have
improved their tools to be Swing-aware and Sun has improved the
components to be more designable, we're now at a stage where Swing
components are basically usable within second-generation IDE tools.
Within IDE tools, however, you can only use the Swing components as
replacement components for the AWT controls. You cannot use them,
yet, in their more advanced MVC mode.
With all this flexibility of Swing comes complexity and performance
bottlenecks. Performance has improved somewhat since the early days
of Swing, but if it's to be a viable option for client-side
applications, performance speed has to improve. Otherwise, we'll be
forced to look to Microsoft's WFC (and limit our programs to run on
only 90 percent of the desktop systems).
By the time JDK 1.2 is released, you'll find the Swing classes in
the javax.swing package. This will be the third home for
Swing in JDK 1.2; previously it lived in java.awt.swing
and in com.sun.java.swing .
Undo/redo framework
The Swing classes (package javax.swing.undo ) include a
framework for supporting undoable and redoable activities. Whenever
an editable activity occurs, you add it to the list of undoable
activities an UndoManager is managing. Then, when a user
asks to undo the activity, it can be undone. After being undone, it
can also be redone, unless something isn't redoable, in which case
a CannotRedoException is thrown.
Tomer Meshorer discusses Swing's undo/redo facility in "Add an undo/redo
function to your Java apps with Swing" (JavaWorld, June
1998).
Drag and drop
The drag and drop capabilities of JDK 1.2 beta 4 are somewhat
crippled. Not only has drag and drop changed significantly between beta
3 and beta 4, but Sun had to disable it completely under Solaris, permitting
it to work only in Java programs on Win32 machines.
Hopefully, by the time JDK 1.2 hits the street, all the kinks will
be worked out, including that annoying three- to five-second delay
before dragging is actually initiated.
Assuming everything is working, drag and drop is meant to permit
dragging and dropping between Java applications and native platform
applications. (See Resources for an example of
using the beta 4 Drag and Drop API.)
Accessibility
The Accessibility API lets developers enable their applications for
assistive technologies. These technologies include screen readers,
voice recognition software, and many other options for users unable
to physically see output or respond with input.
Assistive technologies may be used to augment users with disabilities or
support users whose jobs require them to be away from keyboard and monitor.
The Swing component set automates many of the steps necessary to make components
accessible. So, if you use them, there is little extra you need to
do. However, you should still be aware of the capabilities and set
appropriate messages when necessary (assuming an application could run in
such an environment). Here's an example of how to set such a
descriptive message. How it's used depends upon the assistive
device installed.
aButton.getAccessibleContext().setAccessibleDescription(
"Selecting this button turns off the coffee pot.");
Java 2D
The Java 2D API is an important part of the Java Foundation Classes.
So important, in fact, that JavaWorld has columnist Bill Day
writing about it in every issue (the JavaWorld Topical Index
provides links to all of Bill's Java Media columns).
The Java 2D API adds capabilities like adding an alpha (or
transparency) channel to colors, drawing with antialiasing to get rid
of the jaggies when drawing diagonal lines, filling shapes with
arbitrary styles, and defining stroking patterns when drawing lines. I
leave the details of the Java 2D API for Bill Day to explain.
Many people I spoke with placed the Java 2D capabilities among their top
three enhancements in JDK 1.2, along with Swing and Security.
"Component developers will be most interested in the 2D API provided
in JDK 1.2, which eliminates the complicated and slow capabilities
introduced in JDK 1.0," says Frank Pittelli, PhD, of Pittelli &
Associates, co-founder of ChartWorks Inc. (formerly NetFactory), a
Java-based charting solution provider. "As the designer of charting
components, I only wish that the 2D API was around three years ago,
when it all began."
Input Method framework
The Input Method framework supports input of
multibyte characters (specifically Japanese, Chinese, and Korean)
within text components. Currently, the TextArea and
TextField components of AWT cannot support this framework
because they use the underlying operating system to create the
controls through platform-specific peers. If you need to use this
framework, you must use lightweight components, like the Swing
controls.
Printing
Printing in JDK 1.2 now supports an optional print
dialog. JDK 1.1 printing capabilities required a
print dialog, so you couldn't automate print jobs for after hours. Located
in the java.awt.print package, the key class for printing is
PrinterJob and the key interface is Printable . The
print() method of the Printable interface is
repeatedly called as long as the method returns
Printable.PAGE_EXISTS . The calls cease when the method returns
Printable.NO_SUCH_PAGE .
Font support
You can forget about the limited font support in JDK 1.0 and JDK
1.1. With JDK 1.2 you now have access to all the fonts available on
your system (or at least those available by the directory specified in
the JAVA_FONTS environment variable). Instead of asking a
Toolkit for the font list, you ask the
GraphicsEnvironment . You then set the font according to
the user's choice.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Font fonts[] = ge.getAllFonts();
Font aFont = fonts[1].deriveFont (Font.PLAIN, 12);
// or
String fontList[] = ge.getAvailableFontFamilyNames();
Font bFont = new Font (fontList[1], Font.PLAIN, 12);
Buffered image
With the addition of the java.awt.image.BufferedImage class,
double buffering has gotten much easier. No longer do you have to
worry about when createImage() will return a valid
Image object. And, you can specify the bit-depth when you
create a buffered image, or ask for the optimum image format for the
current graphics-display configuration.
BufferedImage biOne =
new BufferedImage (640, 480, BufferedImage.TYPE_INT_RGB);
// or
Graphics2D gwd = (Graphics2D)g; // g is arg to paint()
GraphicsConfiguration gc =
g2d.getDeviceConfiguration();
BufferedImage biTwo =
gc.createCompatibleImage (640, 480);
Unfortunate incompatibilities
Sun's Java Development Kit Compatibility with Previous Releases
page (see Resources) contains a complete set of
version incompatibilities. Unfortunately, there are some. Most of the
incompatibilities listed are the result of bug fixes. However, there
are some that aren't related to bug fixes. They're caused by the addition of
classes, where a new class is given the same name as an old one, but
exists in a different package. You may happen to import both into your
program, due to importing with asterisks (that is,
import java.util.* ), in which case you'll have to explicitly import one in
the source before it will successfully recompile (or explicitly
reference the class name). The most frequently used duplicately named
classes are as follows:
java.lang.reflect.Array /java.sql.Array
java.sql.Date /java.util.Date
java.awt.List /java.util.List
javax.swing.filechooser.FileFilter /java.io.FileFilter
java.security.Permission /java.security.acl.Permission
JPEG encoding
The com.sun.image.codec.jpeg package comes with Sun's JRE
and allows you to read and write JPEG files. While reading has long been
available with getImage() , writing previously required a
third-party package, assuming you wanted to maintain the
JPEG encoding when you saved. When first introduced into an early beta
version of JDK 1.2, these classes were in a different package, under
the java.* hierarchy. After causing quite a bit of
controversy, they were moved. They're not considered part of the
Core API. However, they are available with the runtime
environments provided by Sun.
FileInputStream fis = new FileInputStream ("imagefile.jpg");
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder (fis);
BufferedImage bi = decoder.deco deAsBufferedImage();
Once you've read the file into a buffered image, you can manipulate it,
and later save it back out. Saving allows you to set
JPEGEncoderParam data like image quality, or you can just
use the defaults, as follows:
FileOutputStream fos = new FileOutputStream ("imagefile.jpg");
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder (fois);
encoder.encode (bi);
What happened to servlets?
When JDK 1.2 was first announced, the servlets package
(javax.servlet ) was supposed to be included as a standard
extension with the 1.2 development and runtime environments. At
some point, Sun decided it was best left packaged separately, in the
Java Servlet Development Kit (JSDK). The 2.0 JSDK is the latest
release, and works with both JDK 1.1 and JDK 1.2. When creating
servlets, be sure to use the version of Java technology supported by
your servlet-enabled Web server.
The only deprecation change between the 1.x and 2.x servlet packages is
the getServlets() method of ServletContext ,
which has been deprecated in favor of the
getServletNames() and getServlet() methods.
If you've been using the 1.x JSDK, the biggest changes you'll
see in the move to the 2.x JSDK include delegation of different request types to
specific methods (like doGet and doPut ) of
HttpServlet , the addition of Reader and
Writer support with ServletRequest and
ServletResponse , as well as the addition of the
SingleThreadModel interface to indicate a servlet should implement
service requests in a single-threaded manner.
Browser support
For now, browser support for JRE 1.2 will be provided with Sun's
Java Plug-in. This immediately enables JRE 1.2 within Netscape
Navigator 3.0/4.0 under Windows (NT/95/98) or Solaris (SPARC and x86
(3.0 only for x86)), as well as Internet Explorer under Windows (4.0
for NT/95/98 and 3.02 for NT and 95). Until the Sun vs. Microsoft Java
lawsuit has been resolved, you shouldn't expect to find JRE 1.2
support in Internet Explorer directly from Microsoft. As far as
Netscape goes, rumor has it that the company plans to include the
Plug-in with a future release of its browser software, instead of
requiring the separate installation of the tool.
Conclusion
With the JDK 1.2 FCS release soon upon us, there is much to learn
if you wish to stay current with the third generation of Java
technology development. This article highlights key areas you'll want to
continue exploring on your own. The good news is that, with the sole exception of
security-related code, everything should recompile and run fine under
the 1.2 environment. Hopefully, 1.2 will run faster than, or initially at
least as fast as, JDK 1.1. While Sun has delayed the FCS
for some time now, it appears JDK 1.2 will serve as a complete
development environment with a polished API set.
Rick Ross, president of Java Lobby, commented that Sun "has to fix
today's problems before adding more improvements" and said Sun was
"right to hold off delivery of JDK 1.2 to achieve a lower-memory
footprint and better performance." Ross said performance is key,
"particularly for people creating applications competing with
natively compiled code." Hopefully, by the time JDK 1.2 comes out,
with capabilities like a feature-complete Swing implementation and
better performance, Java developers will be happy. JDK 1.2 offers
many new features, and if Sun can keep to its promised numbers,
Frank Pittelli claims, "Java 1.2 will achieve wide scale acceptance
and will be able to serve as the basis for millions of development
projects over the next few years."
About the author
John Zukowski is a
software mage with MageLang
Institute, author of Mastering
Java 1.2, Java
AWT Reference, and Borland's
JBuilder: No experience required, as well as the Focus on Java guide at The Mining
Co.
|