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

Soon, 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.

  1. 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.)

  2. 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."

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.

Learn more about this topic

  • Java 1.2 home http://java.sun.com/products/jdk/1.2/
  • Java 1.2 documentation http://java.sun.com/products/jdk/1.2/docs/index.html
  • JDK 1.2 features guide http://java.sun.com/products/jdk/1.2/docs/guide/index.html
  • Sun's official discussion of JDK software compatibility http://java.sun.com/products/jdk/1.2/compatibility.html
  • Create servlets with the help of the Java Servlet Development Kit http://jserv.java.sun.com/products/java-server/sdk/index.html
  • Learn about javadoc enhancements and how to create doclets http://java.sun.com/products/jdk/1.2/docs/tooldocs/javadoc/index.html
  • Java Plug-in for Java 1.2 support in browsers http://java.sun.com/products/plugin/
  • Java Tip 46"Use Java 1.2's Authenticator class" http://www.javaworld.com/javaworld/javatips/jw-javatip46.html
  • The Java Lobby http://www.javalobby.org
  • RSA Data Security Inc., Java security solutions provider http://www.rsa.com
  • ChartWorks, Java charting solutions provider http://www.chartworksinc.com/
  • Apptivity, Java-based data access tool provider http://www.apptivity.com
  • Sample doclet and output http://www.javaworld.com/jw-11-1998/jdk12/jw-11-jdk12.zip
  • Drag and drop how-to, beta-4 style http://java.miningco.com/library/weekly/aa072398.htm
  • For CORBA information from the source, visit the Object Management Group http://www.omg.org/
  • The Generic Collection Library for Java, an alternative set of collection classes http://www.objectspace.com/jgl/
  • Sun's Java Tutorial"Thread Deprecation Changes in Java 1.2" http://java.sun.com/docs/books/tutorial/post1.0/preview/threads.html
  • The JavaBeans Glasgow Draft Specifications http://java.sun.com/beans/glasgow/
  • Read about the Java 1.2 beta 4 security changes in "New API for Privileged Blocks" http://java.sun.com/products/jdk/1.2/docs/guide/security/doprivileged.html
  • Check out "Reference Objects and Garbage Collection," one of many great technical articles on the JDC (registration required -- it's free) http://developer.java.sun.com/developer/technicalArticles/monicap/RefObj/refobj.html