Applies to ReadyAPI 3.5, last modified on January 19, 2021

Here are the general topics to help you build your plugins:

Guice and Governator

ReadyAPI uses Google Guice as its dependency-injection framework and NetFlix Governator for lifecycle functionality (@PostCreate, @PreDestroy, etc.). All plugin classes that are loaded via one of the described plugin annotations will get instantiated through Guice, and thus, have the possibility of injecting any other exposed ReadyAPI class.

The following table lists types that might be of interest for injection:

Type Description
Workspace.class The root object of the object model. It gives access to all projects and their contents.
ReadyApiEventBus.class It is used for passing synchronous and asynchronous events, see below.


UISupport contains a large number of static general UI-related utilities, including methods for

  • showing pop-up alerts and prompts;
  • building common UI elements (toolbars, splitters, panels);
  • opening windows for objects from the ReadyAPI object model.


Due to backward compatibility requirements, with the old ReadyAPI codebase, we still use log4j under the hood, but we use slf4j for the actual logging calls in new ReadyAPI code – using the log4j bridge for slf4j underneath. For classes created with Guice, you can create a logger with:

@ReadyApiLogger Logger logger;

This makes it possible for us to change the way the loggers are created if needed.

Note: Make sure your package contains a logger configured in soapui-log4j.xml for it to work.

LIMITATION: Do not try to use the logger in the constructor, either directly or indirectly, because, currently, only field injection is supported (so, the object must be created before the field can be injected).

Currently, the injector just does the same as LoggerFactory.getLogger( <requesting class> ).

Usage Analytics

ReadyAPI provides an analytics API to track user actions anonymously as they use the application. Adding your own counters is extremely easy, and SmartBear can provide you with data on the values of these counters over time.

Tracking is done by calling the trackAction static method in the Analytics class:


import; // log an action without parameters Analytics.trackAction( Category.CUSTOM-PLUGIN-ACTION, "DoSomething" ); // log an action with parameters Analytics.trackAction( Category.CUSTOM-PLUGIN-ACTION, "DoSomethingWithParameters", "Type", "VeryCool" );

The first call above simply logs the "DoSomething" action, after which a variable number of arguments can be used (optional), but they always need to be added in pairs (name,value). The second call above adds a "Type" parameter with the "VeryCool" value. Use this option if you have a limited set of possible values, for example, in an enumeration.


ReadyAPI internally uses an event bus for triggering/handling both synchronous and asynchronous events. This is meant to replace the listener approach (over time) in the ReadyAPI code base. Instead of each observable object handling its own collection of listeners, it can use the event bus for distributing messages.

The ReadyApiEventBus interface in ready-api-core defines the behavior of the event bus:


public interface ReadyApiEventBus {

    void postAsync(ReadyApiMessage message);

    void post(ReadyApiMessage message);

    void register(Object listener);

    void unregister(Object listener);

    void clearEventBus();

There are two ways of accessing the available ReadyApiEventBus instance:

  • For classes created via Guice, inject it into your class with Guice @Inject (constructor, field, or method).
  • For classes not created via Guice, use the static ReadyApiCoreModule.getEventBus() method. For these classes, consider creating factory interfaces together with the Guice AssistedInject functionality.

Posting and Receiving Messages

Posting messages can either be synchronous or asynchronous, use the later if you don't want to block the current thread of execution, but make sure that eventual objects you are sending with a message will still be valid when that message is delivered.

Listening to messages is achieved by creating methods with the @Handler annotation and registering the containing class with EventBus. This can either be done by calling ReadyApiEventBus.register or by annotating the class with @ReadyApiEventHandler , which will automatically perform this registration for you, provided that the class is created with Guice.

Unregistering Handlers

If you register handlers that are temporary, i.e., they don't exist for the entire lifespan of the ReadyAPI session, you will need to unregister them using either the ReadyApiEventBus.unregister(...) method, or by adding a method annotated with @UnregisterReadyApiEventHandler to a @ReadyApiEventHandler class that gets called when the class is disposed (for example, a release method).

Implementation Notes

ReadyAPI currently uses the MBassador project for implementing the ReadyApiEventBus interface.

Highlight search results