WebObjects 5.2

com.webobjects.foundation
Class NSLog

java.lang.Object
  |
  +--com.webobjects.foundation.NSLog

public final class NSLog
extends Object

NSLog is a static class that is used to access the WebObjects Foundation logging system. It allows you to log debugging messages and provides functionality for controlling the level and focus of debugging output. Logging with NSLog offers greater flexibility and integration with the WebObjects runtime and debugging system than does logging with System.out, System.err, or java.rmi.server.LogStream.

By specifying debug groups and the debug level using NSLog's methods, you can control the scope and granularity of debugging output . Perhaps you are only interested in seeing debugging output that relates to the Enterprise Objects Framework, or more specifically, debugging output that relates to database fetches. NSLog is designed to allow you to specify the output based on predefined debug groups and levels.

Although NSLog provides functionality for advanced debugging, it is also as simple to use as System.out.:

NSLog.out.appendln("WebObjects");

The above code outputs "WebObjects" in the console by default, but output can be directed to custom NSLog.Logger classes.

The logging system is made up of three classes: NSLog, NSLog.Logger, and NSLog.PrintStreamLogger. NSLog provides methods for controlling the level (amount of information sent to the logger) and focus (scope of the information sent to the logger) of debugging output. NSLog.Logger is an abstract class that provides the basic functionality for NSLog. NSLog.PrintStreamLogger is a subclass of NSLog.Logger and appends information to the debug logger which is directed to a java.io.PrintStream pointing to System.out, System.err, or to a custom java.io.PrintStream.

The NSLog class cannot be instantiated.

Redirecting the Output of NSLog

NSLog offers the ability to redirect output to custom java.io.PrintStreams, such as local files. Note that setting the WOOutputPath property in WOApplication will automatically redirect output from NSLog to the specified file. This example illustrates manually appending error output to the local file "/Local/Users/log.txt":

// New print stream based on path.
PrintStream aStream = NSLog.printStreamForPath("/Local/Users/log.txt");

if (aStream != null) {
  // Direct output to the custom PrintStream.
  ( (NSLog.PrintStreamLogger) NSLog.err).setPrintStream(aStream);
}

// Enable verbose logging.
NSLog.err.setIsVerbose(true);

// Outputs "[2000-10-18 09:01:00 GMT] <main> WebObjects"
NSLog.err.appendln("WebObjects");

// Disables logging.
NSLog.err.setIsEnabled(false);

// Outputs nothing, since logging is disabled.
NSLog.err.appendln("Enterprise Objects");

NSLog also allows developer to use their own custom subclasses of NSLog.Logger or NSLog.PrintStreamLogger to implement custom behavior. By subclassing NSLog.Logger instead of NSLog.PrintStreamLogger, you can provide custom logging implementations that are not based on java.io.PrintStreams, such as outputting to email, Swing windows, etc. In the following example, a custom Logger is used to capture error messages:

// The developer has created a custom subclass of NSLog.Logger called MyMailLogger
MyMailLogger aLogger = new MyMailLogger("admin@mac.com", "smtp.mac.com");

// Use the custom logger for all error messages
// NSLog.out and NSLog.debug still use the default NSLog.PrintStreamLogger implementation
NSLog.setErr(aLogger);

Debug Groups

To control the scope of the debug information that is sent to the logger, NSLog declares a number of debug groups. By default, logging is enabled for all the debug groups declared by NSLog, except DebugGroupParsing. All the WebObjects frameworks, including Foundation and EOF, use NSLog for debugging, and rely on debug groups to control the scope of their debug logging.

As an example, this code uses debug groups to disable logging for debug information related to the Enterprise Objects Framework:

NSLog.refuseDebugLoggingForGroups(NSLog.DebugGroupEnterpriseObjects)

Before sending debug information to the logger, all classes that log EOF-related debug information check to see if debug logging is allowed for EOF-related issues using one of the debugLoggingAllowedFor... methods. Since the above code removed the DebugGroupEnterpriseObjects bit from the bit mask, EOF-related issues won't be sent to the logger.

Debug Levels

To control the granularity of debug information that is sent to the logger, NSLog declares a number of debug levels. A debug level specifies the importance of the information displayed in a message. These messages may be the result of exceptions or errors, but may also just be informational, such as printing variable values.

When an exception is encountered, the exception message should always be output, but the stack trace should only be output if a particular level of debugging is requested: :

} catch (Exception e) {
  NSLog.err.appendln("Exception encountered: " + e.getMessage());
  if (NSLog.debugLoggingAllowedForLevel(DebugLevelCritical) {
    NSLog.debug.appendln(e);
  }
}

When you desire to see the value of a variable at particular points in the application, DebugLevelInformational can be used to control logging. Logging the values of variables can be expensive, so it is prudent to wrap this kind of logging in a debug level conditional. For instance, you should conditionalize the logging of values in an array like this:

// Assuming declaration of int[] anArray = new int[10];
if debugLoggingAllowedForLevel(DebugLevelInformational) {
  for (i = 0, i < 9, i++) {
    NSLog.out.appendln(anArray[i]);
  }
}

DebugLevelDetailed should be used to conditionalize logging for computationally intensive tasks, such as JDBC function calls.

Note that if the allowed debug level is specified using the setAllowedDebugLevel method, messages of that level and lower will be logged. That is, DebugLevelDetailed will also log messages of level DebugLevelInformational and messages of level DebugLevelCritical. Likewise, DebugLevelInformational will also log messages of level DebugLevelCritical, but not messages of level DebugLevelDetailed.

Creating Custom Debug Group Sets

NSLog uses a bit mask to specify a set of debug groups, which means that you can easily create a custom debug groups mask for more flexible logging. For instance, if the requirement is logging debugging output only for EOF-related issues and EOModel-related issues, you can simply bitwise inclusive OR the groups together using the "|" operator in Java. That creates a debug groups mask which can be used to more flexibly monitor and log errors relating to those two issues. To do this:

// Create a custom debug groups mask.
NSLog.setAllowedDebugGroups(NSLog.DebugGroupEnterpriseObjects | NSLog.DebugGroupModel);
...
// Later, add NSLog.DebugGroupWebObjects
NSLog.allowDebuggingForGroups(NSLog.DebugGroupWebObjects);

In addition to the debug groups provided by WebObjects, new debug groups can be added. The high 32 bits (i.e. bits 32 - 63) are available to developers. The low bits are reserved by WebObjects. An example of declaring a new debug group:

public static final long DebugGroupCustomGroup = 1L << 45;

NSLog From the Command Line

Debug groups and levels can be enabled from the command line, or in Properties files by setting values for the properties NSDebugLevel and NSDebugGroups. You can enable multiple debug groups by name, by bit position, or both. A series of examples:

To start with the default set of Debug Groups, and the Debug Level set to Informational:
% ./MyJavaWOApp -DNSDebugLevel=NSLog.DebugLevelInformational
To start with the default Debug Level, and the Debug Groups set to DebugGroupResources:
% ./MyJavaWOApp -DNSDebugGroups=NSLog.DebugGroupResources
To start with the default Debug Level, and the Debug Groups set to all mask values from 10 to 63:
% ./MyJavaWOApp -DNSDebugGroups=10:
To start with the default Debug Level, and the Debug Groups set to all mask values from 0 to 23:
% ./MyJavaWOApp -DNSDebugGroups=:23
To start with the default Debug Level, and the Debug Groups set to all mask values between 10 and 23:
% ./MyJavaWOApp -DNSDebugGroups=10:23
To start with the default Debug Level, and the Debug Groups set to DebugGroupResources:
% ./MyJavaWOApp -DNSDebugGroups="(NSLog.DebugGroupResources, NSLog.DebugGroupWebObjects)"
To start with the default Debug Level, and the Debug Groups set to mask values 0 to 2, 10 to 14, 18, and 29 to 63, as well as DebugGroupJSPServlets:
% ./MyJavaWOApp -DNSDebugLevel=NSLog.DebugLevelInformational -DNSDebugGroups="(:2, 10:14, 18, NSLog.DebugGroupJSPServlets, 29:)"

Constants

The following table displays the values of different debug groups and debug levels:

ConstantValue
DebugGroupApplicationGeneration3
DebugGroupArchiving6
DebugGroupAssociations19
DebugGroupComponentBindings9
DebugGroupControllers20
DebugGroupComponents26
DebugGroupDatabaseAccess16
DebugGroupDeployment22
DebugGroupEnterpriseObjects1
DebugGroupFormatting10
DebugGroupIO13
DebugGroupJSPServlets27
DebugGroupKeyValueCoding8
DebugGroupModel15
DebugGroupMultithreading4
DebugGroupParsing23
DebugGroupQualifiers11
DebugGroupReflection24
DebugGroupRequestHandling25
DebugGroupResources5
DebugGroupRules21
DebugGroupSQLGeneration17
DebugGroupTiming14
DebugGroupUserInterface18
DebugGroupValidation7
DebugGroupWebObjects2
DebugGroupWebServices2
DebugLevelOff0
DebugLevelCritical1
DebugLevelInformational2
DebugLevelDetailed3

See Also:
NSLog.Logger, NSLog.PrintStreamLogger

Inner Class Summary
static class NSLog.Logger
          NSLog.Logger is an abstract class that specifies the core functionality for NSLog.
static class NSLog.PrintStreamLogger
          NSLog.PrintStreamLogger is a concrete subclass of NSLog.Logger.
 
Field Summary
static NSLog.Logger debug
          Logger sending error to system error file.
static long DebugGroupApplicationGeneration
          The debug group for logging of general application generation issues.
static long DebugGroupArchiving
          The debug group for logging of encoding and decoding issues.
static long DebugGroupAssociations
          The debug group for logging of association exceptions and problems.
static long DebugGroupComponentBindings
          The debug group for logging of binding exceptions and problems.
static long DebugGroupComponents
          The debug group for logging issues related to components and component definitions.
static long DebugGroupControllers
          The debug group for logging of controller exceptions and problems.
static long DebugGroupDatabaseAccess
          The debug group for logging of database access exceptions and problems.
static long DebugGroupDeployment
          The debug group for logging of Monitor, wotaskd, and deployment related issues.
static long DebugGroupEnterpriseObjects
          The debug group for enabling logging of general EOF issues.
static long DebugGroupFormatting
          The debug group for logging of formatting exceptions and problems.
static long DebugGroupIO
          The debug group for logging of I/O exceptions and problems.
static long DebugGroupJSPServlets
          The debug group for logging issues related to JSP or Servlet integration.
static long DebugGroupKeyValueCoding
          The debug group for logging of key value coding exceptions and problems
static long DebugGroupModel
          The debug group for logging of EOModel exceptions, problems, and inconsistencies.
static long DebugGroupMultithreading
          The debug group for logging of threading issues.
static long DebugGroupParsing
          The debug group for logging of HTML parsing issues and other HTML-related issues.
static long DebugGroupQualifiers
          The debug group for logging of qualifier issues
static long DebugGroupReflection
          The debug group for logging of class introspection issues.
static long DebugGroupRequestHandling
          The debug group for logging of issues related to the request-response loop.
static long DebugGroupResources
          The debug group for logging of resource loading/lookup exceptions and problems.
static long DebugGroupRules
          The debug group for logging of dynamic rule system issues and logging issues
static long DebugGroupSQLGeneration
          The debug group for logging of SQL generation issues and logging.
static long DebugGroupTiming
          The debug group for logging of dynamic rule system issues.
static long DebugGroupUserInterface
          The debug mask for logging of widget set and view exceptions and problems.
static long DebugGroupValidation
          The debug group for logging of validation exceptions and problems.
static long DebugGroupWebObjects
          The debug group for enabling logging of general WebObjects framework issues.
static long DebugGroupWebServices
          The debug group for logging issues related to Web Services.
static int DebugLevelCritical
          Logs debug messages that should not be sent in non-debug mode, such as stack traces.
static int DebugLevelDetailed
          Logs debug messages that qualify as computationally intensive, such as JDBC function calls.
static int DebugLevelInformational
          Logs debug messages that don't qualify as computationally intensive.
static int DebugLevelOff
          Logs no messages.
static NSLog.Logger err
          Print stream logger sending output to system error file.
static NSLog.Logger out
          Print stream logger sending output to system output file.
 
Constructor Summary
NSLog()
           
 
Method Summary
static void allowDebugLoggingForGroups(long aDebugGroups)
          Enables logging for the debug group or the debug groups mask specified by aDebugGroups by adding it (via bitwise inclusive OR) to the debug groups mask.
static int allowedDebugLevel()
           
static boolean debugLoggingAllowedForGroups(long aDebugGroups)
          Returns true if the groups specified by aDebugGroups are enabled (that is, the debug groups are part of the debug groups bit mask).
static boolean debugLoggingAllowedForLevel(int aDebugLevel)
          Debug logging is allowed if aDebuglevel is less than or equal to the debug level set by setAllowedDebugLevel.
static boolean debugLoggingAllowedForLevelAndGroups(int aDebugLevel, long aDebugGroups)
          Debug logging is allowed if the aDebugLevel is less than or equal to current debug level, and if the aDebugGroups mask is included in the currently set debug groups.
static PrintStream printStreamForPath(String aPath)
          This will return a java.io.PrintStream object representing the file specified by aPath.
static void refuseDebugLoggingForGroups(long aDebugGroups)
          Disables debug logging for the debug groups mask specified by aDebugGroups.
static void setAllowedDebugGroups(long aDebugGroups)
          Determines the set (the bit mask) of allowed debug groups.
static void setAllowedDebugLevel(int aDebugLevel)
          Sets the debug level to aDebugLevel.
static void setDebug(NSLog.Logger instance)
          Sets the debugging logger NSLog.debug to instance.
static void setErr(NSLog.Logger instance)
          Sets the logger NSLog.err to instance.
static void setOut(NSLog.Logger instance)
          Sets the logger NSLog.out to instance.
static String throwableAsString(Throwable t)
          Returns the stack trace of t as a string.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DebugGroupApplicationGeneration

public static final long DebugGroupApplicationGeneration
The debug group for logging of general application generation issues.

DebugGroupArchiving

public static final long DebugGroupArchiving
The debug group for logging of encoding and decoding issues.

DebugGroupAssociations

public static final long DebugGroupAssociations
The debug group for logging of association exceptions and problems.

DebugGroupComponentBindings

public static final long DebugGroupComponentBindings
The debug group for logging of binding exceptions and problems.

DebugGroupComponents

public static final long DebugGroupComponents
The debug group for logging issues related to components and component definitions.

DebugGroupControllers

public static final long DebugGroupControllers
The debug group for logging of controller exceptions and problems.

DebugGroupDatabaseAccess

public static final long DebugGroupDatabaseAccess
The debug group for logging of database access exceptions and problems.

DebugGroupDeployment

public static final long DebugGroupDeployment
The debug group for logging of Monitor, wotaskd, and deployment related issues.

DebugGroupEnterpriseObjects

public static final long DebugGroupEnterpriseObjects
The debug group for enabling logging of general EOF issues.

DebugGroupFormatting

public static final long DebugGroupFormatting
The debug group for logging of formatting exceptions and problems.

DebugGroupIO

public static final long DebugGroupIO
The debug group for logging of I/O exceptions and problems.

DebugGroupJSPServlets

public static final long DebugGroupJSPServlets
The debug group for logging issues related to JSP or Servlet integration.

DebugGroupKeyValueCoding

public static final long DebugGroupKeyValueCoding
The debug group for logging of key value coding exceptions and problems

DebugGroupModel

public static final long DebugGroupModel
The debug group for logging of EOModel exceptions, problems, and inconsistencies.

DebugGroupMultithreading

public static final long DebugGroupMultithreading
The debug group for logging of threading issues.

DebugGroupParsing

public static final long DebugGroupParsing
The debug group for logging of HTML parsing issues and other HTML-related issues.

DebugGroupQualifiers

public static final long DebugGroupQualifiers
The debug group for logging of qualifier issues

DebugGroupReflection

public static final long DebugGroupReflection
The debug group for logging of class introspection issues.

DebugGroupRequestHandling

public static final long DebugGroupRequestHandling
The debug group for logging of issues related to the request-response loop.

DebugGroupResources

public static final long DebugGroupResources
The debug group for logging of resource loading/lookup exceptions and problems.

DebugGroupRules

public static final long DebugGroupRules
The debug group for logging of dynamic rule system issues and logging issues

DebugGroupSQLGeneration

public static final long DebugGroupSQLGeneration
The debug group for logging of SQL generation issues and logging.

DebugGroupTiming

public static final long DebugGroupTiming
The debug group for logging of dynamic rule system issues.

DebugGroupUserInterface

public static final long DebugGroupUserInterface
The debug mask for logging of widget set and view exceptions and problems.

DebugGroupValidation

public static final long DebugGroupValidation
The debug group for logging of validation exceptions and problems.

DebugGroupWebObjects

public static final long DebugGroupWebObjects
The debug group for enabling logging of general WebObjects framework issues.

DebugGroupWebServices

public static final long DebugGroupWebServices
The debug group for logging issues related to Web Services.

DebugLevelCritical

public static final int DebugLevelCritical
Logs debug messages that should not be sent in non-debug mode, such as stack traces. Logging with this debug level is not likely to affect the performance of the application.

DebugLevelDetailed

public static final int DebugLevelDetailed
Logs debug messages that qualify as computationally intensive, such as JDBC function calls. Logging with this debug level will slow the application considerably.

DebugLevelInformational

public static final int DebugLevelInformational
Logs debug messages that don't qualify as computationally intensive. Logging with this debug level will slow the application only moderately.

DebugLevelOff

public static final int DebugLevelOff
Logs no messages. The default.

debug

public static volatile NSLog.Logger debug
Logger sending error to system error file.

err

public static volatile NSLog.Logger err
Print stream logger sending output to system error file.

out

public static volatile NSLog.Logger out
Print stream logger sending output to system output file.
Constructor Detail

NSLog

public NSLog()
Method Detail

allowDebugLoggingForGroups

public static void allowDebugLoggingForGroups(long aDebugGroups)
Enables logging for the debug group or the debug groups mask specified by aDebugGroups by adding it (via bitwise inclusive OR) to the debug groups mask. For instance, to allow debug logging for EOF-related issues, add the EOF debug group, DebugGroupEnterpriseObjects to the mask:
NSLog.allowDebugLoggingForGroups(DebugGroupEnterpriseObjects);

This differs from setAllowedDebugGroups in that allowDebugLoggingForGroups adds debug groups and debug groups masks to the existing bit mask in NSLog. setAllowedDebugGroups, however, replaces the existing bit mask in NSLog with the debug group or debug groups mask it is passed. For example,

// This will add the EOF debug group to the mask: NSLog.allowDebugLoggingForGroups(DebugGroupEnterpriseObjects); // This will replace all debug groups and masks in // the bit mask with the EOF debug group NSLog.setAllowedDebugGroups(DebugGroupEnterpriseObjects);

Use the refuseDebugLoggingForGroups method to disallow specific debug groups.

By default, logging is allowed for all debug groups. If you set the debug level to be high (for example, DebugLevelDetailed), the debugging output may be overwhelming.

Parameters:
aDebugGroups - a customized set of debug groups
See Also:
setAllowedDebugGroups(long aDebugGroups), allowDebugLoggingForGroups(long aDebugGroups), refuseDebugLoggingForGroups(long aDebugGroups), NSLog

allowedDebugLevel

public static int allowedDebugLevel()
Returns:
the allowed debug level

debugLoggingAllowedForGroups

public static boolean debugLoggingAllowedForGroups(long aDebugGroups)
Returns true if the groups specified by aDebugGroups are enabled (that is, the debug groups are part of the debug groups bit mask). This method will return false if the debug level is set to DebugLevelOff. See "Creating Custom Debug Groups" in the class concepts for examples of how to create a custom debug groups bitmask.
Parameters:
aDebugGroups - a customized set of debug groups
Returns:
true if the debug groups specified by aDebugGroups are enabled (that is, the debug groups are part of the debug groups bit mask)
See Also:
setAllowedDebugGroups(long aDebugGroups)

debugLoggingAllowedForLevel

public static boolean debugLoggingAllowedForLevel(int aDebugLevel)
Debug logging is allowed if aDebuglevel is less than or equal to the debug level set by setAllowedDebugLevel. This is because the highest debug level, DebugLevelDetailed, implies DebugLevelInformational which implies DebugLevelCritical. See "Debug Levels" in the class concepts for more information.
Parameters:
aDebugLevel - level of debug required
Returns:
true if debug logging is allowed for aDebugLevel
See Also:
DebugLevelDetailed, DebugLevelInformational, DebugLevelCritical, setAllowedDebugLevel(int aDebugLevel)

debugLoggingAllowedForLevelAndGroups

public static boolean debugLoggingAllowedForLevelAndGroups(int aDebugLevel,
                                                           long aDebugGroups)
Debug logging is allowed if the aDebugLevel is less than or equal to current debug level, and if the aDebugGroups mask is included in the currently set debug groups.
Parameters:
aDebugLevel - level of debug required
aDebugGroups - customized group for debug
Returns:
true if the debug groups specified by aDebugGroups are enabled, and if the debug level is less than or equal to the debug level set by setAllowedDebugLevel
See Also:
debugLoggingAllowedForLevel(int aDebugLevel), debugLoggingAllowedForGroups(long groups)

printStreamForPath

public static PrintStream printStreamForPath(String aPath)
This will return a java.io.PrintStream object representing the file specified by aPath. If the stream cannot be created, null will be returned, but no exception will be thrown.
Parameters:
aPath - path of the file
Returns:
a java.io.PrintStream to a file at the specified path or null if there is any problem with the path (i.e. it doesn't exist), or with the file at that path (i.e. it's a path to a directory, so a PrintStream can't be created for it)

refuseDebugLoggingForGroups

public static void refuseDebugLoggingForGroups(long aDebugGroups)
Disables debug logging for the debug groups mask specified by aDebugGroups.

By default, logging is allowed for all debug groups. If the debug level is set to be high (for example, DebugLevelDetailed), the debugging output may be overwhelming.

Parameters:
aDebugGroups - customized groups for debug
See Also:
allowDebugLoggingForGroups(long aDebugGroups)

setAllowedDebugGroups

public static void setAllowedDebugGroups(long aDebugGroups)
Determines the set (the bit mask) of allowed debug groups. Typically, this method is invoked at the beginning of the application execution, since it affects logging behavior in the entire application, and completely overrides the global debug groups mask. If it is required to turn logging on for a smaller scope and for a shorter period of execution, allowDebugLoggingForGroups and refuseDebugLoggingForGroups should be used.

Note: This method completely overrides the global debug groups mask, and affects logging behavior in the entire application. It is suggested that it is used once at the beginning of application execution.

By default, logging is allowed for all debug groups. If the debug level is set to be high (for example, DebugLevelDetailed), the debugging output may be overwhelming.

Parameters:
aDebugGroups - customized groups for debug
See Also:
allowDebugLoggingForGroups(long aDebugGroups), refuseDebugLoggingForGroups(long aDebugGroups)

setAllowedDebugLevel

public static void setAllowedDebugLevel(int aDebugLevel)
Sets the debug level to aDebugLevel. Throws an IllegalArgumentException if aDebugLevel is invalid. Typically, this method is invoked at the beginning of the application execution, since it affects logging behavior in the entire application.

By default, logging is allowed for all debug groups. If the debug level is set to be high (for example, DebugLevelDetailed), the debugging output may be overwhelming.

Parameters:
aDebugLevel - level of debug required
Throws:
IllegalArgumentException - if aDebugLevel is invalid

setDebug

public static void setDebug(NSLog.Logger instance)
Sets the debugging logger NSLog.debug to instance. By default, NSLog.debug is an NSLog.PrintStreamLogger that sends its output to System.err. NSLog.debug is used for status and error messages that will conditionally be shown. If the Logger instance is null, no change will be made.
Parameters:
instance - instance of the logger to use as the debug logger
See Also:
NSLog.Logger, NSLog.PrintStreamLogger

setErr

public static void setErr(NSLog.Logger instance)
Sets the logger NSLog.err to instance. By default, NSLog.err is a NSLog.PrintStreamLogger that sends its output to System.err. NSLog.err is used for error messages that will always be shown. If the Logger instance is null, no change will be made.
Parameters:
instance - instance of the logger to use as the error logger
See Also:
NSLog.Logger, NSLog.PrintStreamLogger

setOut

public static void setOut(NSLog.Logger instance)
Sets the logger NSLog.out to instance. By default, NSLog.out is a NSLog.PrintStreamLogger that sends its output to System.out. NSLog.out is used for status messages that will always be shown. If the Logger instance is null, no change will be made.
Parameters:
instance - instance of the logger to use as the out logger
See Also:
NSLog.Logger, NSLog.PrintStreamLogger

throwableAsString

public static String throwableAsString(Throwable t)
Returns the stack trace of t as a string.
Parameters:
t - the throwable message
Returns:
the output message as a string

Last updated Fri Feb 21 13:15:00 PST 2003.

Copyright © 2003 Apple Computer, Inc.