|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
General Java Developing Cross-Platform Applications in Java
Developing Cross-Platform Applications in Java
By: Steven Gould
Apr. 1, 1999 12:00 AM
One of the primary design goals for Java is the idea of "write once, run anywhere." Java is therefore an ideal language choice when faced with the challenge of developing a platform-independent application. Many articles have been written on applet development and the use of Java for bringing more interactivity to pages on the Web. While this is a valid use of Java, it's equally well suited for developing more traditional standalone or client/server applications that can run across multiple platforms. When Java is used to develop each of the tiers of an n-tier client/server application, its cross-platform nature offers additional benefits, including scalability (independent of hardware platform), flexibility and vendor independence.
Which JDK? Whichever version you decide to use, be sure to bundle the appropriate Java Runtime Environment when you distribute your application.
Application development, with its more relaxed security model, allows lower-level access to the operating system. This access, however, can result in your application's becoming platform-specific. In this article I'll look at five primary areas you should pay special attention to when developing cross-platform Java applications:
Good Programming Practices If you use any third-party class libraries, you'll need to distribute their runtime versions (which may require a separate license). It's also recommended that you verify that these third-party libraries make use of the core Java API only and don't use any native calls. Otherwise the code you write may be cross-platform. However, since your code depends on a third-party product that's not cross-platform, your resulting application won't be cross-platform either.
Enable all compiler warnings.
Avoid deprecated methods
Avoid "undocumented features" Similarly, your applications shouldn't depend on the implementation details of any one particular Java implementation. For example, use of the AWT component peer interfaces is documented as being "For use by AWT implementers." Peer classes are highly platform-specific. As a portable application makes use of the AWT rather than implementing it, you should avoid using peer classes in your application.
Follow any applicable API protocols. For example, the JDK 1.1 introduced a new AWT event model. According to the new documentation, the results may be unpredictable if you mix the new event model with the older 1.0 event model. (Refer to "Updating 1.0 source files to 1.1" in the JDK documentation download bundle for details.) Several of the AWT methods (Component.Paint and Component.Update, in particular) accept a Graphics object as one of their arguments. While you can use and make changes to this object within the method to which it was passed, you shouldn't store a reference to it for later use. Since the AWT implementation is allowed to invalidate any Graphics object after the method returns, storing and later using a reference to it may work on one platform but isn't guaranteed to work on another. This type of problem is particularly difficult to debug. If any of your classes override the Object.equals method, they should also override the Object.hashCode method so that for any two objects x and y: x.equals(y) implies that a.hashCode()==b.hashCode() See the JDK java.lang.Object.hashCode documentation for details.
Use System.exit method sparingly. Since the System.exit method forces termination of all threads in the JVM, it may, for example, destroy windows containing user data without giving users a chance to save their work.
Adhere to good practices with thread scheduling and synchronization Before using Java's multithreaded capabilities, read and understand the JDK documentation for the java.lang.Thread class and the java.lang.Runnable interface. Although Java does simplify multithreaded application development, it's still somewhat of an advanced topic and many of the thread synchronization issues still exist. Doug Lea's book, Concurrent Programming in Java, covers this subject in depth.
OS Differences and LimitationsAvoid Native Methods
Before using native code, consider the following alternatives: You may think that confining the native methods to a single class and providing an implementation of that class for every Java platform is a sufficient workaround. This is actually a poor "solution" since the number of Java platforms is ever-increasing. In addition, some Java platforms have no ability to execute native code.
Exercise caution when using Runtime.exec If you intend to use the Runtime.exec methods in your application, then you should provide a way in which the user can specify the exact command strings. Ideally this would be done through a GUI. However, if the command(s) rarely need changing, you can prompt the user to enter them during installation, then store them in a properties file for later use.
Don't use hardwired platform-specific constants The AWT also provides ways to help you create a platform-independent GUI. Details of these features are described in a separate section below.
Issues particular to command line programs and processing Even with those platforms that support command line programs, command line processing isn't consistent across these platforms. Although the most portable solution doesn't use the command line, this may not be acceptable for programs that need to be executed from within a script. In this case consider using the POSIX convention in which command line options are indicated with a leading dash. As an alternative, you may also want to consider reading the options from a properties file and/or providing a GUI.
Don't assume support for rendering unicode characters
Make no assumptions about the hostname format If your application is merely displaying the resulting hostname, this is unlikely to cause a problem. However, when the name is passed to other systems or applications, it may be best to provide the IP address in addition to the hostname. Note that the IP address is available using the InetAddress.getAddress or InetAddress.getHostAddress methods.
Read/Write Files Alternatively, to dynamically construct a path and filename in a platform-independent way, use one of the java.io.File constructors. Be aware that even the format of an absolute path differs between platforms. For example, on DOS and Windows-based platforms, an absolute path typically begins with a letter followed by a colon. Under UNIX, absolute paths begin with a forward slash: "/"
Don't hard-code line termination characters Additionally, though Java internally uses Unicode characters for text, different platforms have different internal representations. JDK 1.1 provides several methods to help address both of these problems. To output text in a platform-independent manner, use any of Java's println methods. These methods output the end-of-line character sequence appropriate for the platform on which your Java application is running. If you really need access to the appropriate end-of-line sequence for the current platform, use the value returned by java.lang.System.getProperty("line.separator"). Similarly, to input text files, use the java.io.BufferedReader.readLine method. This reads a line of text terminated by a line feed ("\n"), a carriage return ("\r") or a carriage return followed immediately by a linefeed, and returns the contents of the line, excluding any line-termination characters.
Be aware of the maximum length of filenames One workaround to this is to package your classes into a Java archive (JAR). Alternatively, a ZIP file will work if you're developing for JDK 1.0. Observe strict case distinctions on all platforms. Some platforms - most notably DOS and the Microsoft Windows platforms - ignore case when comparing filenames. However, don't let this affect your development efforts. Always use the correct case for class names and filenames throughout your code. That way, your Java application will run as intended on a wider range of platforms. Combining all your classes into a JAR or ZIP file, as discussed above, also helps preserve the case of filenames.
Avoid "special" filenames Be aware of these and other "special" filenames on the different Java platforms.
GUI Design The JDK 1.1 documentation download bundle contains details about upgrading in the section titled "Updating 1.0 source files to 1.1." Although it may be tempting when upgrading your application from JDK 1.0 to 1.1 to do this piece by piece, resist this temptation. Bite the bullet and do the entire upgrade in one step.
Use layout managers for sizing elements. Break the habit of laying out components by size and position, and learn how to use Java's layout managers effectively to achieve the desired results.
Blend your GUI with the desktop To make your colors blend in with the user's desktop, you can use colors from the java.awt.SystemColor class. Alternatively, you may want to provide the user some way of customizing the appearance - particularly the colors and fonts - of your application, either through an Options dialog, a properties file or both. Rarely should you need to obtain the screen resolution, but if you really have to, you can use the java.awt.Toolkit.getScreenResolution method.
Don't assume existence of nonstandard fonts Don't hard-code font sizes. Let text components take on their default size using an appropriate layout manager, and use java.awt.FontMetrics.stringWidth if you really need to determine the actual displayed width of a string. Before selecting a nonstandard font, be sure to test for its availability and provide a suitable default font in the event that it doesn't exist. The default fonts supported by JDK 1.1 are: "Serif" (usually Times Roman), "SansSerif" (usually Helvetica) and "Monospaced" (usually Courier).
Other Issues
Choosing a distributed framework CORBA, the most generic of these frameworks, supports not only a wide variety of platforms but also a variety of object development languages. This allows, for example, a Java client to communicate with a C++ CORBA server on a different machine, knowing only the interface published by that object. RMI is specific to Java and makes communication between distributed Java objects fast and easy. It has a lot in common with CORBA, and there have been talks about possibly merging the RMI specification into CORBA sometime in the future. Finally, DCOM is Microsoft's Distributed Common Object Model. Like CORBA, it's also language-independent but isn't platform-independent, being supported only on the newer Microsoft Windows operating systems. Furthermore, DCOM isn't supported in the standard Java API. This isn't recommended if you're aiming to develop a truly cross-platform solution.
Loading JDBC drivers Using JDBC may restrict the portability of your application if not implemented with some forethought. To keep your application as portable as possible, provide a means for the user to specify the JDBC driver name. This can be done through either a GUI, the jdbc.drivers system property or a similar properties file.
Resources Reader Feedback: Page 1 of 1
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||