This is an automated email from the ASF dual-hosted git repository.

mattcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new f9cbbe4bb0 Issue apache#8087 Configure Hop Environment is not working 
on Windows (#8109)
f9cbbe4bb0 is described below

commit f9cbbe4bb0f20b4ffb894aaaa92cbe8cdf813444
Author: Sergio Ramazzina <[email protected]>
AuthorDate: Wed Aug 26 20:02:09 2026 +0200

    Issue apache#8087 Configure Hop Environment is not working on Windows 
(#8109)
    
    Preview and Apply threw a HopSetupException, and once that was out of the 
way
    Apply took over two minutes. Five defects:
    
    - The Windows launchers rewrote HOP_OPTIONS in place, so the java child
      inherited the expanded flag list, quotes included. They now accumulate 
into
      _HOP_OPTIONS, which also stops the list from growing at every start.
    - The dialog seeded its HOP_OPTIONS field from that value; the snapshot now
      discards values carrying the launcher-only -DHOP_PLATFORM_RUNTIME marker.
    - EnvValueEscaper rejected " % ! & | < > ^ instead of escaping; it now 
renders
      the whole set statement. "!" stays rejected because hop.bat enables 
delayed
      expansion before sourcing hop-env.cmd.
    - Apply hung forever: powershell.exe kept reading the stdin pipe that Java
      never closed. The write end is now closed right after start.
    - Apply still took minutes: writing user-level variables makes Windows
      broadcast an environment change to every top-level window and wait for a
      reply that the blocked user interface thread could not send. The applier 
now
      runs in a ProgressMonitorDialog, keeping the event loop alive.
    
    Fixes #8087
---
 assemblies/static/src/main/resources/hop-conf.bat  | 37 +++++++++--------
 .../static/src/main/resources/hop-encrypt.bat      | 35 ++++++++--------
 .../static/src/main/resources/hop-gui-nolog.bat    | 35 ++++++++--------
 assemblies/static/src/main/resources/hop-gui.bat   | 37 +++++++++--------
 .../static/src/main/resources/hop-import.bat       | 37 +++++++++--------
 assemblies/static/src/main/resources/hop-run.bat   | 37 +++++++++--------
 .../static/src/main/resources/hop-search.bat       | 37 +++++++++--------
 .../static/src/main/resources/hop-server.bat       | 37 +++++++++--------
 assemblies/static/src/main/resources/hop.bat       | 35 ++++++++--------
 .../apache/hop/setup/HopEnvironmentSnapshot.java   | 17 +++++++-
 .../java/org/apache/hop/setup/gui/SetupDialog.java | 38 +++++++++++++++++-
 .../apache/hop/setup/persist/EnvScriptWriter.java  |  9 ++---
 .../apache/hop/setup/persist/EnvValueEscaper.java  | 40 +++++++++++++------
 .../hop/setup/persist/SystemProcessRunner.java     |  3 ++
 .../setup/gui/messages/messages_en_US.properties   |  1 +
 .../hop/setup/HopEnvironmentSnapshotTest.java      | 16 ++++++++
 .../hop/setup/persist/EnvScriptWriterTest.java     | 11 ++++++
 .../hop/setup/persist/EnvValueEscaperTest.java     | 24 +++++++++--
 .../hop/setup/persist/SystemProcessRunnerTest.java | 46 ++++++++++++++++++++++
 19 files changed, 360 insertions(+), 172 deletions(-)

diff --git a/assemblies/static/src/main/resources/hop-conf.bat 
b/assemblies/static/src/main/resources/hop-conf.bat
index 4c1fcf4e69..fda75fa7dc 100644
--- a/assemblies/static/src/main/resources/hop-conf.bat
+++ b/assemblies/static/src/main/resources/hop-conf.bat
@@ -48,50 +48,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5009
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Conf
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Conf
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - 
hop-conf.bat]===================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 rem ===[Collect command line 
arguments...]======================================
 if [%1]==[DEBUG] (
@@ -102,8 +105,8 @@ set _cmdline=%*
 
 :Run
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
 echo.
 echo ===[Starting 
HopConfig]=========================================================
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
diff --git a/assemblies/static/src/main/resources/hop-encrypt.bat 
b/assemblies/static/src/main/resources/hop-encrypt.bat
index acbe596479..b25a01f2a5 100644
--- a/assemblies/static/src/main/resources/hop-encrypt.bat
+++ b/assemblies/static/src/main/resources/hop-encrypt.bat
@@ -49,50 +49,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx64m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx64m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5009
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 
 echo ===[Environment Settings - 
hop-encrypt.bat]====================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 echo.
 rem ===[Collect command line 
arguments...]======================================
@@ -104,10 +107,10 @@ set _cmdline=%*
 
 :Run
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.core.encryption.Encr %_cmdline%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.core.encryption.Encr %_cmdline%
 echo.
 echo ===[Starting 
HopEncrypt]=========================================================
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.encryption.HopEncrypt %_cmdline%
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.encryption.HopEncrypt %_cmdline%
 @echo off
 :End
\ No newline at end of file
diff --git a/assemblies/static/src/main/resources/hop-gui-nolog.bat 
b/assemblies/static/src/main/resources/hop-gui-nolog.bat
index 77dcb6f2ac..65a65219aa 100644
--- a/assemblies/static/src/main/resources/hop-gui-nolog.bat
+++ b/assemblies/static/src/main/resources/hop-gui-nolog.bat
@@ -67,57 +67,60 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5005
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - hop-gui-nolog.bat]=============================
 echo.
 echo Java identified as "%_HOP_JAVA%"
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 echo Command to start Hop will be:
-echo start "" "%_HOP_JAVA%" -classpath %CLASSPATH% 
-Djava.library.path=%LIBSPATH% %HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
+echo start "" "%_HOP_JAVA%" -classpath %CLASSPATH% 
-Djava.library.path=%LIBSPATH% %_HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
 echo.
 echo ===[Starting Hop]=========================================================
 
 REM Empty title "" is required: start treats the first quoted argument as the 
window title.
 REM SWT 3.134+ enables monitor-specific scaling by default on Windows; only
 REM "quarter" and "exact" are compatible. Do not set -Dswt.autoScale=false.
-start "" "%_HOP_JAVA%" -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
+start "" "%_HOP_JAVA%" -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
 
 :End
 endlocal
diff --git a/assemblies/static/src/main/resources/hop-gui.bat 
b/assemblies/static/src/main/resources/hop-gui.bat
index 2659d2b16a..551cebbba6 100755
--- a/assemblies/static/src/main/resources/hop-gui.bat
+++ b/assemblies/static/src/main/resources/hop-gui.bat
@@ -72,59 +72,62 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5005
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger + turning on GUI debug logging
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 
-DHOP_LOG_LEVEL=Debug)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 
-DHOP_LOG_LEVEL=Debug)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=GUI
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - hop-gui.bat]===================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
 echo.
 echo ===[Starting Hop]=========================================================
 
 REM SWT 3.134+ enables monitor-specific scaling by default on Windows; only
 REM "quarter" and "exact" are compatible. Do not set -Dswt.autoScale=false.
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.ui.hopgui.HopGui
 if ERRORLEVEL 1 (pause)
 
 :End
diff --git a/assemblies/static/src/main/resources/hop-import.bat 
b/assemblies/static/src/main/resources/hop-import.bat
index 224c5efc5a..8a829580bd 100644
--- a/assemblies/static/src/main/resources/hop-import.bat
+++ b/assemblies/static/src/main/resources/hop-import.bat
@@ -49,50 +49,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5009
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Import
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Import
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - 
hop-import.bat]===================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 rem ===[Collect command line 
arguments...]======================================
 if [%1]==[DEBUG] (
@@ -103,10 +106,10 @@ set _cmdline=%*
 
 :Run
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
 echo.
 echo ===[Starting 
HopConfig]=========================================================
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.imp.HopImport %_cmdline%
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.imp.HopImport %_cmdline%
 @echo off
 :End
diff --git a/assemblies/static/src/main/resources/hop-run.bat 
b/assemblies/static/src/main/resources/hop-run.bat
index 846fe673b5..c2ee048f4d 100755
--- a/assemblies/static/src/main/resources/hop-run.bat
+++ b/assemblies/static/src/main/resources/hop-run.bat
@@ -68,50 +68,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m"
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS="-Xmx2048m"
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5005
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - hop-run.bat]===================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 rem ===[Collect command line 
arguments...]======================================
 if [%1]==[DEBUG] (
@@ -126,7 +129,7 @@ echo Consolidated parameters to pass to HopRun are
 echo %_cmdline%%
 echo.
 echo Command to start HopRun will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%%
 echo.
 echo ===[Starting 
HopRun]=========================================================
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%%
\ No newline at end of file
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.run.HopRun %_cmdline%%
\ No newline at end of file
diff --git a/assemblies/static/src/main/resources/hop-search.bat 
b/assemblies/static/src/main/resources/hop-search.bat
index 14b0560f03..2e9710c1f1 100644
--- a/assemblies/static/src/main/resources/hop-search.bat
+++ b/assemblies/static/src/main/resources/hop-search.bat
@@ -48,50 +48,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5009
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Search
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Search
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - 
hop-search.bat]===================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 rem ===[Collect command line 
arguments...]======================================
 if [%1]==[DEBUG] (
@@ -102,8 +105,8 @@ set _cmdline=%*
 
 :Run
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.config.HopConfig %_cmdline%
 echo.
 echo ===[Starting 
HopConfig]=========================================================
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.search.HopSearch %_cmdline%
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.search.HopSearch %_cmdline%
diff --git a/assemblies/static/src/main/resources/hop-server.bat 
b/assemblies/static/src/main/resources/hop-server.bat
index 3fd6df7e57..3bb40d0cc4 100644
--- a/assemblies/static/src/main/resources/hop-server.bat
+++ b/assemblies/static/src/main/resources/hop-server.bat
@@ -51,50 +51,53 @@ if not "%HOP_JAVA_HOME%"=="" (
 
 REM # Settings for all OSses
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS=-Xmx2048m
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS=-Xmx2048m
 
 REM
 REM If the user passes in DEBUG as the first parameter, it starts Hop in 
debugger mode and opens port 5009
 REM to allow attaching a debugger to step code.
 if [%1]==[DEBUG] (
 REM # optional line for attaching a debugger
-set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
+set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5009)
 
 REM Pass HOP variables if they're set.
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-    set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+    set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Server
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Server
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 echo ===[Environment Settings - 
hop-server.bat]====================================
 echo.
 echo Java identified as %_HOP_JAVA%
 echo.
-echo HOP_OPTIONS=%HOP_OPTIONS%
+echo HOP_OPTIONS=%_HOP_OPTIONS%
 echo.
 echo.
 rem ===[Collect command line 
arguments...]======================================
@@ -106,8 +109,8 @@ set _cmdline=%*
 
 :Run
 echo Command to start Hop will be:
-echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline%
+echo %_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline%
 echo.
 echo ===[Starting 
HopServer]=========================================================
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline%
\ No newline at end of file
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.www.HopServer %_cmdline%
\ No newline at end of file
diff --git a/assemblies/static/src/main/resources/hop.bat 
b/assemblies/static/src/main/resources/hop.bat
index dea46c7280..4849ea4bee 100755
--- a/assemblies/static/src/main/resources/hop.bat
+++ b/assemblies/static/src/main/resources/hop.bat
@@ -54,49 +54,52 @@ if not "%HOP_JAVA_HOME%"=="" (
 REM # Settings for all OSses
 REM
 
-if "%HOP_OPTIONS%"=="" set HOP_OPTIONS="-Xmx2048m"
+REM HOP_OPTIONS is user input. The launcher accumulates its own flags in 
_HOP_OPTIONS so
+REM the expanded value is never exported to the java process and fed back into 
the setup dialog.
+set "_HOP_OPTIONS=%HOP_OPTIONS%"
+if "%_HOP_OPTIONS%"=="" set _HOP_OPTIONS="-Xmx2048m"
 
 REM See if we need to enable some remote debugging options for our developers.
 REM
 FOR %%a in (%*) DO (
   if "%%~a" == "--dev-debug" (
-    set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5010
+    set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5010
   )
   if "%%~a" == "--dev-debug-wait" (
-    set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5010
+    set _HOP_OPTIONS=%_HOP_OPTIONS% -Xdebug -Xnoagent 
-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5010
   )
 )
 
 REM Pass HOP variables if they're set.
 REM
 if not "%HOP_AUDIT_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER="%HOP_AUDIT_FOLDER%"
 ) else (
-   set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
+   set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUDIT_FOLDER=.\audit
 )
 if not "%HOP_CONFIG_FOLDER%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_CONFIG_FOLDER="%HOP_CONFIG_FOLDER%"
 )
 if not "%HOP_SHARED_JDBC_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_SHARED_JDBC_FOLDERS="%HOP_SHARED_JDBC_FOLDERS%"
 )
 if not "%HOP_PLUGIN_BASE_FOLDERS%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PLUGIN_BASE_FOLDERS="%HOP_PLUGIN_BASE_FOLDERS%"
 )
 if not "%HOP_PASSWORD_ENCODER_PLUGIN%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_PASSWORD_ENCODER_PLUGIN=%HOP_PASSWORD_ENCODER_PLUGIN%
 )
 if not "%HOP_AES_ENCODER_KEY%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AES_ENCODER_KEY=%HOP_AES_ENCODER_KEY%
 )
 if not "%HOP_AES_ENCODER_KEY_FILE%"=="" (
-  set HOP_OPTIONS=%HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
+  set _HOP_OPTIONS=%_HOP_OPTIONS% 
-DHOP_AES_ENCODER_KEY_FILE=%HOP_AES_ENCODER_KEY_FILE%
 )
 
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run
-set HOP_OPTIONS=%HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
-set HOP_OPTIONS=%HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens 
java.base/java.util.concur [...]
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_OS=Windows
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_PLATFORM_RUNTIME=Run
+set _HOP_OPTIONS=%_HOP_OPTIONS% -DHOP_AUTO_CREATE_CONFIG=Y
+set _HOP_OPTIONS=%_HOP_OPTIONS% --add-opens 
java.xml/jdk.xml.internal=ALL-UNNAMED --add-opens 
java.base/java.lang=ALL-UNNAMED --add-opens 
java.base/java.lang.invoke=ALL-UNNAMED --add-opens 
java.base/java.lang.reflect=ALL-UNNAMED --add-opens 
java.base/java.io=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED 
--add-opens java.base/java.nio=ALL-UNNAMED --add-opens 
java.base/java.util=ALL-UNNAMED --add-opens 
java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.util.conc 
[...]
 
 REM ===[Collect command line 
arguments...]======================================
 REM
@@ -104,5 +107,5 @@ set _cmdline=%*
 
 :Run
 
-%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%HOP_OPTIONS% org.apache.hop.hop.Hop %_cmdline%%
+%_HOP_JAVA% -classpath %CLASSPATH% -Djava.library.path=%LIBSPATH% 
%_HOP_OPTIONS% org.apache.hop.hop.Hop %_cmdline%%
 
diff --git 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/HopEnvironmentSnapshot.java
 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/HopEnvironmentSnapshot.java
index 462798489d..f38485dd08 100644
--- 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/HopEnvironmentSnapshot.java
+++ 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/HopEnvironmentSnapshot.java
@@ -52,6 +52,8 @@ public class HopEnvironmentSnapshot {
     this.wellKnownEnvFile = wellKnownEnvFile;
   }
 
+  private static final String LAUNCHER_OPTIONS_MARKER = 
"-DHOP_PLATFORM_RUNTIME";
+
   public static HopEnvironmentSnapshot capture() {
     return capture(OsFamily.detect(), UserPaths.system());
   }
@@ -72,13 +74,26 @@ public class HopEnvironmentSnapshot {
             System.getenv(HopSetupVariables.JAVA_HOME),
             System.getenv("JAVA_HOME"),
             System.getProperty("java.home")),
-        firstNonBlank(System.getenv(HopSetupVariables.OPTIONS), 
HopSetupVariables.DEFAULT_OPTIONS),
+        firstNonBlank(
+            userOptions(System.getenv(HopSetupVariables.OPTIONS)),
+            HopSetupVariables.DEFAULT_OPTIONS),
         firstNonBlank(System.getenv(HopSetupVariables.JDBC_FOLDERS), ""),
         StringUtils.isNotBlank(configEnv),
         StringUtils.isNotBlank(auditEnv),
         HopEnvironmentDefaults.wellKnownEnvFile(os, paths));
   }
 
+  /**
+   * Windows launchers accumulate the computed JVM flags into HOP_OPTIONS 
itself, and cmd exports
+   * that to the child process. Such a value is launcher output, not user 
input: persisting it would
+   * grow on every start. It is recognised by a flag only the launchers add.
+   */
+  static String userOptions(String environmentValue) {
+    return environmentValue != null && 
environmentValue.contains(LAUNCHER_OPTIONS_MARKER)
+        ? null
+        : environmentValue;
+  }
+
   public static boolean configFolderSetInEnvironment() {
     return 
StringUtils.isNotBlank(System.getenv(HopSetupVariables.CONFIG_FOLDER));
   }
diff --git 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/gui/SetupDialog.java 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/gui/SetupDialog.java
index 9bc14bac55..3a120be059 100644
--- a/plugins/misc/setup/src/main/java/org/apache/hop/setup/gui/SetupDialog.java
+++ b/plugins/misc/setup/src/main/java/org/apache/hop/setup/gui/SetupDialog.java
@@ -17,6 +17,7 @@
 
 package org.apache.hop.setup.gui;
 
+import java.lang.reflect.InvocationTargetException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.config.HopConfig;
@@ -38,6 +39,7 @@ import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.EnterTextDialog;
 import org.apache.hop.ui.core.dialog.ErrorDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.dialog.ProgressMonitorDialog;
 import org.apache.hop.ui.core.gui.GuiResource;
 import org.apache.hop.ui.core.gui.WindowProperty;
 import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
@@ -527,7 +529,7 @@ public class SetupDialog extends Dialog {
         spec.setWriteScript(true);
         spec.setDryRun(true);
       }
-      HopEnvironmentApplyResult result = new 
HopEnvironmentApplier().apply(spec);
+      HopEnvironmentApplyResult result = applyEnvironment(spec);
       if (dryRun || web) {
         StringBuilder preview = new StringBuilder(result.describe());
         result
@@ -561,6 +563,40 @@ public class SetupDialog extends Dialog {
     }
   }
 
+  /**
+   * Writing user-level variables makes Windows broadcast an environment 
change to every top-level
+   * window and wait for each one to answer. On the UI thread that blocks the 
very windows expected
+   * to answer, which costs about 25 seconds per variable, so the work runs on 
a background thread
+   * while the event loop keeps dispatching.
+   */
+  private HopEnvironmentApplyResult applyEnvironment(HopEnvironmentSpec spec) 
throws Exception {
+    if (spec.isDryRun()) {
+      return new HopEnvironmentApplier().apply(spec);
+    }
+    HopEnvironmentApplyResult[] applied = new HopEnvironmentApplyResult[1];
+    try {
+      new ProgressMonitorDialog(shell)
+          .run(
+              false,
+              monitor -> {
+                monitor.beginTask(BaseMessages.getString(PKG, 
"SetupDialog.Apply.Progress"), 1);
+                try {
+                  applied[0] = new HopEnvironmentApplier().apply(spec);
+                } catch (Exception e) {
+                  throw new InvocationTargetException(e);
+                }
+                monitor.worked(1);
+                monitor.done();
+              });
+    } catch (InvocationTargetException e) {
+      if (e.getCause() instanceof Exception cause) {
+        throw cause;
+      }
+      throw e;
+    }
+    return applied[0];
+  }
+
   private void cancel() {
     dispose();
   }
diff --git 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvScriptWriter.java
 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvScriptWriter.java
index 82442f75eb..2bac21cae4 100644
--- 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvScriptWriter.java
+++ 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvScriptWriter.java
@@ -62,14 +62,11 @@ public final class EnvScriptWriter {
       if (StringUtils.isEmpty(entry.getValue())) {
         continue;
       }
-      EnvValueEscaper.cmdQuoted(entry.getKey(), entry.getValue());
       out.append("if not defined ")
           .append(entry.getKey())
-          .append(" set \"")
-          .append(entry.getKey())
-          .append('=')
-          .append(entry.getValue())
-          .append("\"\r\n");
+          .append(' ')
+          .append(EnvValueEscaper.cmdAssignment(entry.getKey(), 
entry.getValue()))
+          .append("\r\n");
     }
     return out.toString();
   }
diff --git 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvValueEscaper.java
 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvValueEscaper.java
index bdc5c46fe3..83c88edb8d 100644
--- 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvValueEscaper.java
+++ 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/EnvValueEscaper.java
@@ -29,22 +29,40 @@ public final class EnvValueEscaper {
     return "'" + value + "'";
   }
 
-  public static String cmdQuoted(String name, String value) throws 
HopSetupException {
+  /**
+   * Renders a {@code set} statement assigning the value in a cmd script. 
Values without a double
+   * quote are wrapped in quotes, which already neutralises {@code & | < > ^}. 
A value carrying its
+   * own quotes cannot be wrapped, so the unquoted form is used and cmd 
metacharacters are rejected.
+   */
+  public static String cmdAssignment(String name, String value) throws 
HopSetupException {
     rejectNewlines(name, value);
-    if (value.indexOf('"') >= 0
-        || value.indexOf('%') >= 0
-        || value.indexOf('!') >= 0
-        || value.indexOf('&') >= 0
-        || value.indexOf('|') >= 0
-        || value.indexOf('<') >= 0
-        || value.indexOf('>') >= 0
-        || value.indexOf('^') >= 0) {
+    if (value.indexOf('!') >= 0) {
       throw new HopSetupException(
           "Value for "
               + name
-              + " contains characters that cannot be written safely to a 
Windows cmd script");
+              + " must not contain '!': launchers run with delayed expansion 
enabled");
     }
-    return "\"" + value + "\"";
+    String escaped = value.replace("%", "%%");
+    if (escaped.indexOf('"') < 0) {
+      return "set \"" + name + "=" + escaped + "\"";
+    }
+    if (containsAny(escaped, "&|<>^")) {
+      throw new HopSetupException(
+          "Value for "
+              + name
+              + " combines double quotes with characters that cannot be 
written safely to a"
+              + " Windows cmd script");
+    }
+    return "set " + name + "=" + escaped;
+  }
+
+  private static boolean containsAny(String value, String characters) {
+    for (int i = 0; i < characters.length(); i++) {
+      if (value.indexOf(characters.charAt(i)) >= 0) {
+        return true;
+      }
+    }
+    return false;
   }
 
   public static String powershellSingleQuoted(String name, String value) 
throws HopSetupException {
diff --git 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/SystemProcessRunner.java
 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/SystemProcessRunner.java
index 98886a633f..5a25c45d5b 100644
--- 
a/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/SystemProcessRunner.java
+++ 
b/plugins/misc/setup/src/main/java/org/apache/hop/setup/persist/SystemProcessRunner.java
@@ -25,6 +25,9 @@ public class SystemProcessRunner implements IProcessRunner {
   @Override
   public int run(List<String> command) throws Exception {
     Process process = new 
ProcessBuilder(command).redirectErrorStream(true).start();
+    // A child reading its standard input only exits once it sees EOF, so 
release the write end
+    // immediately: powershell.exe otherwise keeps waiting for more commands 
and never terminates.
+    process.getOutputStream().close();
     try (InputStream in = process.getInputStream()) {
       in.readAllBytes();
     }
diff --git 
a/plugins/misc/setup/src/main/resources/org/apache/hop/setup/gui/messages/messages_en_US.properties
 
b/plugins/misc/setup/src/main/resources/org/apache/hop/setup/gui/messages/messages_en_US.properties
index d71388f714..1d5bda47f2 100644
--- 
a/plugins/misc/setup/src/main/resources/org/apache/hop/setup/gui/messages/messages_en_US.properties
+++ 
b/plugins/misc/setup/src/main/resources/org/apache/hop/setup/gui/messages/messages_en_US.properties
@@ -52,6 +52,7 @@ SetupDialog.Preview=Preview
 SetupDialog.Apply=Apply
 SetupDialog.Preview.Header=Preview
 SetupDialog.Preview.Message=Planned writes (nothing has been changed yet)
+SetupDialog.Apply.Progress=Writing the Hop environment settings
 SetupDialog.Success.Header=Environment configured
 SetupDialog.Error.Header=Unable to configure Hop environment
 SetupDialog.NoVariables=Set at least one variable, or click "Use recommended 
values".
diff --git 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/HopEnvironmentSnapshotTest.java
 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/HopEnvironmentSnapshotTest.java
index 5eed2012ce..a8d1b47ade 100644
--- 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/HopEnvironmentSnapshotTest.java
+++ 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/HopEnvironmentSnapshotTest.java
@@ -18,6 +18,7 @@
 package org.apache.hop.setup;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import org.junit.jupiter.api.Test;
 
@@ -41,4 +42,19 @@ class HopEnvironmentSnapshotTest {
     assertEquals("./config", HopEnvironmentSnapshot.existingFolder(null, null, 
"./config"));
     assertEquals("./audit", HopEnvironmentSnapshot.existingFolder("", "", 
"./audit"));
   }
+
+  @Test
+  void userOptionsKeepsPlainValues() {
+    assertEquals("-Xmx4096m", HopEnvironmentSnapshot.userOptions("-Xmx4096m"));
+    assertNull(HopEnvironmentSnapshot.userOptions(null));
+  }
+
+  @Test
+  void userOptionsDiscardsLauncherExpandedValue() {
+    assertNull(
+        HopEnvironmentSnapshot.userOptions(
+            "-Xmx2048m 
-DHOP_SHARED_JDBC_FOLDERS=\"C:\\java\\hop\\jdbc-shared\""
+                + " -DHOP_PLATFORM_OS=Windows -DHOP_PLATFORM_RUNTIME=GUI"
+                + " --add-opens java.base/java.lang=ALL-UNNAMED"));
+  }
 }
diff --git 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvScriptWriterTest.java
 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvScriptWriterTest.java
index 71ce34e01a..55f0c1815e 100644
--- 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvScriptWriterTest.java
+++ 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvScriptWriterTest.java
@@ -45,6 +45,17 @@ class EnvScriptWriterTest {
             "if not defined HOP_CONFIG_FOLDER set 
\"HOP_CONFIG_FOLDER=C:\\Users\\alice\\.hop\\config\""));
   }
 
+  @Test
+  void windowsScriptWritesOptionsContainingDoubleQuotes() throws Exception {
+    Map<String, String> vars =
+        Map.of("HOP_OPTIONS", "-Xmx2048m 
-DHOP_SHARED_JDBC_FOLDERS=\"C:\\java\\hop\\jdbc-shared\"");
+    String script = EnvScriptWriter.windowsScript(vars);
+    assertTrue(
+        script.contains(
+            "if not defined HOP_OPTIONS set HOP_OPTIONS=-Xmx2048m"
+                + " 
-DHOP_SHARED_JDBC_FOLDERS=\"C:\\java\\hop\\jdbc-shared\""));
+  }
+
   @Test
   void emptyValuesAreOmitted() throws Exception {
     Map<String, String> vars = new LinkedHashMap<>();
diff --git 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvValueEscaperTest.java
 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvValueEscaperTest.java
index 77dd96040b..9357ff6644 100644
--- 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvValueEscaperTest.java
+++ 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/EnvValueEscaperTest.java
@@ -39,9 +39,27 @@ class EnvValueEscaperTest {
   }
 
   @Test
-  void cmdRejectsMetacharacters() {
-    assertThrows(HopSetupException.class, () -> EnvValueEscaper.cmdQuoted("V", 
"a%PATH%"));
-    assertThrows(HopSetupException.class, () -> EnvValueEscaper.cmdQuoted("V", 
"a&b"));
+  void cmdQuotesValueAndEscapesPercent() throws Exception {
+    assertEquals(
+        "set \"V=C:\\Users\\alice\\.hop\\config\"",
+        EnvValueEscaper.cmdAssignment("V", "C:\\Users\\alice\\.hop\\config"));
+    assertEquals("set \"V=a%%PATH%%\"", EnvValueEscaper.cmdAssignment("V", 
"a%PATH%"));
+    assertEquals("set \"V=a&b\"", EnvValueEscaper.cmdAssignment("V", "a&b"));
+  }
+
+  @Test
+  void cmdWritesValuesContainingDoubleQuotesUnquoted() throws Exception {
+    assertEquals(
+        "set V=-Xmx2048m 
-DHOP_SHARED_JDBC_FOLDERS=\"C:\\java\\hop\\jdbc-shared\"",
+        EnvValueEscaper.cmdAssignment(
+            "V", "-Xmx2048m 
-DHOP_SHARED_JDBC_FOLDERS=\"C:\\java\\hop\\jdbc-shared\""));
+  }
+
+  @Test
+  void cmdRejectsUnsafeValues() {
+    assertThrows(HopSetupException.class, () -> 
EnvValueEscaper.cmdAssignment("V", "a!b"));
+    assertThrows(HopSetupException.class, () -> 
EnvValueEscaper.cmdAssignment("V", "a\nb"));
+    assertThrows(HopSetupException.class, () -> 
EnvValueEscaper.cmdAssignment("V", "\"a b\"&c"));
   }
 
   @Test
diff --git 
a/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/SystemProcessRunnerTest.java
 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/SystemProcessRunnerTest.java
new file mode 100644
index 0000000000..899d943277
--- /dev/null
+++ 
b/plugins/misc/setup/src/test/java/org/apache/hop/setup/persist/SystemProcessRunnerTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.setup.persist;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
+import static org.junit.jupiter.api.Assumptions.assumeFalse;
+
+import java.time.Duration;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class SystemProcessRunnerTest {
+
+  /**
+   * A child process that reads its standard input waits for EOF before 
exiting. If the runner keeps
+   * the write end of the stdin pipe open, the child never terminates and 
reading its output blocks
+   * forever. This is what makes powershell.exe hang when writing Windows user 
environment
+   * variables. {@code cat} reproduces the same behaviour on POSIX systems.
+   */
+  @Test
+  void runDoesNotHangOnChildReadingStandardInput() {
+    assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win"));
+
+    int exit =
+        assertTimeoutPreemptively(
+            Duration.ofSeconds(10), () -> new 
SystemProcessRunner().run(List.of("cat")));
+
+    assertEquals(0, exit);
+  }
+}

Reply via email to