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 70805d51dc Fix ExecProcess command-line tokenization after (#7581)
70805d51dc is described below

commit 70805d51dc94e5d19534170d0db66270ccec5a27
Author: Lance <[email protected]>
AuthorDate: Mon Jul 20 23:25:50 2026 +0800

    Fix ExecProcess command-line tokenization after (#7581)
    
    Signed-off-by: lance <[email protected]>
---
 .../pipeline/transforms/execprocess/ExecProcess.java  | 19 ++++++++++++++++++-
 .../transforms/execprocess/ExecProcessTest.java       | 10 ++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git 
a/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcess.java
 
b/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcess.java
index d275946a6a..922ba64803 100644
--- 
a/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcess.java
+++ 
b/plugins/transforms/execprocess/src/main/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcess.java
@@ -23,6 +23,7 @@ import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.StringTokenizer;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
 import java.util.concurrent.CountDownLatch;
@@ -218,7 +219,10 @@ public class ExecProcess extends 
BaseTransform<ExecProcessMeta, ExecProcessData>
       // execute process
       try {
         if (!meta.isArgumentsInFields()) {
-          p = data.runtime.exec(new String[] {process[0]});
+          // Match historical Runtime.exec(String) whitespace tokenization 
without using the
+          // deprecated String overload. A single-element String[] would treat 
the whole command
+          // line (e.g. "/bin/echo hop-single") as the executable name.
+          p = data.runtime.exec(tokenizeCommandLine(process[0]));
         } else {
           p = data.runtime.exec(process);
         }
@@ -323,6 +327,19 @@ public class ExecProcess extends 
BaseTransform<ExecProcessMeta, ExecProcessData>
     }
   }
 
+  /**
+   * Tokenize a command line the same way Runtime.exec(String) historically 
did (whitespace via
+   * {@link StringTokenizer}).
+   */
+  static String[] tokenizeCommandLine(String command) {
+    StringTokenizer st = new StringTokenizer(command);
+    String[] cmdArray = new String[st.countTokens()];
+    for (int i = 0; st.hasMoreTokens(); i++) {
+      cmdArray[i] = st.nextToken();
+    }
+    return cmdArray;
+  }
+
   private String getOutputString(BufferedReader b) throws IOException {
     StringBuilder returnValueBuffer = new StringBuilder();
     String line;
diff --git 
a/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessTest.java
 
b/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessTest.java
index 7cfd1e7c7a..832673cbcd 100644
--- 
a/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessTest.java
+++ 
b/plugins/transforms/execprocess/src/test/java/org/apache/hop/pipeline/transforms/execprocess/ExecProcessTest.java
@@ -25,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
 
+import java.util.Arrays;
+import java.util.List;
 import org.apache.hop.core.HopEnvironment;
 import org.apache.hop.core.IRowSet;
 import org.apache.hop.core.QueueRowSet;
@@ -215,6 +217,14 @@ class ExecProcessTest {
     assertEquals(1, transform.getErrors());
   }
 
+  @Test
+  void tokenizeCommandLine_splitsOnWhitespaceLikeRuntimeExecString() {
+    assertEquals(
+        Arrays.asList("/bin/echo", "hop-single"),
+        Arrays.asList(ExecProcess.tokenizeCommandLine("/bin/echo 
hop-single")));
+    assertEquals(List.of("cmd"), 
Arrays.asList(ExecProcess.tokenizeCommandLine("cmd")));
+  }
+
   @Test
   void processRow_emptyProcessField_throws() throws HopException {
     HopEnvironment.init();

Reply via email to