Distributing Java

By Aris Buinevicius

Packaging and Deploying Java Applications

Windows applications are distributed in a number of ways, from small, single-file executables, to large systems that include multiple DLLs (dynamically linked libraries) that consume a huge amount of system resources. While proven to be effective, these techniques have not scaled up well to large organizations where IT departments are responsible for providing software updates throughout an enterprise. One of the promises of Java is to make an IT engineer's job easier by simplifying the deployment process.

How Java Applications Run

In some ways, distributing your Java applications is easier than the traditional distribution model. In other ways, however, it can be even more complex. With Java applets, your audience is any visitor to your Internet site. These applets and the code that resides on a central server (whether available on an intranet or the Internet) can be downloaded onto a client machine, making the whole upgrade/update process more seamless. Java can also be used to write a compiled executable that contains all the elements you need to run the application.

Politics and Java

Over the past two years, the media has put Java into the limelight much more than any other computer language, past and present. I was shocked to see a television commercial that made reference to Java being used in the enterprise during a Chicago Bulls game on a Sunday afternoon. All the media attention has brought a host of unsubstantiated claims, rival technologies, and dramatic changes in the landscape that you must be aware of when packaging a Java application.

The biggest issue at hand today is the "pure Java" concept. While this makes for interesting reading in computer trade magazines and the business section of your newspaper, it also has an effect on you,  depending on what technology your target audience uses. If you have any intention of deploying your Java application/applet to an audience on multiple platforms, then you will need to pay attention to what parts of Java will behave differently on different JVMs (Java Virtual Machines).

You can be reasonably sure that your application will run similarly on different JVMs from Microsoft, Sun, Netscape et al., up to the JDK 1.02 release. Beyond that point, if you start basing your applications on technologies unique to JDK 1.1 and later (such as JFC and the SwingSet components), you might be reducing your potential target audience (i.e. users of Microsoft Internet Explorer may not be able to run such technologies with the out-of-box Microsoft JVM).

The issue here is the Microsoft JVM and how much of "Sun's" Java will be supported. Some technologies such as Sun's Java Activator might provide a short-term solution, but it remains to be seen whether this approach will be successful. The Activator product seeks to do an "end around" of the Microsoft JVM found in Internet Explorer by tying in the Sun JVM through an ActiveX component. With this kind of deployment, there is still an assumption the target audience of a JDK 1.1 application will already have Activator installed correctly before they run such an application. The coming months will show if this is a viable solution.

.class Files

The .class file is the backbone of any Java application. Whether generating an applet for Internet distribution or compiling to a native executable, the .class file is the bytecode that needs to be packaged and sent to your target audience. The .class file format itself is easy to disassemble and read. This is good because it makes it easier for JVMs to ultimately interpret and run your code. However, it also makes trade secrets easily available to anyone with a third-party disassembler tool, or even the standard javap utility that's part of the JDK.

Creating an Applet

One of the simplest ways you can distribute a Java application is by writing it as a Java applet for the Web. The simplest way to distribute your applet is to physically copy all the .class files in the same directory where the applet is to be loaded.

In general, applets are more restrictive in terms of what kind of functionality can be invoked from them; obviously, a public applet won't be able to access a local machine's resources for security reasons. Also, when creating an applet, experience shows that you probably won't be able to predict every browser that will hit your site. Ensure that you have provisions for users to report any problems they might have when attempting to run your applets under different browsers.

Hooking into HTML

The code required to invoke a Java applet from an HTML page is rather simple; simply specify your main entry .class file (the class which is a subclass of the Java Applet class) in your HTML file:

<APPLET CODE="MyApplet.class" WIDTH=200 HEIGHT=200>
</APPLET>

If you stored the .class files in a location other than the same directory where the HTML file is located, you can specify the location via the <CODEBASE> tag:

<APPLET CODEBASE="/applets/libs" CODE="MyApplet.class"

In this case, you can place any .class files within the /applets/libs directory on your Web site, instead of in the same directory as your applet.

Compressed/Archive File Formats

Archived file formats allow you to combine all your Java .class files into a single file, making the deployment process easier and more convenient for your users. When combined with compression options, this can reduce the overall footprint of your application.

The three most common file formats are the standard ZIP file format (supported by Netscape), the CAB file format (supported by Internet Explorer), and the JAR file format (supported by Internet Explorer 4.x, Netscape Navigator 4.x, and Sun's HotJava). CABs and JARs offer approximately the same type of functionality, but fall into a "Beta vs. VHS" type of competition in terms of what is more commonly used.

JavaBeans

JavaBeans is the component model defined by JavaSoft, which competes in part with Microsoft's COM component model. From a certain respect, a JavaBean represents a package of related .class files which are packaged into a single file. The .class file connections are related by a manifest file that is used to create the JavaBean, and certain method naming conventions are used to expose properties of the JavaBean. In Visual J++, Microsoft provides an ActiveX wrapper class that allows you to use your JavaBean in a design-time RAD environment such as Visual Basic.

Native Calls

When developing a Java application, you often need to call into a native library because Java doesn't provide the capability you require. In these cases, you can use native methods to call directly into these libraries. Some dispute has occurred in the Java community regarding calling native methods; the dispute arises out of implementation of JNI (Java native interface) vs. Microsoft's RNI (raw native interface) which is provided as part of the Microsoft JVM. This is one issue that revolves around the "Is Microsoft providing 100% Pure Java code" argument.

When making calls to native libraries, you should definitely try to determine what your target audience is before making a decision about which implementation you'll be using. If your target is users using multiple browsers, then JNI might be your solution. If you can deploy in an all-Microsoft environment, RNI (and J/Direct) are probably a better solution. One compromise that can result in duplication of code would be to attempt to wrap the native calls in a separate RNI or JNI set of classes that are shielded from the rest of your application.

Another developing technology which makes it easier to call into Windows-specific DLLs is the J/Direct technology from Microsoft. J/Direct allows you to easily specify hooks into the Windows system DLLs (as well as user DLLs). With J/Direct, you can even bypass the AWT and program your Java applications as if they were a standard Windows event-driven application.

Class libraries

Many third-party class libraries are available to aid Java software developers. If your application uses such a library, look into the company's policy regarding how they ship their .class files. Some parties have strict restrictions in terms of what you can ship (and sometimes charge royalties), while other companies provide full source code, allowing you to choose how you embed tools into your application. In any case, pay attention to the fine print when researching and purchasing third-party component libraries.

Testing and QA

Probably the toughest task facing Java developers today is Quality Assurance (QA). For those developers who want to distribute to a cross-platform audience, as opposed to deploying an application on a single operating system, the QA process has grown exponentially. Not only does the QA tester need to test under different platforms, but each platform has different JVMs that must be tested. To make matters worse, several versions of each JVM have probably been released as well. The QA tester must simply focus on reality and determine what the target audience of the Java applet or application is. In most cases, they can focus on only the most popular JVM and browser implementations and assume (or hope) the other platforms or JVMs will not misbehave.

Fortunately, more developer tools are becoming available to provide useful information about what parts of the application could be troublesome when running in other environments. As a rule of thumb, probably the most buggy section of the JDK has traditionally been the AWT portion, and as your application grows in complexity from a user interface perspective, you will want to spend more time testing your GUI. Commercial tools such as profilers (including those available from NuMega, Rational, and Intuitive Systems) can be an invaluable aid to profiling your code.

Documentation

Fortunately, many options are available for developing your documentation base. There's always the traditional printed media format that you can ship with your application; and if you wish to ship everything online, you can use HTML pages to document your application. So far, no strong tools exist with the bang of a full context-sensitive Help system such as the traditional WinHelp system available for Windows users, but you can get by with HTML in most cases. If you are shipping a Java class library, a useful tool in the JDK is available — the javadoc utility converts your commented .java source files into a format familiar to most Java developers.

Several third-party tools are also available for your documentation needs; Adobe's PDF format is useful for shipping common documentation which can be read on multiple platforms, and HTML Transit (from InfoAccess) allows you to convert standard Word files into a professional looking set of HTML pages.

Obfuscation/Security

The Java .class file format is a well specified and documented file format — which is good and bad. It's easier for JVMs to interpret the bytecode easily, but it's also easy to disassemble and thus, reverse-engineer. While many Java proponents claim that even native binary executables can be disassembled, it's clearly easier to use a third-party tool such as Mocha to construct easy-to-read Java source code from your .class files than it is to read assembler code.

There are a few stop-gap solutions that don't completely solve the problem, but make your code harder to reverse-engineer. There are several third-party obfuscators available to help shroud the symbols of your .class files. Thus, when a reverse-engineering tool is used to try to disassemble your .class files, an obfuscator will show your variable names as unreadable and garbled. While it's still technically feasible to read your code, it makes it more difficult.

Another solution is to simply code your most sensitive trade secrets in native binary code, which can then be accessed via native calls, or a technology such as J/Direct.

Optimization

When it comes time to deploy your application, you'll want to ensure your code is optimized. Several obvious tricks can help you, and when combined, these tricks can result in a slight increase in execution speed of your Java code. First, ensure that the final .class files of your application are compiled in Release mode and not Debug mode. If distributing a Java applet on the Internet (or in an intranet), using compressed file formats (such as CAB and JAR) won't necessarily result in increased execution speed, but will reduce download time and give the impression of an increased execution speed. Several obfuscators claim that while providing obfuscation, they also increase the performance of your Java code. Finally, some third-parties are providing solutions to help optimize your Java code by analyzing your .class files and performing loop cleanups, etc. Two tools that show early promise in helping with optimization are available from Intuitive Systems and preEmptive Solutions.

Digital Signing

Digital signing provides a level of security confidence from a third party (the most popular being VeriSign). When users download a digitally signed CAB file, they can have a higher level of confidence that the code is legitimate and will not attempt a hostile takeover of their operating system. Although not completely foolproof, digital signing provides some additional peace of mind to your customers by vouching that you have a legitimate organization and that your code has not been altered by a third party.

Digital signing involves several technologies (including ActiveX, Java, CAB files, and more) and works with Microsoft's Authenticode technology to warn users they are about to run or download a piece of code that has been digitally signed. It's then up to users to determine if they trust the company providing them with the code and to proceed with its execution.

Tying digital signing to your code is relatively easy. (After you've obtained a digital ID from VeriSign, Microsoft provides a toolkit to make this easier.). The process for obtaining a digital ID involves registering for the ID, paying VeriSign a fee (which varies based on what type of signing you wish to enable), and possibly waiting for a week to finish the registration.

Third-Party Installation Toolkits

Several third parties (most notably InstallShield) provide toolkits that allow you to easily construct a full installation executable that your customer will run to install your own software. InstallShield and some smaller third parties are now providing these tools for Java developers as well.

Creating Native Executables

As part of Visual J++, you can use the jexegen.exe utility to create native Windows applications from your Java source code base. For the most part, jexegen will generate a self-contained static executable. However, there's still a dependency on the Microsoft JVM; it must be on the client machine for the executable to run.

Conclusion

Packaging your Java applet/application requires knowing what your target audience will be. If you can limit the scope of your target distribution to a single operating system, your quality assurance and testing procedures should make it easier to deploy a solid Java application.

Aris Buinevicius was one of the first employees of Bristol Technologies, where he helped develop cross-platform porting solutions for developers moving from Windows to UNIX. He later co-founded Stingray Software. Aris has been programming for more than 15 years, with the last two concentrating on Java.