apache / apache/jmeter

Split JMeterGUIComponent into metadata and UI parts

Open
#5,895 4 comments 0 reactions 0 assignees View on GitHub
enhancement to-triage
Dominant language
Java
Stars
9.5k
Forks
2.3k
Avg merge
1d 22h
Merged PRs (30d)
5

Description

### 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
* https://github.com/apache/jmeter/pull/5885

### Possible solution

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

For instance:

```java
/**
* Metadata for JMeter GUI components.
*/
interface GuiComponentRegistration {
Class implementationClass();
String labelResource();
default String resourceBundle() {
return "";
}
default List 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_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.