Use case
Currently, JMeterGUIComponent mixes several responsibilities:
- Create and serve UI
- 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
Use case
Currently,
JMeterGUIComponentmixes several responsibilities:#getStaticLabel,#getLabelResource,#getDocAnchor,#getMenuCategoriesJMeter, 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
JMeterGUIComponentson the startup.Instantiating the UI in the constructor blocks migration to
ServiceLoaderapproach for component lookup asServiceLoaderalways instantiates the services.See
Possible solution
a) Split "metadata" part into a different interface.
For instance:
The implementation
WhileControllerGuicould delegateWhileControllerGui#labelResourcetoWhileControllerComponentRegistrationservice.For instance, we could add
AbstractJMeterGuiComponent#setMetadata(GuiComponentRegistration)method, and we could provide default implementations ofAbstractJMeterGuiComponent#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 theJMeterGUIComponent#createUImethod to create all the UI components when needed.I am not sure that would work well:
class AbstractJMeterGuiComponent extends JPanel, so it would triggerJPanelinstantiation in any case, so it would impact the startup timeprivate final JTextArea commentField =...fields. Code complexity would increase as it would have to use nullable fieldsPossible workarounds
No response
JMeter Version
5.5
Java Version
No response
OS Version
No response