Skip to content

Split JMeterGUIComponent into metadata and UI parts #5895

@vlsi

Description

@vlsi

Use case

Currently, JMeterGUIComponent mixes several responsibilities:

  1. Create and serve UI
  2. Provide metadata on the component: #getStaticLabel, #getLabelResource, #getDocAnchor, #getMenuCategories

JMeter, needs to build menus on the startup, so it needs to discover elements, their labels, and the categories.
Unfortunately, most implementations create UI elements in their constructors, so it would take a lot of time if JMeter instantiated all JMeterGUIComponents on the startup.

Instantiating the UI in the constructor blocks migration to ServiceLoader approach for component lookup as ServiceLoader always instantiates the services.

See

Possible solution

a) Split "metadata" part into a different interface.

For instance:

/**
 * Metadata for JMeter GUI components.
 */
interface GuiComponentRegistration {
    Class<?> implementationClass();
    String labelResource();
    default String resourceBundle() {
        return "";
    }
    default List<String> actionGroups() {
        return Collections.emptyList();
    }
}

// Sample component implementation

@AutoService(GuiComponentRegistration.class)
class WhileControllerComponentRegistration implements GuiComponentRegistration {
    @Override
    public Class<?> implementationClass() {
        return WhileControllerGui.class;
    }

    @Override
    public String labelResource() {
        return "while_controller_title";
    }
}

The implementation WhileControllerGui could delegate WhileControllerGui#labelResource to WhileControllerComponentRegistration service.

For instance, we could add AbstractJMeterGuiComponent#setMetadata(GuiComponentRegistration) method, and we could provide default implementations of AbstractJMeterGuiComponent#labelResource.

Yet another possibility is to add AbstractJMeterGuiComponent(GuiComponentRegistration) constructor and deprecate the old one. That would enable detecting non-migrated code at the compile time.

b) Move UI instantiation out of constructors

An alternative option is to move init() methods out of constructors and add the JMeterGUIComponent#createUI method to create all the UI components when needed.

I am not sure that would work well:

  • class AbstractJMeterGuiComponent extends JPanel, so it would trigger JPanel instantiation in any case, so it would impact the startup time
  • It would be impossible to use private final JTextArea commentField =... fields. Code complexity would increase as it would have to use nullable fields

Possible workarounds

No response

JMeter Version

5.5

Java Version

No response

OS Version

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions