diff --git a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/hopweb-antipatterns.adoc b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/hopweb-antipatterns.adoc index a6cbf4b4182..fbc0bcc65f9 100644 --- a/docs/hop-dev-manual/modules/ROOT/pages/hopweb/hopweb-antipatterns.adoc +++ b/docs/hop-dev-manual/modules/ROOT/pages/hopweb/hopweb-antipatterns.adoc @@ -171,9 +171,12 @@ Hop Web creates one RAP `UISession` (and one SWT `Display`) per browser session. * **Perspectives:** `getInstance()` must prefer `HopGui.findSessionPerspective(...)`. A static `instance` field is only a fallback for tests and disabled perspectives. * **Caches of SWT `Image`s:** key by `Device`/`Display` and dispose on *that* device. Never one process-wide dispose hook. * **Engine-thread maps (drill-down):** stamp `hopGui.getId()` on the engine in the GUI thread; do not call `HopGui.getInstance()` from pipeline worker threads (no RAP `UISession`). +* **Background threads started by a dialog:** start them with `BackgroundThreadFacade.start(runnable)` instead of `new Thread(runnable).start()`. A dialog that looks up its input fields in the background reads session state while doing so (`ConstUi.sortFieldNames` asks `PropsUi`), and a plain thread has no `UISession` to read it from. Do not store `Control`, `Shell`, `SashForm`, `Image`, `Color`, `Font` or `GC` in `static` fields. When session A ends RAP disposes those objects; session B then hits `Invalid thread access` or `Widget is disposed`. +A thread that carries a session is still not the UI thread: widgets stay off limits to it, and it reaches them the same way as before, through `Display.asyncExec`. + == Avoid use of unimplemented SWT APIs === Example: drawing on an Image diff --git a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java index e6d53889bcf..9100fbc57ec 100644 --- a/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java +++ b/plugins/databases/cratedb/src/main/java/org/apache/hop/pipeline/transforms/cratedbbulkloader/CrateDBBulkLoaderDialog.java @@ -55,6 +55,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -382,7 +383,7 @@ public void run() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); } private void addAwsAuthenticationTab( diff --git a/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java b/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java index a69e029e2d8..ad5ed3e1a9c 100644 --- a/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java +++ b/plugins/databases/doris/src/main/java/org/apache/hop/pipeline/transforms/dorisbulkloader/DorisBulkLoaderDialog.java @@ -43,6 +43,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -570,7 +571,7 @@ public void run() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java b/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java index 75feb73d7df..70e33816c2e 100644 --- a/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java +++ b/plugins/databases/monetdb/src/main/java/org/apache/hop/pipeline/transforms/monetdbbulkloader/MonetDbBulkLoaderDialog.java @@ -48,6 +48,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -697,7 +698,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); wbLogFile.addListener( SWT.Selection, diff --git a/plugins/databases/mssqlnative/src/main/java/org/apache/hop/pipeline/transforms/mssqlbulkloader/MsSqlServerBulkLoaderDialog.java b/plugins/databases/mssqlnative/src/main/java/org/apache/hop/pipeline/transforms/mssqlbulkloader/MsSqlServerBulkLoaderDialog.java index e00ac24903e..f9a69251586 100644 --- a/plugins/databases/mssqlnative/src/main/java/org/apache/hop/pipeline/transforms/mssqlbulkloader/MsSqlServerBulkLoaderDialog.java +++ b/plugins/databases/mssqlnative/src/main/java/org/apache/hop/pipeline/transforms/mssqlbulkloader/MsSqlServerBulkLoaderDialog.java @@ -51,6 +51,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -178,23 +179,22 @@ public void focusLost(FocusEvent event) { wSettingsComp.layout(); // Look up the incoming fields in the background, they feed the stream field drop-down. - new Thread( - () -> { - TransformMeta stepMeta = pipelineMeta.findTransform(transformName); - if (stepMeta == null) { - return; - } - try { - IRowMeta row = pipelineMeta.getPrevTransformFields(variables, stepMeta); - for (int i = 0; i < row.size(); i++) { - inputFields.put(row.getValueMeta(i).getName(), i); - } - setComboBoxes(); - } catch (HopException e) { - logError(BaseMessages.getString(PKG, "System.Dialog.GetFieldsFailed.Message")); - } - }) - .start(); + BackgroundThreadFacade.start( + () -> { + TransformMeta stepMeta = pipelineMeta.findTransform(transformName); + if (stepMeta == null) { + return; + } + try { + IRowMeta row = pipelineMeta.getPrevTransformFields(variables, stepMeta); + for (int i = 0; i < row.size(); i++) { + inputFields.put(row.getValueMeta(i).getName(), i); + } + setComboBoxes(); + } catch (HopException e) { + logError(BaseMessages.getString(PKG, "System.Dialog.GetFieldsFailed.Message")); + } + }); wContent.pack(); Rectangle bounds = wContent.getBounds(); diff --git a/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java b/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java index b72ce822242..c26115c5011 100644 --- a/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java +++ b/plugins/databases/mysql/src/main/java/org/apache/hop/pipeline/transforms/mysqlbulkloader/MySqlBulkLoaderDialog.java @@ -52,6 +52,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -568,7 +569,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); wContent.pack(); Rectangle bounds = wContent.getBounds(); diff --git a/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java b/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java index 6b983cb5ab5..242dd1c5efd 100644 --- a/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java +++ b/plugins/databases/oracle/src/main/java/org/apache/hop/pipeline/transforms/orabulkloader/OraBulkLoaderDialog.java @@ -51,6 +51,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -849,7 +850,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); SelectionListener fileSelectionListener = new SelectionAdapter() { diff --git a/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java b/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java index 561deae9167..4ed6a24455c 100644 --- a/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java +++ b/plugins/databases/postgresql/src/main/java/org/apache/hop/pipeline/transforms/pgbulkloader/PGBulkLoaderDialog.java @@ -48,6 +48,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -397,7 +398,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); // Add listeners wGetLU.addListener(SWT.Selection, e -> getUpdate()); diff --git a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java index c7470396de1..b8c6601ddac 100644 --- a/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java +++ b/plugins/databases/snowflake/src/main/java/org/apache/hop/pipeline/transforms/snowflake/bulkloader/SnowflakeBulkLoaderDialog.java @@ -54,6 +54,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -1105,7 +1106,7 @@ public void focusGained(FocusEvent focusEvent) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java index 6e0dd014c5f..90da761e695 100644 --- a/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java +++ b/plugins/databases/teradata/src/main/java/org/apache/hop/pipeline/transforms/terafast/TeraFastDialog.java @@ -43,6 +43,7 @@ import org.apache.hop.ui.core.widget.PluginWidgetFactory; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -191,7 +192,7 @@ public String open() { BaseMessages.getString(PKG, "System.Dialog.GetFieldsFailed.Message")); } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); this.meta.setChanged(this.changed); diff --git a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java index 887fe6e7a06..a7945e94776 100644 --- a/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java +++ b/plugins/databases/vertica/src/main/java/org/apache/hop/pipeline/transforms/vertica/bulkloader/VerticaBulkLoaderDialog.java @@ -53,6 +53,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -600,7 +601,7 @@ public void run() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); fdTabFolder = new FormData(); fdTabFolder.left = new FormAttachment(0, 0); diff --git a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java index 0fc110746e8..412feb30bbe 100644 --- a/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java +++ b/plugins/tech/avro/src/main/java/org/apache/hop/avro/transforms/avrooutput/AvroOutputDialog.java @@ -41,6 +41,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -759,7 +760,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyDialog.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyDialog.java index fb3ea42b879..3c9c3cf5bc0 100644 --- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyDialog.java +++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/aws/sns/SnsNotifyDialog.java @@ -31,6 +31,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -497,7 +498,7 @@ private void setComboValues() { Arrays.sort(prevTransformFieldNames); fieldColumn.setComboValues(prevTransformFieldNames); }; - new Thread(fieldLoader).start(); + BackgroundThreadFacade.start(fieldLoader); } /** This method fills the ComboVar with common AWS region IDs (SNS-supported). */ diff --git a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java index e05d462606a..ed0c25291d9 100644 --- a/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java +++ b/plugins/tech/aws/src/main/java/org/apache/hop/pipeline/transforms/redshift/bulkloader/RedshiftBulkLoaderDialog.java @@ -55,6 +55,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -738,7 +739,7 @@ public void run() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); } /** diff --git a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbdelete/MongoDbDeleteDialog.java b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbdelete/MongoDbDeleteDialog.java index 2d94853b9d1..f58ed8f7b82 100644 --- a/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbdelete/MongoDbDeleteDialog.java +++ b/plugins/tech/mongodb/src/main/java/org/apache/hop/pipeline/transforms/mongodbdelete/MongoDbDeleteDialog.java @@ -50,6 +50,7 @@ import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.bson.Document; import org.eclipse.swt.SWT; @@ -341,7 +342,7 @@ public void run() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); // get fields but wbGetFields = new Button(wFieldsComp, SWT.PUSH | SWT.CENTER); diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertDialog.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertDialog.java index e8087871f88..4d93948a069 100644 --- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertDialog.java +++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceinsert/SalesforceInsertDialog.java @@ -54,6 +54,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; @@ -566,7 +567,7 @@ public void focusGained(org.eclipse.swt.events.FocusEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdGeneralComp = new FormData(); fdGeneralComp.left = new FormAttachment(0, 0); diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateDialog.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateDialog.java index 92dd7eb579c..62fb0cc3448 100644 --- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateDialog.java +++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupdate/SalesforceUpdateDialog.java @@ -50,6 +50,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; @@ -513,7 +514,7 @@ public void focusGained(org.eclipse.swt.events.FocusEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdGeneralComp = new FormData(); fdGeneralComp.left = new FormAttachment(0, 0); diff --git a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertDialog.java b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertDialog.java index 8ad57a90607..ac335b89f6f 100644 --- a/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertDialog.java +++ b/plugins/tech/salesforce/src/main/java/org/apache/hop/pipeline/transforms/salesforceupsert/SalesforceUpsertDialog.java @@ -52,6 +52,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; @@ -636,7 +637,7 @@ public void focusLost(FocusEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdGeneralComp = new FormData(); fdGeneralComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java b/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java index 3901ab95b21..9fd216bc56c 100644 --- a/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java +++ b/plugins/transforms/analyticquery/src/main/java/org/apache/hop/pipeline/transforms/analyticquery/AnalyticQueryDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.MessageDialogWithToggle; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -191,7 +192,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAgg = new FormData(); fdAgg.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java index eff630fedc1..580ec0beb23 100644 --- a/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java +++ b/plugins/transforms/calculator/src/main/java/org/apache/hop/pipeline/transforms/calculator/CalculatorDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.EnterSelectionDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.SwtSvgImageUtil; import org.eclipse.swt.SWT; @@ -226,7 +227,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); wFields.addModifyListener( arg0 -> diff --git a/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumDialog.java b/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumDialog.java index 7332319fc64..bacd68043ba 100644 --- a/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumDialog.java +++ b/plugins/transforms/checksum/src/main/java/org/apache/hop/pipeline/transforms/checksum/CheckSumDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -262,7 +263,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); activeResultType(); diff --git a/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorDialog.java b/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorDialog.java index 35e7bc52315..d0cf33a8fe9 100644 --- a/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorDialog.java +++ b/plugins/transforms/closure/src/main/java/org/apache/hop/pipeline/transforms/closure/ClosureGeneratorDialog.java @@ -26,6 +26,7 @@ import org.apache.hop.pipeline.transform.TransformMeta; import org.apache.hop.ui.core.PropsUi; import org.apache.hop.ui.core.dialog.BaseDialog; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; import org.eclipse.swt.SWT; @@ -195,7 +196,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceDialog.java b/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceDialog.java index 11013fe0b25..3a184cc5824 100644 --- a/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceDialog.java +++ b/plugins/transforms/coalesce/src/main/java/org/apache/hop/pipeline/transforms/coalesce/CoalesceDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.ColumnsResizer; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; @@ -192,7 +193,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java index b93d57c9ba6..ce66e7e3ed2 100644 --- a/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java +++ b/plugins/transforms/combinationlookup/src/main/java/org/apache/hop/pipeline/transforms/combinationlookup/CombinationLookupDialog.java @@ -44,6 +44,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; @@ -517,7 +518,7 @@ public void focusLost(FocusEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); wbSchema.addSelectionListener( new SelectionAdapter() { diff --git a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java index 7273593e6ce..ab17c15b074 100644 --- a/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java +++ b/plugins/transforms/concatfields/src/main/java/org/apache/hop/pipeline/transforms/concatfields/ConcatFieldsDialog.java @@ -39,6 +39,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -375,7 +376,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java index 8dd1fe8592c..32d783a0798 100644 --- a/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java +++ b/plugins/transforms/databasejoin/src/main/java/org/apache/hop/pipeline/transforms/databasejoin/DatabaseJoinDialog.java @@ -46,6 +46,7 @@ import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.EnvironmentUtils; import org.eclipse.swt.SWT; @@ -423,7 +424,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcDialog.java b/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcDialog.java index 3d4ee97bca5..2d0729e1471 100644 --- a/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcDialog.java +++ b/plugins/transforms/dbproc/src/main/java/org/apache/hop/pipeline/transforms/dbproc/DBProcDialog.java @@ -41,6 +41,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -241,7 +242,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); lsResize = event -> { diff --git a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java index a0567ec0561..53dc7a2ec90 100644 --- a/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java +++ b/plugins/transforms/delete/src/main/java/org/apache/hop/pipeline/transforms/delete/DeleteDialog.java @@ -45,6 +45,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -150,7 +151,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); setTableFieldCombo(); diff --git a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java index 851484774e7..8fc5a31a204 100644 --- a/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java +++ b/plugins/transforms/dimensionlookup/src/main/java/org/apache/hop/pipeline/transforms/dimensionlookup/DimensionLookupDialog.java @@ -62,6 +62,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -855,7 +856,7 @@ public void addFieldsTab(int margin) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java index ac57e325a07..3f30743788f 100644 --- a/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java +++ b/plugins/transforms/excel/src/main/java/org/apache/hop/pipeline/transforms/excelwriter/ExcelWriterTransformDialog.java @@ -49,6 +49,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.apache.poi.ss.usermodel.BuiltinFormats; @@ -1473,7 +1474,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldComp = new FormData(); fdFieldComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceDialog.java b/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceDialog.java index b6c0881f23f..8a17bd5e6c6 100644 --- a/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceDialog.java +++ b/plugins/transforms/fieldschangesequence/src/main/java/org/apache/hop/pipeline/transforms/fieldschangesequence/FieldsChangeSequenceDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -222,7 +223,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); input.setChanged(changed); focusTransformName(); diff --git a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java index df3ee01d096..d6b5c6b96e4 100644 --- a/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java +++ b/plugins/transforms/formula/src/main/java/org/apache/hop/pipeline/transforms/formula/FormulaDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -144,25 +145,24 @@ public String open() { fdFields.bottom = new FormAttachment(wOk, -margin); wFields.setLayoutData(fdFields); - new Thread( - () -> { - TransformMeta transformMeta = pipelineMeta.findTransform(transformName); - if (transformMeta != null) { - try { - IRowMeta row = pipelineMeta.getPrevTransformFields(variables, transformMeta); - - // Remember these fields... - for (int i = 0; i < row.size(); i++) { - inputFields.add(row.getValueMeta(i).getName()); - } - - setComboBoxes(); - } catch (HopTransformException e) { - logError(BaseMessages.getString(PKG, "FormulaDialog.Log.UnableToFindInput")); - } + BackgroundThreadFacade.start( + () -> { + TransformMeta transformMeta = pipelineMeta.findTransform(transformName); + if (transformMeta != null) { + try { + IRowMeta row = pipelineMeta.getPrevTransformFields(variables, transformMeta); + + // Remember these fields... + for (int i = 0; i < row.size(); i++) { + inputFields.add(row.getValueMeta(i).getName()); } - }) - .start(); + + setComboBoxes(); + } catch (HopTransformException e) { + logError(BaseMessages.getString(PKG, "FormulaDialog.Log.UnableToFindInput")); + } + } + }); colinf[1].setSelectionAdapter( new SelectionAdapter() { diff --git a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java index 21c9819dd2d..a8670f9a255 100644 --- a/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java +++ b/plugins/transforms/groupby/src/main/java/org/apache/hop/pipeline/transforms/groupby/GroupByDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -390,7 +391,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAgg = new FormData(); fdAgg.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpDialog.java b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpDialog.java index 217ac0b4fc9..0fe95617a98 100644 --- a/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpDialog.java +++ b/plugins/transforms/http/src/main/java/org/apache/hop/pipeline/transforms/http/HttpDialog.java @@ -38,6 +38,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -262,7 +263,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAdditionalComp = new FormData(); fdAdditionalComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java index 9a84d9c89aa..3e067ac8cc5 100644 --- a/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java +++ b/plugins/transforms/httppost/src/main/java/org/apache/hop/pipeline/transforms/httppost/HttpPostDialog.java @@ -38,6 +38,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; @@ -294,7 +295,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAdditionalComp = new FormData(); fdAdditionalComp.left = new FormAttachment(0, 0); fdAdditionalComp.top = new FormAttachment(wSpacer, margin); diff --git a/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullDialog.java b/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullDialog.java index a03982165fe..2154fdca964 100644 --- a/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullDialog.java +++ b/plugins/transforms/ifnull/src/main/java/org/apache/hop/pipeline/transforms/ifnull/IfNullDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -445,7 +446,7 @@ private void setComboValues() { } } }; - new Thread(fieldLoader).start(); + BackgroundThreadFacade.start(fieldLoader); } public void getFirstData() { diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java index 7cae5572510..eac77b7efff 100644 --- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java +++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/janino/JaninoDialog.java @@ -37,6 +37,7 @@ import org.apache.hop.ui.core.dialog.MessageBox; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -178,7 +179,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); colinf[1].setSelectionAdapter( new SelectionAdapter() { diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterDialog.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterDialog.java index 754a0b451b0..556d1a2f410 100644 --- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterDialog.java +++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/javafilter/JavaFilterDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.StyledTextComp; import org.apache.hop.ui.core.widget.TextComposite; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -223,7 +224,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); // Add listeners wEditor.addListener(SWT.Selection, e -> editorDialog()); diff --git a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java index 0a7e9bedbb2..94d7056beea 100644 --- a/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java +++ b/plugins/transforms/janino/src/main/java/org/apache/hop/pipeline/transforms/userdefinedjavaclass/UserDefinedJavaClassDialog.java @@ -64,6 +64,7 @@ import org.apache.hop.ui.core.widget.StyledTextComp; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.EnvironmentUtils; @@ -492,7 +493,7 @@ public void close(CTabFolderEvent event) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); addRenameToTreeScriptItems(); input.setChanged(changed); @@ -1534,10 +1535,19 @@ public boolean treeItemExist(TreeItem itemToCheck, String strItemName) { } private void populateFieldsTree() { + // Looking the fields up takes a while, and the dialog may well be gone by now. + if (shell.isDisposed()) { + return; + } shell .getDisplay() .syncExec( () -> { + if (itemInput.isDisposed()) { + // Closed while we were waiting our turn on the UI thread. syncExec hands what + // this throws back to the lookup thread, where nothing catches it. + return; + } itemInput.removeAll(); itemInfo.removeAll(); itemOutput.removeAll(); diff --git a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java index 50820f9a635..8063715920d 100644 --- a/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java +++ b/plugins/transforms/javascript/src/main/java/org/apache/hop/pipeline/transforms/javascript/ScriptValuesDialog.java @@ -58,6 +58,7 @@ import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.dialog.PipelinePreviewProgressDialog; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.EnvironmentUtils; @@ -526,7 +527,7 @@ public void close(CTabFolderEvent event) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); buildAddClassesListTree(); addRenameTowTreeScriptItems(); diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java index b10d4c798a1..3aaffbbd0c8 100644 --- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java +++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutput/JsonOutputDialog.java @@ -40,6 +40,7 @@ import org.apache.hop.ui.core.widget.ComboVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -653,7 +654,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputDialog.java b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputDialog.java index e668c22f35b..85eedd17d60 100644 --- a/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputDialog.java +++ b/plugins/transforms/json/src/main/java/org/apache/hop/pipeline/transforms/jsonoutputenhanced/JsonEOutputDialog.java @@ -40,6 +40,7 @@ import org.apache.hop.ui.core.widget.ComboVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -411,7 +412,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputDialog.java b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputDialog.java index 87c9f2ede18..4f02f828375 100644 --- a/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputDialog.java +++ b/plugins/transforms/ldap/src/main/java/org/apache/hop/pipeline/transforms/ldapoutput/LdapOutputDialog.java @@ -45,6 +45,7 @@ import org.apache.hop.ui.core.widget.PasswordTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -981,7 +982,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFields = new FormData(); fdFields.left = new FormAttachment(0, margin); diff --git a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java index db853d0b34a..3806f4d40ca 100644 --- a/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java +++ b/plugins/transforms/memgroupby/src/main/java/org/apache/hop/pipeline/transforms/memgroupby/MemoryGroupByDialog.java @@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -232,7 +233,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAgg = new FormData(); fdAgg.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java index 5a0f5b9c273..81295d1a31d 100644 --- a/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java +++ b/plugins/transforms/normaliser/src/main/java/org/apache/hop/pipeline/transforms/normaliser/NormaliserDialog.java @@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -160,7 +161,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfDialog.java b/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfDialog.java index aa9bde7d009..94c0af13717 100644 --- a/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfDialog.java +++ b/plugins/transforms/nullif/src/main/java/org/apache/hop/pipeline/transforms/nullif/NullIfDialog.java @@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FormAttachment; @@ -126,7 +127,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsDialog.java b/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsDialog.java index ce7fa14e0ad..3d2ef2341b6 100644 --- a/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsDialog.java +++ b/plugins/transforms/repeatfields/src/main/java/org/apache/hop/pipeline/transforms/repeatfields/RepeatFieldsDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.MessageDialogWithToggle; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FormAttachment; @@ -202,7 +203,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); focusTransformName(); diff --git a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java index 46a25952c46..99ea66bea7e 100644 --- a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java +++ b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceStringDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -193,7 +194,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/schemamapping/src/main/java/org/apache/hop/pipeline/transforms/schemamapping/SchemaMappingDialog.java b/plugins/transforms/schemamapping/src/main/java/org/apache/hop/pipeline/transforms/schemamapping/SchemaMappingDialog.java index 80b41d25c80..d2aaff39f36 100644 --- a/plugins/transforms/schemamapping/src/main/java/org/apache/hop/pipeline/transforms/schemamapping/SchemaMappingDialog.java +++ b/plugins/transforms/schemamapping/src/main/java/org/apache/hop/pipeline/transforms/schemamapping/SchemaMappingDialog.java @@ -45,6 +45,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -156,7 +157,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); setSchemaFieldCombo(); wGetFields.addListener(SWT.Selection, e -> get()); diff --git a/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptDialog.java b/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptDialog.java index 9ef7ffc812e..18aae2ee7a1 100644 --- a/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptDialog.java +++ b/plugins/transforms/script/src/main/java/org/apache/hop/pipeline/transforms/script/ScriptDialog.java @@ -41,6 +41,7 @@ import org.apache.hop.ui.core.widget.StyledTextComp; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.EnvironmentUtils; import org.eclipse.swt.SWT; @@ -452,7 +453,7 @@ public void close(CTabFolderEvent event) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); addRenameToTreeScriptItems(); input.setChanged(changed); diff --git a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java index c10369901a0..a1d72584baa 100644 --- a/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java +++ b/plugins/transforms/selectvalues/src/main/java/org/apache/hop/pipeline/transforms/selectvalues/SelectValuesDialog.java @@ -47,6 +47,7 @@ import org.apache.hop.ui.core.gui.GuiResource; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -517,7 +518,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/setvalueconstant/src/main/java/org/apache/hop/pipeline/transforms/setvalueconstant/SetValueConstantDialog.java b/plugins/transforms/setvalueconstant/src/main/java/org/apache/hop/pipeline/transforms/setvalueconstant/SetValueConstantDialog.java index c8e50f15c71..9f675cf8b2d 100644 --- a/plugins/transforms/setvalueconstant/src/main/java/org/apache/hop/pipeline/transforms/setvalueconstant/SetValueConstantDialog.java +++ b/plugins/transforms/setvalueconstant/src/main/java/org/apache/hop/pipeline/transforms/setvalueconstant/SetValueConstantDialog.java @@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -148,7 +149,7 @@ public String open() { // // Search the fields in the background // - new Thread(this::getPreviousFields).start(); + BackgroundThreadFacade.start(this::getPreviousFields); getData(); input.setChanged(changed); diff --git a/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldDialog.java b/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldDialog.java index a1c3691d41d..dd4e318c36d 100644 --- a/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldDialog.java +++ b/plugins/transforms/setvaluefield/src/main/java/org/apache/hop/pipeline/transforms/setvaluefield/SetValueFieldDialog.java @@ -32,6 +32,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FormAttachment; @@ -132,7 +133,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java b/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java index 7aa7ceaa491..812e3990f43 100644 --- a/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java +++ b/plugins/transforms/setvariable/src/main/java/org/apache/hop/pipeline/transforms/setvariable/SetVariableDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.dialog.MessageDialogWithToggle; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; import org.eclipse.swt.SWT; @@ -163,7 +164,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsDialog.java b/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsDialog.java index b73d57bd684..e720b527904 100644 --- a/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsDialog.java +++ b/plugins/transforms/sort/src/main/java/org/apache/hop/pipeline/transforms/sort/SortRowsDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ComponentSelectionListener; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; @@ -322,7 +323,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); lsResize = event -> { diff --git a/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeDialog.java b/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeDialog.java index 7b83117deb9..c294863c244 100644 --- a/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeDialog.java +++ b/plugins/transforms/sortedmerge/src/main/java/org/apache/hop/pipeline/transforms/sortedmerge/SortedMergeDialog.java @@ -34,6 +34,7 @@ import org.apache.hop.ui.core.dialog.MessageDialogWithToggle; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -110,7 +111,7 @@ public String open() { // // Search the fields in the background - new Thread(this::searchPreviousFields).start(); + BackgroundThreadFacade.start(this::searchPreviousFields); getData(); input.setChanged(changed); diff --git a/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlDialog.java b/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlDialog.java index 49e9b2fe68d..bce8257b98a 100644 --- a/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlDialog.java +++ b/plugins/transforms/sql/src/main/java/org/apache/hop/pipeline/transforms/sql/ExecSqlDialog.java @@ -47,6 +47,7 @@ import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.util.EnvironmentUtils; import org.eclipse.swt.SWT; @@ -152,7 +153,7 @@ public void widgetModified( } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); setExecutedEachInputRow(); diff --git a/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberDialog.java b/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberDialog.java index a9918ccfe5c..e0a8e199e68 100644 --- a/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberDialog.java +++ b/plugins/transforms/standardizephonenumber/src/main/java/org/apache/hop/pipeline/transforms/standardizephonenumber/StandardizePhoneNumberDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.ColumnsResizer; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; @@ -233,7 +234,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java index a98812128f3..5108657a7fb 100644 --- a/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java +++ b/plugins/transforms/stringcut/src/main/java/org/apache/hop/pipeline/transforms/stringcut/StringCutDialog.java @@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -147,7 +148,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsDialog.java b/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsDialog.java index 3d602234c47..af0b0486ce4 100644 --- a/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsDialog.java +++ b/plugins/transforms/stringoperations/src/main/java/org/apache/hop/pipeline/transforms/stringoperations/StringOperationsDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.gui.GuiResource; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -151,7 +152,7 @@ private void findFieldsInBackground(Display display) { logError("Error getting fields from incoming stream!", e); } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); } private void buildColumnsForFields() { diff --git a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java index e49edb866b2..caa84753c39 100644 --- a/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java +++ b/plugins/transforms/synchronizeaftermerge/src/main/java/org/apache/hop/pipeline/transforms/synchronizeaftermerge/SynchronizeAfterMergeDialog.java @@ -51,6 +51,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -447,7 +448,7 @@ private void addUpdatesTab(CTabFolder wTabFolder, ModifyListener lsMod) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); wUpdatesTab.setControl(wUpdatesComp); PropsUi.setLook(wUpdatesComp); diff --git a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java index 5db46a18ced..f9383558feb 100644 --- a/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java +++ b/plugins/transforms/tableoutput/src/main/java/org/apache/hop/pipeline/transforms/tableoutput/TableOutputDialog.java @@ -55,6 +55,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; @@ -957,7 +958,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdTabFolder = new FormData(); fdTabFolder.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java index cbbb0aff08c..de6322785ac 100644 --- a/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java +++ b/plugins/transforms/textfile/src/main/java/org/apache/hop/pipeline/transforms/textfileoutput/TextFileOutputDialog.java @@ -49,6 +49,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -1144,7 +1145,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementDialog.java b/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementDialog.java index 0c302cffaa0..34dbb7ddc9a 100644 --- a/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementDialog.java +++ b/plugins/transforms/tokenreplacement/src/main/java/org/apache/hop/pipeline/transforms/tokenreplacement/TokenReplacementDialog.java @@ -36,6 +36,7 @@ import org.apache.hop.ui.core.widget.ComboVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -1166,7 +1167,7 @@ private void addTokensTab(CTabFolder wTabFolder, ModifyListener lsMod) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdTokensComp = new FormData(); fdTokensComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsDialog.java b/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsDialog.java index 36417e244fb..f31ca92722f 100644 --- a/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsDialog.java +++ b/plugins/transforms/uniquerows/src/main/java/org/apache/hop/pipeline/transforms/uniquerows/UniqueRowsDialog.java @@ -37,6 +37,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -250,7 +251,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetDialog.java b/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetDialog.java index c9c7b8e1e78..16f8a940a93 100644 --- a/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetDialog.java +++ b/plugins/transforms/uniquerowsbyhashset/src/main/java/org/apache/hop/pipeline/transforms/uniquerowsbyhashset/UniqueRowsByHashSetDialog.java @@ -35,6 +35,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyListener; @@ -233,7 +234,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); setErrorDesc(); diff --git a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java index d357bdd978c..5eedac20c15 100644 --- a/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java +++ b/plugins/transforms/update/src/main/java/org/apache/hop/pipeline/transforms/update/UpdateDialog.java @@ -49,6 +49,7 @@ import org.apache.hop.ui.core.widget.MetaSelectionLine; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -156,7 +157,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); setActiveIgnoreLookup(); diff --git a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java index b6dea4d2b6c..1fca4077a46 100644 --- a/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java +++ b/plugins/transforms/writetolog/src/main/java/org/apache/hop/pipeline/transforms/writetolog/WriteToLogDialog.java @@ -37,6 +37,7 @@ import org.apache.hop.ui.core.widget.StyledTextComp; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextComposite; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -241,7 +242,7 @@ public String open() { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); getData(); input.setChanged(changed); diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlDialog.java index 2ddf96a3f0c..3df209b4418 100644 --- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlDialog.java +++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/addxml/AddXmlDialog.java @@ -40,6 +40,7 @@ import org.apache.hop.ui.core.gui.GuiResource; import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -348,7 +349,7 @@ public void widgetSelected(SelectionEvent e) { // // Search the fields in the background - new Thread(this::getPreviousFields).start(); + BackgroundThreadFacade.start(this::getPreviousFields); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/advancedxmloutput/AdvancedXmlOutputDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/advancedxmloutput/AdvancedXmlOutputDialog.java index fcc01ee3d7d..ad7a06f2d9d 100644 --- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/advancedxmloutput/AdvancedXmlOutputDialog.java +++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/advancedxmloutput/AdvancedXmlOutputDialog.java @@ -33,6 +33,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog; import org.apache.hop.ui.core.dialog.ErrorDialog; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -747,7 +748,7 @@ private void populateInputFieldsAsync() { logError(BaseMessages.getString(PKG, "AdvancedXMLOutputDialog.ErrorGettingFields"), e); } }; - new Thread(r, "AdvancedXMLOutput-FieldLookup").start(); + BackgroundThreadFacade.start(r, "AdvancedXMLOutput-FieldLookup"); } /** Synchronous re-fetch triggered by the "Get fields" button. */ diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java index a3b307e82f7..a288323166c 100644 --- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java +++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xmloutput/XmlOutputDialog.java @@ -40,6 +40,7 @@ import org.apache.hop.ui.core.widget.ColumnInfo; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.apache.hop.ui.pipeline.transform.ITableItemInsertListener; import org.eclipse.swt.SWT; @@ -686,7 +687,7 @@ public void widgetSelected(SelectionEvent e) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdFieldsComp = new FormData(); fdFieldsComp.left = new FormAttachment(0, 0); diff --git a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltDialog.java b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltDialog.java index 8c83ddf5b42..cefd904d5de 100644 --- a/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltDialog.java +++ b/plugins/transforms/xml/src/main/java/org/apache/hop/pipeline/transforms/xml/xslt/XsltDialog.java @@ -39,6 +39,7 @@ import org.apache.hop.ui.core.widget.LabelTextVar; import org.apache.hop.ui.core.widget.TableView; import org.apache.hop.ui.core.widget.TextVar; +import org.apache.hop.ui.hopgui.BackgroundThreadFacade; import org.apache.hop.ui.pipeline.transform.BaseTransformDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; @@ -507,7 +508,7 @@ public void widgetSelected(SelectionEvent arg0) { } } }; - new Thread(runnable).start(); + BackgroundThreadFacade.start(runnable); FormData fdAdditionalComp = new FormData(); fdAdditionalComp.left = new FormAttachment(0, 0); diff --git a/rap/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java b/rap/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java new file mode 100644 index 00000000000..9e4efd74f8a --- /dev/null +++ b/rap/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.hopgui; + +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.service.UISession; + +/** + * Carries the session of the thread that starts the work over to the thread that runs it, so that + * {@code SingletonUtil.getSessionInstance} keeps answering with this user's GUI state instead of + * throwing "Invalid thread access". + */ +public class BackgroundThreadFacadeImpl extends BackgroundThreadFacade { + + @Override + Runnable bindInternal(Runnable runnable) { + UISession uiSession = currentSession(); + if (uiSession == null) { + return runnable; + } + // exec() binds the session to whatever thread calls it, which is the point here: the work + // itself runs exactly as before, only now with a session to ask. + return () -> uiSession.exec(runnable); + } + + /** The session serving this thread, or null when there is none to carry over. */ + private static UISession currentSession() { + try { + return RWT.getUISession(); + } catch (RuntimeException e) { + // Started outside a request: nothing session scoped to preserve. + return null; + } + } +} diff --git a/rap/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImplTest.java b/rap/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImplTest.java new file mode 100644 index 00000000000..853f0b75c88 --- /dev/null +++ b/rap/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImplTest.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.hopgui; + +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.service.UISession; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + +/** + * A dialog that looks up its input fields on a thread of its own reads session scoped GUI state + * while doing so - {@code PropsUi} through {@code ConstUi.sortFieldNames}. In Hop Web that state + * belongs to a RAP session, and a thread with no session gets "Invalid thread access" instead. + */ +class BackgroundThreadFacadeImplTest { + + @Test + @DisplayName("work started from a session runs with that session bound") + void carriesTheSessionOverToTheBackgroundThread() { + UISession uiSession = mock(UISession.class); + Runnable work = mock(Runnable.class); + + try (MockedStatic rwt = mockStatic(RWT.class)) { + rwt.when(() -> RWT.getUISession()).thenReturn(uiSession); + + Runnable bound = new BackgroundThreadFacadeImpl().bindInternal(work); + + // The session is read here, on the thread that starts the work; the work itself waits. + verifyNoInteractions(uiSession, work); + + bound.run(); + + // exec() makes the session current for whichever thread runs the work, which is the point. + verify(uiSession).exec(work); + } + } + + @Test + @DisplayName("without a session there is nothing to carry over") + void leavesTheWorkAloneOutsideASession() { + Runnable work = mock(Runnable.class); + + try (MockedStatic rwt = mockStatic(RWT.class)) { + rwt.when(() -> RWT.getUISession()) + .thenThrow(new IllegalStateException("Invalid thread access")); + + assertSame(work, new BackgroundThreadFacadeImpl().bindInternal(work)); + } + } +} diff --git a/rcp/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java b/rcp/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java new file mode 100644 index 00000000000..0b936235be2 --- /dev/null +++ b/rcp/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeImpl.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.hopgui; + +/** The desktop GUI serves one user and keeps its state in process, so there is nothing to carry. */ +public class BackgroundThreadFacadeImpl extends BackgroundThreadFacade { + + @Override + Runnable bindInternal(Runnable runnable) { + return runnable; + } +} diff --git a/rcp/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeTest.java b/rcp/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeTest.java new file mode 100644 index 00000000000..e6479a6884c --- /dev/null +++ b/rcp/src/test/java/org/apache/hop/ui/hopgui/BackgroundThreadFacadeTest.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.hopgui; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; + +import java.util.concurrent.CompletableFuture; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +/** The desktop half of the facade: still a background thread, with nothing extra around it. */ +class BackgroundThreadFacadeTest { + + @Test + @DisplayName("the work runs on a thread of its own") + void startsTheWorkInTheBackground() throws Exception { + CompletableFuture ranOn = new CompletableFuture<>(); + + BackgroundThreadFacade.start(() -> ranOn.complete(Thread.currentThread()), "field-lookup"); + + Thread worker = ranOn.get(10, SECONDS); + assertNotSame(Thread.currentThread(), worker, "the caller must not be blocked by the lookup"); + assertEquals("field-lookup", worker.getName()); + } +} diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacade.java b/ui/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacade.java new file mode 100644 index 00000000000..5b72e67ad7b --- /dev/null +++ b/ui/src/main/java/org/apache/hop/ui/hopgui/BackgroundThreadFacade.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hop.ui.hopgui; + +/** + * Starts the background threads dialogs use to look up their input fields, in a way that keeps + * session scoped GUI state reachable. + * + *

A dialog that fetches the fields of the previous transform does so on a thread of its own so + * the dialog can already be shown. That thread then reads GUI state - {@link + * org.apache.hop.ui.core.PropsUi} through {@code ConstUi.sortFieldNames}, images from {@link + * org.apache.hop.ui.core.gui.GuiResource} - which in Hop Web belongs to a RAP {@code UISession}. + * RAP hands out session state by looking up the session bound to the calling thread, and a plain + * {@code new Thread(runnable).start()} has none: the lookup throws {@code IllegalStateException: + * Invalid thread access}, the thread dies and the dialog opens with empty combo boxes, its only + * trace an uncaught exception in the server log. + * + *

So the session is captured here, on the UI thread that starts the work, and made current again + * inside the new thread. On the desktop there is no session and this is a plain thread. + * + *

This does not make the thread a UI thread: widgets still have to be touched through {@code + * Display.asyncExec}. It only carries over the session identity that tells Hop Web whose GUI this + * work belongs to. + */ +public abstract class BackgroundThreadFacade { + + private static final BackgroundThreadFacade IMPL = load(); + + private static BackgroundThreadFacade load() { + try { + return (BackgroundThreadFacade) + ImplementationLoader.newInstance(BackgroundThreadFacade.class); + } catch (Throwable e) { + // Unit tests of the hop-ui module have neither rcp nor rap on the classpath, and outside + // Hop Web there is no session to carry over anyway. + return new BackgroundThreadFacade() { + @Override + Runnable bindInternal(Runnable runnable) { + return runnable; + } + }; + } + } + + /** + * Runs the given work on a new thread, from which session scoped GUI state stays reachable. + * + *

Call this on the UI thread: that is where the session it carries over is read. + * + * @param runnable the work to run in the background + * @return the thread that was started, already running + */ + public static Thread start(Runnable runnable) { + return start(runnable, null); + } + + /** + * Runs the given work on a new named thread, from which session scoped GUI state stays reachable. + * + * @param runnable the work to run in the background + * @param threadName name for the new thread, or null to let the JVM name it + * @return the thread that was started, already running + */ + public static Thread start(Runnable runnable, String threadName) { + Runnable bound = bind(runnable); + Thread thread = threadName == null ? new Thread(bound) : new Thread(bound, threadName); + thread.start(); + return thread; + } + + /** + * The same work, wrapped so that it keeps the current session when it runs on another thread. For + * callers that create the thread themselves because they configure it first. + * + *

Call this on the UI thread, not on the thread that will run the work. + * + * @param runnable the work to wrap + * @return the wrapped work + */ + public static Runnable bind(Runnable runnable) { + return IMPL.bindInternal(runnable); + } + + abstract Runnable bindInternal(Runnable runnable); +}