The Java Extension Mechanism Blog

Version 2

    {cs.r.title}



              
                                          

    Contents
    The Class Path
    How User Classes Are Found
    Sharing .jar Archives
    Optional Packages
       Location of Optional Packages
       Sharing Optional Packages Among Java Runtimes
       Linux
       Windows
    Tweaking the Manifest File
    Pros and Cons of the Extension Mechanism
    Conclusion
    Resources

    A huge number of publicly available packages extends the functionality of the Java core platform. Some of them provide access to features of the underlying operating system that are not available through the standard class library, such as missing GUI components, or reader and writer classes for important file formats. Others are exciting technologies in their own right, like Spring, Hibernate or Struts.

    Sometimes installing them is a bit tricky, requiring you to modify the class path of your application or tweak options passed to the Java launcher. Others utilize a handy feature called theJava Extension Mechanism. Libraries loaded via the extension mechanism can be accessed by any Java program without further prerequisites (besides copying some files to certain directories). This article explains how the Extension Mechanism works and discusses the steps required to implement your own so-called optional packages.

    The Class Path

    The virtual machine uses the concept of a class path, which is a set of directories and .zip or .jar archives. To find classes (as well as other resources like properties files, images, or audio content) the Java runtime looks in all locations specified in the class path to find the required resource.

    Early versions of Java relied heavily on an environment variable called CLASSPATH that stored these locations. It is easy to modify this variable, perhaps too easy: setting the class path this way turned out to be error-prone, as changes usually affected other applications. Another shortcoming of this approach was the missing distinction between user (third-party) and system classes. Today there is no need to use the CLASSPATHenvironment variable.

    Since Java 1.2, the virtual machine has distinguished between three types of classes: bootstrap classes, extension classes, and user classes. Each type has its own individual search path that can be modified separately. All three parts together make up the class path. It is worth mentioning, however, that the user class path is commonly referred to as simply "the class path."

    The difference between extension classes and user classes may not be clear at first sight, as they both are implemented by third-party developers, and hence do not belong to the core Java classes. The difference is that user classes do not take advantage of the extension mechanism. Additionally, the way that extension classes are found by the virtual machine is different.

    The boot class path specifies where core system classes are searched. The system property sun.boot.class.pathstores these locations. It generally should not be necessary to change them, but there is a non-standard option of the Java launcher, -Xbootclasspath, that allows you to use alternative core system classes.

    How User Classes Are Found

    The user class path specifies where user classes and resources are searched. A simple program consisting of one class calledTest is invoked through:

     
    java Test
    

    This assumes you use the standard Java launcher. The class path defaults to the current directory, so Test is found easily (if the current directory containsTest.class).

    A program consisting of two .jars (the main application inMyApp.jar and a set of utility classes inMyUtils.zip) is invoked through:

     
    java -classpath MyApp.jar;MyUtils.zip myapp.MyAppMain
    

    The path separator is ; on Windows, while Unix variants like Mac OS X and Linux use : instead.

    Using -classpath completely overrides the default setting; therefore, the current directory is not part of the class path. Consequently, to access classes that are not part of the specified .jar or .zip archives, the directory containing them must be added to the user class path with the -classpathoption.

    Sharing .jar Archives

    It is common practice to have a Main-Class:attribute in the main application .jar's manifest file so the application can be launched by typing java -jar MyApp.jar. In this case, the .jar file is the source forall user classes. Any other class path option is ignored.

    To gain access to classes and resources stored in utility class .jars, you must add a Class-Path: attribute to your application's manifest file. Its value contains a space-delimited list of relative URLs referencing libraries your application wishes to use. These URLs are assumed to point to directories if they end with the / character. Otherwise they are assumed to refer to .jars.

    To share a library among multiple projects, you could add its location to the class paths of these programs using-classpath or Class-Path: in the manifest file of each program. This can be a cumbersome task if several projects are involved. If we used the old-styleCLASSPATH environment variable, it would have been sufficient to append the location of the library--no need to explicitly reference it with each application wishing to use it. But there must be a similar feature in recent Java versions, right?

    Optional Packages

    The extension mechanism is a convenient and easy to use infrastructure to provide optional packages. These are sets of classes that extend the functionality of the core platform. A key feature is that the virtual machine can find components (we will see shortly what this means) of an optional package without the need to explicitly mention it on the (user) class path.

    Optional packages consist of Java classes and other resources like images, sounds, text, and property files. They are wrapped in a .jar file that may be accompanied by platform-specific native code, such as shared libraries and executables.

    There are two flavors of optional packages, calledbundled and installed optional packages. If it is bundled with an application, the library is provided at the same code base and will therefore be downloaded automatically if necessary. Installed optional packages are shared by all applications using the same Java runtime environment.

    Location of Optional Packages

    There is nothing special about an optional package. To create one, it is sufficient to bundle classes and resources into a .jar archive. The only prerequisite is that the .jar must be copied to a certain location inside of the Java runtime directory tree.

    The location of optional packages can be determined and set through system properties. Here is a small program that prints out some interesting values.

     
    public class ShowProperties { public static void main(String[] args) { String [] properties = { "java.ext.dirs", "java.home", "path.separator", "file.separator", "java.library.path", "os.arch", "sun.boot.class.path" }; for (int i = 0; i < properties.length; i++) { String key = properties[i]; System.out.println(key + ": " + System.getProperty(key)); } } } 
    

    The output of this program depends on the underlying operating system, as seen in Figures 1-3.

    Figure 1. Running ShowProperties on Mac OS X Panther
    Figure 1. Running ShowProperties on Mac OS X Panther

      

    Figure 2
    Figure 2. Running ShowProperties on Linux--click for full-size image


        

    Figure 2
    Figure 3. Running ShowProperties on Windows--click for full-size image

    java.home is a very important system property, as it points to the base directory of the Java runtime.path.separator contains the delimiter for search path lists, as we have seen with the -classpath option.file.separator contains the delimiter for files and directories. In my examples here, I will use the backslash, but please keep in mind that on Unix variants you must substitute it with the slash. java.ext.dirs stores one or more directories to be searched for optional packages. The default location is java.home\lib\ext.

    If an optional package requires native code, the Java runtime looks in java.home\bin andjava.home\lib\ext\<arch>. <arch>specifies the architecture for which the native code has been compiled. It can be determined through the os.archsystem property. Please note that Windows and Linux return different values, even when running on the same machine. Pictures 2 and 3 were taken on a Toshiba notebook running Windows Media Center Edition 2005 and SuSE Linux 9.2.

    Installed optional packages are, by default, granted the same security privileges as core platform classes, because they often need to load and access native code. This can be modified by editing the security policy configuration file calledjava.policy, which is located injava.home\lib\security.

    Sharing Optional Packages Among Java Runtimes

    So far, there is no standard procedure to make an optional package system global; that is, to share it among Java runtimes. If you have several versions of Java installed on your machine, you need to copy all files associated with an optional package to theext directories of all Java installations. Undoubtedly, this is a cumbersome task.

    To solve this, you might pass -Djava.ext.dirs=...as an additional argument when you invoke Java programs. As many applications are launched through startup scripts or shortcuts, you would need to modify all of them.

    Apple offers a very nice solution to this problem. In Mac OS X, you can throw .jars in /Library/Java/Extensions. The classes will be visible in all Java runtimes./System/Library/Java/Extensions is reserved for Apple extensions, and therefore should not be used by third-party developers.

    Fortunately, it is possible to simulate this behavior on other operating systems.

    Linux

    On Linux, it is easy to achieve the same effect. You just need to create symbolic links in the lib directories of the Java installations you want to benefit from shared classes. These links point to a directory that will contain the .jars.

    1. First, create a directory that will contain the shared optional packages; for example, /usr/java/extensions.
    2. cd to the lib directory of the Java installation you would like to have participate in the optional packages sharing.
    3. Rename the existing ext directory (mv ext ext.old).
    4. Create the link as follows: ln -s /usr/java/extensions ext.
    5. Finally, check that access permissions, owner, and group are set correctly and that you have copied the files of the originalext directory (ext.old) to the newly created one.

    From now on, any optional package you copy to/usr/java/extensions will be visible to any Java version you've modified as described.

    Windows

    Unfortunately, current versions of Windows do not support symbolic links out of the box. The native NTFS file system does, however, provide a similar concept, calledjunctions, which is based upon NTFS reparse points. Sadly enough, typical Windows installations do not contain tools to create them. but you can use a freeware tool by Mark Russinovich called Junction. Please consult the Resources section to download the program.

    With the Junction tool, it is easy to adapt the steps described in the Linux section.

    1. First, create a directory that will contain shared optional packages; for example, C:\Program Files\Java\Extensions.
    2. Then you need to rename the ext directory toext.old.
    3. The next step is to create a junction named extthat points to C:\Program Files\Java\Extensions. This is done as follows (please open cmd.exe):junction.exe C:\Programme\Java\jdk1.5.0\jre\lib\ext C:\Programme\Java\Extensions. The pathnames, of course, reflect my machine and need to be modified to meet your configuration. The first argument to junction.exe is the name of the junction to be created, which is the extdirectory. The second argument specifies the directory this junction shall point to. In our case, this is the newly created directory that will contain all shared optional packages.

    Follow these steps for all Java versions you would like to have participate in optional packages sharing.

    Tweaking the Manifest File

    The manifest file of installed optional packages should contain some attributes that describe the extension.

    • Extension-Name: should contain a name for the optional package, possibly the name of its main package.
    • Specification-Vendor: andSpecification-Version: specify the vendor of the specification and the version number to which the optional package conforms. The Java documentation suggests Sun Microsystems, Inc and 1.0.
    • Implementation-Vendor-id: identifies the producer of the optional package. The examples suggest a naming scheme similar to packages; for example,de.thomaskuenneth.
    • Implementation-Vendor: contains the vendor name; for example, Thomas Kuenneth.
    • Implementation-Version: contains the version number of the optional package; for example, 1.0.

    An optional package should use these attributes to identify itself. There is an additional set of attributes that should be used for applets.

    Pros and Cons of the Extension Mechanism

    Installed optional packages are visible to any Java program in the context of a runtime environment without the need to modify the class path. They are very easy to install, as they just need to be copied to certain directories. If you receive an enhanced or bug-fixed version, an existing program is easy to update, as you just have to replace the library.

    On the other hand, applications may no longer work correctly if a new version of an optional package changes its behavior. This may be the case if classes or methods are removed or method signatures are modified without providing backwards-compatible versions.

    So far, Sun has specified a versioning scheme for optional packages only for applets. In this case, the Java plugin checks for appropriate version numbers. For installed optional packages, no versioning mechanism is applied.

    Another point worth mentioning is that classes of optional packages will be found prior to application classes, as they are treated like core platform classes. The user class path is searched last. So even if your application .jar contains a newer version of a class, the class belonging to the optional package will be used.

    Conclusion

    The Java extension mechanism offers an easy-to-use infrastructure for providing optional packages. Packages can be used by all Java programs without the need to modify the user class path. Instead of requiring the user to work with the-classpath option, please consider taking advantage of the extension mechanism.

    However, the current approach has some shortcomings, such as the inability to share optional packages among Java installations. Additionally, just like for applets, Sun needs to specify a versioning scheme that ensures that applications will use the appropriate version of an installed optional package.

    Resources

      
    http://today.java.net/im/a.gif