BEA Home | Events | Solutions | Partners | Products | Services | Download | Developer Center | WebSUPPORT
| WebLogic Server Doc Home | Using ZAC | Previous Topic | Next Topic | Contents | View as PDF

Developing with WebLogic ZAC

This section describes the Application Programmatic Interface (API) for the Zero Administration Client, including the following topics:

- Introduction

- The WebLogic ZAC API

- Implementing with WebLogic ZAC

Introduction

This document describes how to use the ZAC API to ZAC-enable your Java applications. You should also be familiar writing a WebLogic client application, which introduces all of the services and facilities within the WebLogic environment.

WebLogic ZAC (Zero Administration Client), lets you automate the distribution and maintenance of your application software. ZAC removes the burden of manual software distribution, installation, re-installation, upgrades, bug-fix patches, and data distribution. It keeps your application software always up-to-date on your client machines via the Internet or intranet. ZAC's services can be made automatic and transparent to the end-user. Updates are fast and efficient, since ZAC only transmits the minimum changes required to bring each client up-to-date.

ZAC is an implementation of the W3C specification, the HTTP Distribution and Replication Protocol. In addition to a GUI wizard, the ZAC Publish Wizard, that makes it easy to publish software on a ZAC-enabled WebLogic Server. ZAC also has an API with which you can incorporate the same functionality directly into your Java applications. Note that ZAC is not supported using the 1.3.0 JDK with or without Java HotSpot TM.

Note: The JRE Update Frequency property set in the ZAC Publishing Wizard is not supported as of Version 4.5.1, and you need to use one of the following methods to update your JRE when necessary.

When a JRE is packaged with an application, it will be reinstalled on the client only if:

(a) The entire JRE installation directory is deleted from the client AND either the client executable OR the ZAC bootstrap routine is run; or

(b) A new version of the JRE library package is published on the WebLogic Server AND the bootstrap routine (not the client executable) is run from the client.

No package versioning takes place on the server (unless the version number is made part of the package name); it is only possible to "revert" a package if it has not already been published.

When to use the ZAC API

ZAC can be used as a wrapper around your existing Java applets and applications, or can be incorporated into your applications via the ZAC API. If you want to distribute and automatically update your Java software with ZAC, you do not really need to use the ZAC API; the ZAC Publish Wizard allows you to specify everything necessary to publish your application and make it available to client machines. For information on publishing applications with ZAC, see Publishing with WebLogic ZAC.

You should consider building ZAC into your Java code if you need to closely control the ZAC update services with your application. Your application can respond automatically when new updates are published, or offer more control to the user over when to accept new software updates. Another use of the ZAC API is to write applications that administer updates for other applications, or non-executable data on the client machine. For instance, maintaining a large dataset on each client machine, such as a copy of a large corporate intranet that must be kept up-to-date on every Sales person's field laptop. Downloading the entire dataset every time a change is made might take a long time over the network, but when a ZAC-enabled application finds newly published versions, it downloads only the required changes.

How ZAC deploys applications

ZAC applications must be published on a ZAC-enabled WebLogic Server to be made available to WebLogic clients. You do not have to use the ZAC Java API in your application code in order to publish the application with ZAC; as part of the publishing process, ZAC supplies a tiny bootstrap executable that your client can download, and the bootstrapper will then handle initial download, subsequent updates (configurable), and starting of the published application. This bootstrap executable is compiled for each target platform's operating system, so that Java need not be pre-installed on the client.

You publish the bootstrap by posting a link for the executable from any web page; after the user downloads and runs the bootstrapper, an icon is installed on the desktop that the user can double-click to start the initial installation and subsequently to start the application itself. Before starting the published application, the bootstrapper checks for new updates on the server and upgrades the application as necessary. Subsequent updates will be more efficient since only the changes are downloaded.

You can exercise more control over when an application is updated by using the ZAC API to add code to your Java client. When the bootstrapper is generated by the ZAC Publish Wizard (see Using the Publish Wizard), you may uncheck the option so that it will not automatically update the client from a newly published ZAC package; rather, you can add the ZAC update functionality to the application itself, enabling the user can choose when to update from the application's user interface.

The WebLogic ZAC API

Package-weblogic.zac

>     Class java.lang.Object
>       Class weblogic.zac.ZAC
>         (implements weblogic.drp.events.ProgressListener,
>         weblogic.drp.common.DRPConstants)
>       Class weblogic.zac.ZACLog

Use the ZAC class to manage ZAC packages on the client machine from within your application. Most likely, you will use only a very small subset of the methods in this class, such as the update() method to update the ZAC package on the client machine from the publishing WebLogic Server.

The ZACLog class provides information about the published ZAC packages in use by your client, and the most recent updates for each of these packages.

Implementing with WebLogic ZAC

This section discusses the following topics:

- Importing Packages

- Updating ZAC Applications

- Using ZACLog to Query the Latest Updates

- Restarting a ZAC Client Application

- Using WebLogic Events with ZAC

- Packaging Libraries with Your ZAC Application

Importing Packages

To use the ZAC class in your Java application or applet you must import the WebLogic ZAC package, as well as the package that supports all WebLogic clients. For example:

>     import weblogic.zac.*;
>     import weblogic.common.*;

Updating ZAC Applications

Your application should create and use a ZAC object to reference and update a ZAC package. The ZAC constructor requires that you specify the following details about the ZAC package you want to administer:

- The address of the WebLogic Server where the ZAC package is published

- The name of the published ZAC package on the WebLogic Server

- The local installation directory of the ZAC package on the client machine

You can use the ZACLog class to obtain information about each ZAC package in use by your client application, and then pass that information to the ZAC constructor. The code below illustrates how you might do this:

>       // Find the address of each publishing server
>       // and connect to each in turn
>       ZACLog zl;
>       ZAC zac;
>       // Obtain an enumeration of ZACLog(s) for each published
>       // package this application is dependent upon
>       Enumeration enum = ZACLog.getUpdateLogs();
>       while (enum.hasMoreElements()) {
>         zl = (ZACLog)enum.nextElement();
>         // Construct a URL of the server address from each ZACLog
>         t3url = "t3://" + zl.getZACHost() + ":" + zl.getZACPort() + '/';
>         // Create a new ZAC object, and connect to the server.
>         zac = new ZAC(zl.getZACHost(),
>                       zl.getZACPort(),
>                       zl.getZACName(),
>                       zl.getLocalDirectory());
>         // Now perform the ZAC package update...
>         zac.update();
>       }

In the above example, we use the ZACLog.getUpdateLogs() method to examine an enumeration of ZACLog instances. Each ZACLog instance refers to a separate ZAC package that this application depends upon. We use the properties of each ZACLog to create a ZAC object for each ZAC package. We then update each ZAC package using the zac.update() method.

If your application administers another ZAC package that it is not dependent upon, then the ZACLog.getUpdateLogs() method will be ineffective, since it only returns a ZACLog for each package that the current ZAC application uses. In this case, your application will need to pass explicit details about the publishing WebLogic Server and the name of the package to the constructor.

Once you have created a ZAC object, you may call its update() method. This checks for a newly published ZAC package, and updates the package on the client if necessary.

Using ZACLog to Query the Latest Updates

The details of each ZAC update are recorded into a set of ZACLog objects. Updates can occur when the application starts, or when the application initiates an update itself (as above). You obtain an Enumeration of ZACLog object from the latest update using the ZACLog.getUpdateLogs() static method. All previous ZACLog records are discarded; it is the responsibility of the application to maintain a record of updates if required.

The Enumeration returned by a call to the getUpdateLogs() method contains one ZACLog for each package that the application is dependent upon. You might process this Enumeration as shown in the following code:

>       // Obtain Enumeration of ZACLog(s)
>       Enumeration enum = ZACLog.getUpdateLogs();
>       ZACLog zl;
>       // Process each ZACLog...
>       while(enum.hasMoreElements()) {
>         zl = (ZACLog)enum.nextElement();
>         // Print the ZAC package name
>         System.out.println("ZAC log for package" + zl.getZACName());

>         // Print the ZAC update status
>         switch(zl.getUpdateStatus()) {
>         case ZACLog.UPDATE_NONE:
>           System.out.println("ZAC update status: No update was
>     necessary.");
>           break;
>         case ZACLog.UPDATE_FAILURE:
>           System.out.println("ZAC update status: FAILED!");
>           System.out.println("Details: " + zl.getUpdateFailureString());
>           break;

>         // This is where the real work starts
>         case ZACLog.UPDATE_SUCCESS:
>           System.out.println("ZAC update status: Completed
>     successfully");

>           // Get info about the update
>           int fileCnt = zl.getUpdateFileCount();
>           long binarySize = zl.getUpdateByteCount();

>           String details;

>           if (fileCnt == 0) {
>             details = "Update Success, 0 files updated, 0 bytes
>     transferred.";
>           }
>           else {
>             if (fileCnt == 1) {
>               details = "Update Success, 1 file updated, ";
>             }
>             else {
>               details = "Update Success, " + fileCnt + " files updated, ";
>             }

>             if (binarySize > 1000) {
>               details += (binarySize / 1000) + " KBytes transferred.";
>             }
>             else {
>               details += (binarySize) + " bytes transferred.";
>             }
>           }
>           System.out.println("Details: " + details);

>           // Report which files were updated
>           System.out.println("The following files were updated:");
>           Enumeration fl = zl.getUpdateFileList();
>           File zacroot = zl.getLocalDirectory();
>           while (fl.hasMoreElements()) {
>             String path = (String)fl.nextElement();
>             File updated = new File(zacroot, path);
>             System.out.println("Updated: " + updated.getAbsolutePath());
>           }
>         }
>       }

The example above shows how to retrieve detailed information about the latest ZAC update from the ZACLog. First, the name of the ZAC package to which the ZACLog refers is obtained and printed out to the console. Next, the status of the ZAC update is queried and a switch statement is used to act upon the possible outcomes. The getUpdateStatus() method will return one of the following constants:

  ZACLog.UPDATE_NONE

  No update was necessary; the package was up-to-date.

  ZACLog.UPDATE_FAILURE

  The update failed in some way. More information can be obtained about the failure by calling the getUpdateFailureString() and the getUpdateFailure() methods. This returns a String containing a stack trace and the Throwable exception that occurred respectively. An update may fail due to a server error, a communications interruption, or a lack of disk space on the client machine.

  ZACLog.UPDATE_SUCCESS

  Indicates that a successful update occurred. Several other pieces of information about the ZACLog are available when an update is successful, such as the size of the data transferred and the files that were updated.

The names of the updated files returned by the getUpdateFileList() method are relative to the installation directory into which the ZAC package was installed. In the above example, a FILE object is constructed from the relative pathname, appended to the path returned by the getLocalDirectory() method, giving the full path name of each file.

Changes that an update makes to an application will not be reflected until it is restarted.

Restarting a ZAC Client Application

If your client application was started using the ZAC bootstrapper, you may request it to be restarted by sending a ZAC.ZAC_EXIT_RESTART flag to the System.exit() method. Here is an example:

>       System.exit(ZAC.ZAC_EXIT_RESTART);

Since, the ZAC bootstrapper was used to start the application, it can also catch the exit status. When it receives the ZAC.ZAC_EXIT_RESTART status, it restarts the application. Prior to restarting, the bootstrapper will also update the application and other ZAC packages it is dependent upon if configured to do so. You usually configure this when you publish the application with the ZAC Publish Wizard.

Using WebLogic Events with ZAC

You can incorporate WebLogic Events into your client application to have it respond instantly when a new version of a ZAC package is published on a WebLogic Server.

Note: WebLogic Events are deprecated with the 6.0 release of WebLogic Server.

The WebLogic Server generates a new event for the WEBLOGIC.ZAC.UPDATE.myPackage topic when a new update of the package named myPackage is published on the WebLogic Server. When your application registers an interest in the event topic WEBLOGIC.ZAC.UPDATE and sets the sink flag to true, your application is notified when a new package version is published. For information about events, see Using WebLogic Events.

The following code shows how a client connects to the WebLogic Server and registers interest in the publication of a ZAC package. In this example, the client registers interest in the "WEBLOGIC.ZAC.UPDATE.myPackage" event topic.

>       ZACLog zl;
>       String t3url = null;
>       while (enum.hasMoreElements()) {
>         ZACLog zl = (ZACLog)enum.nextElement();
>         // Test for a match to the package name
>         if (zl.getZACName().equals("myPackage")) {
>           t3url = "t3://" + zl.getZACHost() +
>                   ":" + zl.getZACPort() + '/';
>           break;
>         }
>       }

>       if (t3url != null) {
>         // Now connect to the server.
>         T3ServicesDef t3services = getT3Services(t3url);

>         // Register interest in the update event...
>         // Create an Evaluate object to be used in the registration
>         Evaluate eval =
>           new Evaluate("weblogic.event.evaluators.EvaluateTrue");

>         // Create an Action object parameter for the registration
>         // To have the notification returned to the client, the client
>         // must implement ActionDef and the Action must be instantiated
>         // with the client object, i.e. "this".
>         Action act = new Action(this);
>         // Create the EventRegistrationDef object
>         EventRegistrationDef erd =
>           t3services.events()
>             .getEventRegistration("WEBLOGIC.ZAC.UPDATE.myPackage",
>                                   eval, act, true, true, 1);

>         // Finally, we register interest in the event
>         int regid = erd.register();
>       }

The client must implement the action() method, part of the ActionDef interface. In the action() method, you client may act upon notification of a published update, and update itself. Here is an example:

>       public synchronized void action(EventMessageDef ev) {
>         System.out.println("Notification of an " +
>                            ev.getTopic() +
>                            " Event received.");
>         zacUpdate = true;
>         notifyAll();
>         }

The action() method is usually synchronized to prevent multiple threads from executing in it simultaneously. In this implementation, we simply print a message to the console, set the private variable zacUpdate to true, and wake up other application threads to handle the event by calling the notifyAll() method. The zacUpdate variable indicates to the suspended application thread that is should perform a ZAC update.

Note: It is not good practice to perform time-consuming operations in a callback method such as this, since the event notification is called from another thread. Small operations that return quickly are acceptible, but in our case, we may decide to perform a ZAC update, which may take some time so is best handled from one of the client application threads.

Packaging Libraries with Your ZAC Application

Your published ZAC application should be published with any required libraries that it depends upon. The ZAC subset of the Weblogic classes is distributed with any ZAC application by default and is necessary for its operation, regardless of whether the application uses the ZAC API or not. These classes are downloaded to the client in the zac.jar file and placed in a lib directory below the ZAC application installation directory. For this reason, applications that use the ZAC API need not deploy the ZAC classes, since they are supplied by default.

However, applications that use WebLogic resources that are not included in the zac.jar file, or any other non-default libraries or packages, must be configured so that those resources are also installed on the client machine. This can be achieved in two ways, described below.

Including Libraries within a ZAC Package

If you include the required classes, jars, libraries, or any other data under your ZAC application's publish directory, they will automatically be deployed with that package and installed under the same relative package directory on the client machine.

If you application depends on classes outside of the application package, you must make sure that they are in the CLASSPATH of the ZAC application. You can specify a runtime CLASSPATH for your application in the ZAC Publish Wizard (see Using the Publish Wizard); the CLASSPATH must be specified relative to the root installation directory.

Making a ZAC Package Depend upon Another ZAC Package

If you intend to publish several ZAC applications that use the same libraries or classes, you can save disc space on the client machine by publishing the shared components as a separate package. You then make each ZAC package dependent upon the shared package. The packages that your application depends upon, as well as your application itself, will be included each time your client application is updated.

When ZAC installs a package on a client, everything is installed under a root directory. The ZAC application you originally published will be installed in a subdirectory of the same name under this root directory. Any other packages will also be stored in subdirectories with the same name as the package under this root directory. ZAC only has knowledge of the packages it has installed under the root directory. The location of the install-root directory is either defined when the package is published, or the package may be configured to allow the user to choose its location at install time.

In this example, the ZAC root directory is called ZacExamples, under which there are two packages, ZSimple and WeblogicClasses. In this case, the ZSimple package might depend upon WeblogicClasses.

For two ZAC packages to share a dependency on another package, both ZAC packages must be installed under the same root directory.

This illustration shows the directory structure when another package (called AnotherOne) has been installed under the same root directory. Both packages can share dependency on the same WeblogicClasses package, and both will update it if necessary.

Note: If not installed under the same root, each will maintain separate copies of the same package under their corresponding root directories. This is the default behavior; otherwise, a ZAC package might unintentionally update a package that another package was dependent upon.

Copyright © 2001 BEA Systems, Inc. All rights reserved. Required browser: Netscape 4.0 or higher, or Microsoft Internet Explorer 4.0 or higher.