UIX Developer's Guide
Go to Table of Contents
Contents
Go to previous page
Previous
Go to next page
Next

21. X Server Configuration for Image Generation

If you have found your way to this chapter, you are probably wondering why certain images seem to be missing from your page, or perhaps you are concerned about some confusing messages in your error log that are related to image generations. As discussed in the Image Generation chapter, the UIX implementation of the Browser Look And Feel uses the UIX Dynamic Images technology to dynamically generate images for components such as buttons and tab bars at runtime. The flexibility provided by dynamic image generation does come at a cost: the deployment environment must be capable of supporting the graphical operations needed for image generation. In Unix environments, this requirement typically means that some special configuration work is necessary.

This chapter describes how to enable dynamic image generation in Unix environments. Most of the work in enabling image generation revolves around the configuration of an X server for use by AWT. Fortunately, Sun Microsystems has recognized that requiring an X server for simple graphics operations such as image generation is not a good idea. AWT's dependency on the X Windowing System will shortly be removed in JDK 1.4. At that point, AWT will no longer require an X server, and the X server configuration steps described in this document will no longer be necessary. In the meantime, if you are wondering why your button or tab bar images aren't showing up, read on to find out more about X server configuration.

This chapter contains the following sections:

The X Server Requirement

On Unix platforms, graphics support is typically provided by the X Window System, a graphics system which is developed by a consortium of Unix vendors, currently known as X.Org. The X Window System is a networked graphics system. Graphics requests are made by client applications, known as X clients, to a server process, known as an X server. The X client and X server can be running on the same machine or on different machines. In either case, communication between the X client and server is performed using a network protocol known as the X Protocol.

UIX Dynamic Images uses the standard Java graphics library, AWT, to perform all graphics operations. The current production version of AWT (Java 2 release 1.3) requires access to an X server. This requirement means that in order to generate images from Java-based applications on Unix, an X server must be available, and the location of the X server must be known by AWT. Fortunately, these requirements will soon disappear. The next version of Java (release 1.4, currently in beta) removes the X server dependency through a feature known as "headless" Java. In the meantime, setting up X server access is an essential part of UIX deployment on Unix.

If X server access is not configured correctly, your UIX-based application will run, but will not be able to generate any images. If the X server can not be accessed, UIX logs an error message to the servlet engine's error log (for example, to jserv.log when running in jserv, application.log in OC4J), which often includes a stack trace as follows:

    uix/oracle.cabo.style: The following exception was thrown while 
    initializing the graphics environment: 

    uix/java.lang.InternalError: Can't connect to X11 window server using ':0.0'
    as the value of the DISPLAY variable.
  at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
  at <UNLOADED Method>
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName0(Compiled Code)
  at java.lang.Class.forName(Compiled Code)
  at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:63)
  at oracle.cabo.style.util.GraphicsUtils$GraphicsLoader.run(GraphicsUtils.java:294)
  at java.lang.Thread.run(Thread.java:479)

    uix/oracle.cabo.style: Could not initialize the graphical environment.  
    Please make sure that the DISPLAY environment variable is set correctly.  
    Proceeding with image generation disabled...

This error message indicates that a connection to the X server could not be established, and that no new images will be generated. In the event that a new image is needed but cannot be generated, UIX will generate alternate HTML content (for example, a link or input element instead of a button image) where possible.

Configuring X Server Access

Although the X Window System is a standard component of most Unix platforms, quite often some configuration work is needed to set up X server access. The X server must be started, AWT must be informed of the location of the X server, and the X server must be configured to allow access to the AWT-based application. Failure to perform any of these steps correctly can result in the error message described above, as well as missing images, or images replaced with alternate content. This section describes how to enable image generation in environments which support the X Window System.

Hardware Requirements

The standard X server software which ships with most Unix platforms imposes some hardware requirements on the hosting machine. The X server requires access to a hardware frame buffer. Also, a keyboard is required by default (although there may be some way to work around this requirement). In general, if the Unix box includes a monitor and a keyboard, the X server should run with no problems. However, a frame buffer and keyboard may not be installed in some machines in middle-tier, data center environments. In this case, the X server can not be started, and alternate solutions, such as using a remote X server, XVFB, the Image Servlet, or pre-generation must be explored.

Starting the X Server

The most common way to start the X server process is to log in to the console of the Unix machine. Most Unix platforms boot into the X Display Manager, a small authentication application which displays a login screen. Once the user logs in, the X server is started as a process that is owned by the console user. In the typical default configuration, the console user "owns" the X server - no other users are allowed to access the X server. As discussed later, these default settings can be overridden to allow wider access to the X server.

In cases where system administration is performed remotely (for example, by using telnet from a remote machine), the owner of the console may be required to start the X server on behalf of the remote administrator. To determine whether the X server is already running, look for a process name which starts with X. For example, on Solaris, the X server process is called Xsun.

Once the X server is running, it is extremely important to avoid stopping the X server while any client applications are connected. If the X server is stopped, a signal is sent to any connected clients. In response to this notification, AWT causes the Java virtual machine to abort, killing off the application.

This problem is exacerbated by the fact that once AWT connects to the X server, the connection is maintained by AWT for the life time of the VM. So, once any image is generated, an X server connection is established and kept alive until the servlet engine is stopped. Since the X Display Manager shuts down the X server when the console user logs out, this means that the administrator must remain logged in to the X server host machine for as long as the application is running. The console can be locked for security reasons (for example, using a tool such as xlock), but the console user must not end the X server session by logging out.

Note: It may be possible to configure the machine hosting the X server to start the X server without requiring a console login. Or alternatively, the XVFB pseudo-X server can be used independently of the X Display Manager. In any case, it is critical to avoid stopping the X server once a connection has been established by AWT.

Setting the DISPLAY Environment Variable

Once the X server is started, the next step in the configuration process is to specify the location of the X server via the DISPLAY environment variable. All X client applications use the information specified by the DISPLAY environment variable to determine how to locate and connect to the X server. The DISPLAY environment variable specifies three pieces of information:

  1. The machine name. This is the name (or IP address) of the machine on which the X server is running. If the machine name is not specified, the local machine is used as the default.
  2. The server number. This number specifies the X server instance to use. In some environments, multiple X servers may be running on a single machine. In most environments, however, only a single X server can be supported. In this case, the server number should be set to 0 (zero).
  3. The screen number. Each X server instance is capable of supporting multiple logical screens. By default, screen 0 (zero) is used.
These three pieces of information are combined into a single value of the following form:

    <machine name>:<server number>.<screen number>

When the X server is running on the same machine as the X client, the simplest way to set DISPLAY is to let both the machine name and the screen number default. In this case, the DISPLAY must minimally be set to :0, to indicate that screen zero on server zero on the local machine should be used for all X connections. This is sometimes specified as :0.0, although explicitly specifying the screen number is unnecessary.

Normally, the DISPLAY environment variable can be specified in a login script or shell script. However, in some servlet environments, the DISPLAY environment variable must be specified within servlet engine-specific configuration files. For example, when running a inside of Apache Jserv in automatic mode, the DISPLAY environment variable must be specified in the jserv.properties file using the following syntax:

  wrapper.env=DISPLAY=<machine name>:<server number>.<screen number>

When deploying to an OC4J instance within Oracle9iAS, the DISPLAY must be specified within the opmn.xml file. Prior to iAS 9.0.4, the DISPLAY environment variable could be set using the <prop> element:


    <oc4j instanceName="OC4J_Demos" gid="OC4J_Demos">

      <!-- OC4J configuration information here... -->

      <environment>
        <prop name="DISPLAY" value="machinename:0.0"/>
      </environment>
    </oc4j>

The structure of the opmn.xml file has changed as of iAS 9.0.4. Starting in iAS 9.0.4, the <variable> element is used to specify environment variables:


      <environment>
        <variable id="DISPLAY" value="machinename:0.0"/>
      </environment>

Note that opmn.xml contains an entry for each OC4J instance within iAS. Each of these entries must be updated to specify the appropriate DISPLAY setting. Please see the iAS documentation set for more information about setting environment variables via opmn.xml.

If the DISPLAY environment variable is not explicitly set in the proper servlet engine configuration file, it is likely that attempts to connect to the X server will fail and image generation will be disabled.

Since the X Window System is designed for network-based operation, the X server can be run on a different machine from the X client. This ability can be useful for "headless" middle-tier environments, where some middle-tier machines do not have the necessary hardware to run an X server locally. In this case, the X server can be run on some other machine which can support an X server. The remote X server can be accessed by an X client simply by specifying the machine name via the DISPLAY environment variable.

Note, however, that using a single remote X server as the DISPLAY for many machines within a headless middle-tier environment can be somewhat risky. As mentioned above, if the X server is stopped for any reason, any connected processes are aborted. To avoid this single point of failure, a better solution is to use a remote Image Servlet instance, which can protect the UIX-based applications against X server outages.

Testing the Connection

After the DISPLAY is set, the next step in the configuration process is to verify that the X server can be accessed by an X client. The easiest way to verify X server access is to run one of the many X client applications, such as xterm or xclock, that are shipped with the X Window System. (On Solaris, these tools are located in the /usr/openwin/bin directory.)

If the DISPLAY environment variable is set correctly, an application like xterm or xclock should run with no error messages. If the DISPLAY is set to the local machine, the application should become visible on the console. If the DISPLAY is not set, or is set incorrectly, an error message such as "Can't open display: ..." should be printed. If the DISPLAY is set correctly but the client does not have permission to access the X server, a more explicit error message is displayed, for example:

  Xlib: connection to "..." refused by server
  Xlib: Client is not authorized to connect to Server
  Xt error: Can't open display: ...

Access control problems can be resolved using one of two X Window System security mechanisms: xhost or xauth.

Since X server access can be controlled on a per-user basis, when testing X server access from the command line it is important to test using the same user ID that is used to run the servlet engine. Web server and servlet engine processes are often run under a special user ID, such as apache or oracle. Before testing X server access from a servlet engine environment, it is important to verify that the appropriate user does indeed have access to the X server. The easiest way to test this is to log in using the user ID that is used to run the servlet engine and to test X server access from the command line by running one of the standard X client applications. Typically, if the console owner is a different user than the servlet engine process owner, some access control configuration (via xhost or xauth) is necessary, since by default only the console owner has access to the X server.

Testing the Connection in a Servlet Environment

Once X server access has been verified by running some X client application from the command line, X server access from the servlet engine should be tested. Writing a servlet or Java Server Page (JSP) which tests the X server access is easy, as a single AWT call is sufficient to force AWT to establish the X server connection. The following servlet calls java.awtGraphicsEnvironment.getLocalGraphicsEnvironment(), which forces AWT to connect to the X server:

  import java.io.IOException;
  import java.io.PrintWriter;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  public class TestServlet extends HttpServlet
  {
    public void service(
      HttpServletRequest request, 
      HttpServletResponse response
      ) throws ServletException, IOException
    {
      // This code will force AWT to connect to the X server
      java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
  
      // Set the content type
      response.setContentType("text/html");
  
      // Get the writer
      PrintWriter out = response.getWriter();
  
      // Send some content
      out.println("<html><body><h1>Hello, world!</h1></body></html>");
    }
  }

The following JSP accomplishes the same result:

  <% java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); %>

  <html>
  <body>
  <h1>Hello, world!</h1>
  </body>
  </html>

Before attempting to test the X server connection from within a servlet engine, be sure that the DISPLAY environment variable is set in the appropriate servlet engine configuration file.

If the X server connection is established, getLocalGraphicsEnvironment() returns successfully and the "Hello, world!" message is sent back to the browser. If the X server connection can not be established, one of several error messages may occur.

If the DISPLAY environment variable is not set at all, AWT sometimes reports a NoClassDefFoundError:

  java.lang.NoClassDefFoundError: sun/awt/X11GraphicsEnvironment
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName0(Compiled Code)
  at java.lang.Class.forName(Compiled Code)
  at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:63)
  at TestServlet.service(TestServlet.java:16)

Unfortunately, this error message is somewhat misleading. This message does not actually reflect a class loading problem. The error can be avoiding by setting the DISPLAY environment variable in the appropriate configuration file.

Another common error message occurs when the DISPLAY is specified but the specified X server can not be accessed:

  Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
  at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
  at <UNLOADED Method>
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:124)
  at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:63)
  at TestServlet.service(TestServlet.java:16)

If the X server can be accessed using a command line tool such as xterm, but cannot be accessed by the same user when running within a servlet engine, the problem is likely due to xauth configuration problems discussed below.

Granting Access with Xhost

The X Window System provides two built-in security mechanisms. The xhost tool is used to control machine-level security. The xauth tool is used to control user-level security. For most configurations, using xhost to grant X server access from a specific machine is sufficient.

When the X server is first started, access is typically restricted to the local machine - and only to the console user. Other users, such as an administrator that logs on to the local machine (for example, via telnet), or even other user IDs used by the console owner (such as apache or oracle) do not have access to the X server by default.

The simplest way to grant access to the X server is to use xhost to grant access to every user on the local machine. For example, if an administrator logs in to the X server console using an administration user ID, but wants to run the servlet engine on the same machine using a different user ID, then all users on the same machine can be granted access with the following command:

  xhost + <machine name>

In the above command, the <machine name> is the name of the local machine which is running both the X server and the servlet engine. After executing this command, all users that are logged into this machine (whether via the console, telnet, remote login, etc...) will have access to the X server.

The xhost tool can also be used to grant access to all users on a remote machine. For example, if the servlet engine is running on a machine called mtier and the X server is running on a machine called xserv, the console user on the xserv machine would need to run the following command to grant access to the servlet engine running on mtier:

  xhost + mtier

Xhost can also be used to disable all access control through the command xhost +. Running this command grants access to all users on all machines on the network. However, disabling access control in this way is inherently less secure and as such should be avoided in favor of per-machine access.

Note: Each time the X server is restarted, the Xhost access control is reset to its default state. That is, after restarting the X server, only the console user can access the X server, even if the Xhost tool was used in the previous session to grant wider access. So, the appropriate Xhost command must be run every time the X server is restarted.

Granting Access with Xauth

Although xhost + <local machine name> is by far the easiest way to grant X server access, it does grant somewhat wider access than is actually necessary, since xhost grants machine-level access. The xauth tool can be used to grant access to specific users. For example, xauth can be used to grant access to the specific user ID that is used to run the servlet engine, without providing access to all other users on the same machine.

The xauth security mechanism uses a secret "cookie" that is used to identify authorized users. When the X server is started, the cookie is determined and is written to an .Xauthority file in the console user's home directory. Only users which know the cookie can access the X server. By default, this means that only the console user can access the X server.

Actually, in some circumstances, access may be denied to the console user even if the .Xauthority file contains the current cookie. When running in some servlet engines, the user's .Xauthority file can not always be located, in which case even the X server owner cannot access the X server from within the servlet engine. For example, when running Jserv in automatic mode, access to the X server is denied even to the console user. To avoid this problem, the .Xauthority file must be explicitly identified using the XAUTHORITY environment variable. If access to the X server is denied even though Jserv is run by the console user, adding the following line to jserv.properties should enable access:

   wrapper.env=XAUTHORITY=~/.Xauthority

To grant access to a user other than the X server owner, the xauth tool must be used to create a .Xauthority file for the other user. For example, assuming that the user administrator is logged into the console and the user apache is used to run the servlet engine on the same machine, the following steps can be performed to grant access to apache:

  1. As the user administrator, run the xauth tool (xauth).

  2. At the xauth> prompt, type list to list all of the cookies.

  3. Find the cookie for the local machine. It should look something like:
        machine name:0 MIT-MAGIC-COOKIE-1 34285439adcas098q2w3098qf3209412

    This is the the xuath cookie for the X server running at <machine name>:0.

  4. As the user apache, run xauth.

  5. At the xauth> prompt, add the cookie with the add command:
         xauth> add machine name:0 MIT-MAGIC-COOKIE-1 34285439adcas098q2w3098qf3209412
  6. To make sure that the cookie was added, use list to list all cookies.

  7. Save the changes and exit the xauth tool by typing exit.

As a result of this process, an .Xauthority file should be created in the home directory of the user apache with the current xuath cookie. The apache user should now be able to access the X server.

Note: the xauth cookie is typically changed each time the X server is started. As such, this process must be repeated any time the X server is restarted and should probably be automated using Unix shell scripts. A similar process can be used to grant access to specific users on remote machines. More information about how to grant xuath access to remote users and how to automate this process can be found in the xauth man page and on the Web.

Enabling Image Generation with XVFB

Not all machines meet the hardware requirements needed to run an X server. It is not uncommon for middle-tier machines hosted in data centers to lack a frame buffer or a keyboard. In this case, the X server cannot be run locally on each middle-tier machine. Instead, the X server can be run remotely on a machine which does meet the hardware requirements. However, configuring many "headless" machines to share a single remote X server can be a risky configuration, as any problems with the shared X server can affect all machines.

An alternative to the remote X server solution is to run a pseudo-X server such as the X Virtual Frame Buffer, or XVFB. Actually, XVFB is an X server. That is, XVFB processes X Window System requests and sends responses using the same network protocol as the standard X server. The main difference between XVFB and the standard X server software is that XVFB uses an in-memory virtual frame buffer instead of a hardware frame buffer. As such, XVFB can be run on almost any Unix machine, including "headless" middle-tier machines which lack a hardware frame buffer and keyboard.

The advantage of running XVFB on each headless middle-tier machine instead of using a single shared X server is that XVFB failures only affect applications running on local machine. When used in conjunction with the Image Servlet, problems caused by any X server/XVFB failures can be isolated and have little impact on the operation of the web application.

Obtaining XVFB

XVFB is a standard component of the X Window System which is developed and distributed by X.Org. X.Org distributes the X Window System in source code form to X.Org members, which includes most Unix vendors. The Unix vendors are responsible for building and distributing platform-specific X Window System binaries. These binaries are in turn shipped by the vendors with the platform-specific operating system distributions. However, not all Unix vendors distribute XVFB binaries. Some Unix vendors, such as Compaq and various Linux vendors, include XVFB as a standard operating system component. Other Unix vendors, such as HP, provide an XVFB binary via a corporate web site. Other Unix vendors, such as Sun, do not distribute XVFB binaries at all.

XVFB for Solaris is available from the Oracle Technology Network (see http://otn.oracle.com/products/ias/ias_utilities.html#xvfb).

Running XVFB

The following command line can be used to launch XVFB:

  Xvfb :1 -screen 0 1x1x24

The XVFB binary must be run as root or must have the suid bit set. The :1 argument indicates that the XVFB binary runs as server number 1 (the standard X server typically runs as server number 0). The -screen argument indicates that a single screen of size 1x1 with 24-bit pixel depth should be used. Note, since all images are generated off screen, the 1x1 screen size is sufficient for image generation purposes.

Since XVFB must remain running for the lifetime of the application, perhaps the best approach is to automatically launch XVFB during the machine's boot process. XVFB can then remain running as a background process until the machine is shut down.

Once the XVFB executable is running, client applications can connect to XVFB by setting the DISPLAY environment variable to :1. The :1 setting indicates that server number 1 (the XVFB server) on the local machine should be used for all X graphics operations. When running in Jserv, the DISPLAY environment variable should be set in jserv.properties, for example:

  wrapper.env=DISPLAY=:1

Known XVFB Issues

Offloading Image Generation with the Image Servlet

So far, all of the proposed image generation solutions require that the web application connect directly to the X server through AWT. As discussed earlier, one of the drawbacks of this intimate connection is that the X server (or XVFB process) must not be shut down for any reason while the application is running. Stopping the X server causes any connected applications to abort, and as such should be avoided at all costs.

UIX Dynamic Images provides a solution which protects the application from any X server problems - the Image Servlet. The Image Servlet processes image generation requests which are made by UIX applications over HTTP. In response to such requests, the Image Servlet generates the image if possible and streams the results back over HTTP. The generated image is then stored in the local UIX Dynamic Images cache and served up to end users as required.

Since the Image Servlet performs all of its communication over HTTP, the Image Servlet instance can be run in any servlet engine on any machine which is accessible on the network. So, for example, the Image Servlet can be deployed on a Windows machine and be used to generate images on behalf of headless Unix machines. In this scenario, no X server is necessary, as the graphics support provided by the Windows platform is sufficient for image generation.

When the Image Servlet is deployed on a Unix machine, the Image Servlet must have access to an X server (or XVFB instance). However, since the Image Servlet performs all graphics-related operations, this means that the web application no longer needs its own direct connection to the X server. Instead, the web application communicates over HTTP with the Image Servlet, which in turn maintains the X server connection. The advantage of this configuration is that the web application is protected from X server failures. When the web application has a direct connection to the X server, any X server failure causes the web application to abort. On the other hand, if the Image Servlet connects to the X server on behalf of the web application, an X server failure causes the Image Servlet to abort, but the web application can continue functioning (with image generation disabled).

Deploying the Image Servlet

The Image Servlet is an HttpServlet which can be deployed in any servlet engine. The Image Servlet class is oracle.cabo.image.servlet.ImageServlet. No servlet initialization parameters are necessary. Simply place the UIX jar files and dependencies on the class path and install the servlet into any servlet engine.

The Installation chapter provides detailed instructions on how to install UIX-based web applications in a variety of servlet engine environments. Installing the Image Servlet is very similar to installing any UIX application. The primary differences are:

To install the Image Servlet, follow the instructions in the Installation chapter, while keeping these differences in mind.

Once the Image Servlet is up and running, you can verify that the Image Servlet is ready to generate images by pointing a web browser at the Image Servlet. For example, if the Image Servlet is bound to http://localhost:8888/image/servlet, a diagnostic message should be displayed when this URL is accessed from a web browser.

Accessing the Image Servlet

Once the Image Servlet is deployed, UIX must be notified of the location of the Image Servlet to use. This requires only a single entry in your uix-config.xml file:


 <?xml version="1.0" encoding="ISO-8859-1"?> 
 <configurations xmlns="http://xmlns.oracle.com/uix/config">
   <default-configuration>
     <image-servlet-url>http://www.example.org:8888/image/servlet</image-servlet-url>
   </default-configuration>
 </configurations>

For more information on uix-config.xml, see the Configuration chapter.

If you need to control this within Java code, the location of the Image Servlet is specified as a java.net.URL via the Configuration.IMAGE_SERVLET_URL property. For example, the following code sets an URL on the default Configuration instance:

 URL servletURL = null;

  try
  {
    servletURL = new URL("http://localhost:8888/image/servlet");
  }
  catch (MalformedURLException e)
  {
  }

  ConfigurationImpl config = ConfigurationImpl.sharedInstance();
  config.putProperty(config.IMAGE_SERVLET_URL, servletURL);

Most applications should create and register their own Configuration instances as described in the Configuration chapter.

Once the Image Servlet is running and the URL to the Image Servlet is specified, UIX Dynamic Images will automatically redirect any image generation requests to the specified servlet.

Avoiding Image Generation through Pre-Generation

In some cases, the administrative overhead involved in configuring an X server, XVFB, or Image Servlet instance may simply not be worth the effort. UIX Dynamic Images provides one other alternative. The images used by an application can be pre-generated and bundled with the application.

When UIX Dynamic Images generates an image, it saves both the image as well as a metadata file describing the image to an image cache on the file system. The next time that the same image is requested, UIX Dynamic Images knows that the image has already been generated, and as such can avoid regenerating the same image multiple times. Since metadata describing the image is saved along with the image, images can be reused across servlet engine sessions, and can even be copied across machines.

By default, UIX Dynamic Images saves all images and image metadata files in the /cabo/images/cache directory on the web server or servlet context root directory. As the application is exercised, images are saved to this directory. After fully exercising the application, all of the images that are needed by the application should be generated. By shipping the cache directory with the application, dynamic image generation in the deployment environment, and the related configuration work, can be avoided.

Complete image pre-generation may not be possible for all applications. For example, applications which support customizations may not be able to predict all of the images that might be needed by a particular customer. Also, generating images for all supported languages can be a tedious task. However, for most applications, providing pre-generated images for at least some languages can greatly simplify the customer's deployment experience. As such image pre-generation is encouraged, at least until JDK 1.4 makes the X server configuration work unnecessary.

Recommendations

This section contains some recommendations which all application developers are encouraged to follow.

Pre-Generate Where Possible

UIX developers are encouraged to ship pre-generated image caches where possible, to simplify the deployment process. Since UIX Dynamic Images can serve up any pre-generated images without requiring access to an X server, the best out-of-the-box experience can be provided by shipping as many pre-generated images as possible. In some cases, the X server configuration may never be an issue if enough pre-generated images are provided.

The easiest way to obtain pre-generated images is to collect the images that are generated during application regression testing.

Expose Image Servlet URL

The Image Servlet provides flexibility that may be useful in many deployment environments. It also provides a more stable deployment configuration, as the web application is isolated from the X server by the Image Servlet. As such, deployers should be given a choice over whether the Image Servlet should be used.

For UIX Controller-based applications, the deployer can configure the Image Servlet URL through the oracle.cabo.image.servletURL initialization parameter. However, all other applications must specify the Image Servlet URL programmatically via the Configuration API. All UIX application developers are encouraged to expose some mechanism to allow their customers to specify a deployment environment-specific URL for the Image Servlet. For servlets, the preferred mechanism is through a servlet initialization parameter. The oracle.cabo.image.servletURL parameter name can be reused for this purpose.