Writing User Extensions

The JRas framework described in this task and its sub-tasks is deprecated. However, one can achieve similar results using Java logging.

 

General Considerations

One can configure the WAS to use Java 2 security to restrict access to protected resources such as the file system and sockets. Since user written extensions typically access such protected resources, user written extensions must contain the appropriate security checking calls, using AccessController doPrivileged() calls. In addition, the user written extensions must contain the appropriate policy file. In general, it is recommended that you locate user written extensions in a separate package. It is your responsibility to restrict access to the user written extensions appropriately.

 

Writing a handler

User written handlers must implement the RASIHandler interface. The RASIHandler interface extends the RASIMaskChangeGenerator interface, which extends the RASIObject interface. A short discussion of the methods introduced by each of these interfaces follows, along with implementation pointers. For more in depth information on any of the particular interfaces or methods, see the corresponding product javadoc.

 

RASIObject interface

The RASIObject interface

is the base interface for stand-alone JRas logging toolkit classes that are stateful or configurable, such as loggers, handlers and formatters.

  • The stand-alone JRas logging tookit supports rudimentary properties-file based configuration. To implement this configuration support, the configuration state is stored as a set of key-value pairs in a properties file. The methods public Hashtable getConfig() and public void setConfig(Hashtable ht) are used to get and set the configuration state. The JRas extensions do not support properties based configuration and it is recommended that these methods be implemented as no-operations. We can implement your own properties based configuration using these methods.

  • Loggers, handlers and formatters can be named objects. For example, the JRas extensions require the user to provide a name for the loggers that are retrieved from the manager. We can name your handlers. The methods public String getName() and public void setName(String name) are provided to get or set the name field. The JRas extensions currently do not call these methods on user handlers. We can implement these methods as you want, including as no operations.

  • Loggers, handlers and formatters can also contain a description field. The methods public String getDescription() and public void setDescription(String desc) can be used to get or set the description field. The JRas extensions currently do not use the description field. We can implement these methods as you want, including as no operations.

  • The method public String getGroup() is provided for usage by the RASManager. Since the JRas extensions provide their own Manager class, this method is never called. It is recommended you implement this as a no-operation.

 

RASIMaskChangeGenerator interface

The RASIMaskChangeGenerator interface is the interface that defines the implementation methods for filtering of events based on a mask state. This means that it is currently implemented by both loggers and handlers. By definition, an object that implements this interface contains both a message mask and a trace mask, although both need not be used. For example, message loggers contain a trace mask, but the trace mask is never used since the message logger never generates trace events. Handlers however can actively use both mask values. For example a single handler could handle both message and trace events.

  • The methods public long getMessageMask() and public void setMessageMask(long mask) are used to get or set the value of the message mask. The methods public long getTraceMask() and public void setTraceMask(long mask) are used to get or set the value of the trace mask.

In addition, this interface introduces the concept of calling back to interested parties when a mask changes state. The callback object must implement the RASIMaskChangeListener interface.

  • The methods public void addMaskChangeListener(RASIMaskChangeListener listener) and public void removeMaskChangeListener(RASIMaskChangeListener listener) are used to add or remove listeners to the handler. The method public Enumeration getMaskChangeListeners() returns an Enumeration over the list of currently registered listeners. The method public void fireMaskChangedEvent(RASMaskChangeEvent mc) is used to call back all the registered listeners to inform them of a mask change event.

For efficiency reasons, the Jras extensions message and trace loggers implement the RASIMaskChangeListener interface. The logger implementations maintain a "composite mask" in addition to the logger's own mask. The logger's composite mask is formed by logically or'ing the appropriate masks of all handlers that are registered to that logger, then and'ing the result with the logger's own mask. For example, the message logger's composite mask is formed by or'ing the message masks of all handlers registered with that logger, then and'ing the result with the logger's own message mask.

This means that all handlers are required to properly implement these methods. In addition, when a user handler is instantiated, the logger it is to be added to should be registered with the handler using the addMaskChangeListener() method. When either the message mask or trace mask of the handler is changed, the logger must be called back to inform it of the mask change. This allows the logger to dynamically maintain the composite mask.

The RASMaskChangedEvent class is defined by the stand-alone JRas logging toolkit. Direct usage of that class by user code is allowed in this context.

In addition the RASIMaskChangeGenerator introduces the concept of caching the names of all message and trace event classes that the implementing object will process. The intent of these methods is to allow a management program such as a GUI to retrieve the list of names, introspect the classes to determine the event types that they might possibly process and display the results. The JRas extensions do not ever call these methods, so they can be implemented as no operations, if desired.

  • The methods public void addMessageEventClass(String name) and public void removeMessageEventClass(String name) can be called to add or remove a message event class name from the list. The method public Enumeration getMessageEventClasses() will return an enumeration over the list of message event class names. Similarly, the public void addTraceEventClass(String name) and public void removeTraceEventClass(String name) can be called to add or remove a trace event class name from the list. The method public Enumeration getTraceEventClasses() will return an enumeration over the list of trace event class names.

 

RASIHandler interface

The RASIHandler interface introduces the methods that are specific to the behavior of a handler.

The RASIHandler interface as provided by the stand-alone JRas logging toolkit supports handlers that run in either a synchronous or asynchronous mode. In asynchronous mode, events are typically queued by the calling thread and then written by a worker thread. Since spawning of threads is not allowed in the WebSphere Application Server environment, it is expected that handlers will not queue or batch events, although this is not expressly prohibited.

  • The methods public int getMaximumQueueSize() and public void setMaximumQueueSize(int size) throw IllegalStateException are provided to manage the maximum queue size. The method public int getQueueSize() is provided to query the actual queue size.

  • The methods public int getRetryInterval() and public void setRetryInterval(int interval) support the notion of error retry, which again implies some type of queueing.

  • The methods public void addFormatter(RASIFormatter formatter), public void removeFormatter(RASIFormatter formatter) and public Enumeration getFormatters() are provided to manage the list of formatters that the handler can be configured with. Different formatters can be provided for different event classes, if appropriate.

  • The methods public void openDevice(), public void closeDevice() and public void stop() are provided to manage the underlying device that the handler abstracts.

  • The methods public void logEvent(RASIEvent event) and public void writeEvent(RASIEvent event) are provided to actually pass events to the handler for processing.

 

Writing a formatter

User written formatters must implement the RASIFormatter interface. The RASIFormatter interface extends the RASIObject interface. The implementation of the RASIObject interface is the same for both handlers and formatters. A short discussion of the methods introduced by the RASIFormatter interface follows. For more in depth information on the methods introduced by this interface, see the corresponding product API documentation.

 

RASIFormatter interface

  • The methods public void setDefault(boolean flag) and public boolean isDefault() are used by the concrete RASHandler classes provided by the stand-alone JRas logging toolkit to determine if a particular formatter is the default formatter. Since these RASHandler classes must never be used in a WAS environment, the semantic significance of these methods can be determined by the user.

  • The methods public void addEventClass(String name), public void removeEventClass(String name) and public Enumeration getEventClasses() are provided to determine which event classes a formatter can be used to format. We can provide the appropriate implementations as you see fit.

  • The method public String format(RASIEvent event) is called by handler objects and returns a formatted String representation of the event.