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

epugh pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new 7597d14fdaf 9x backport for "SOLR-7962 --jvm-opts with -e doesn't work 
on windows (#3347)" (#3376)
7597d14fdaf is described below

commit 7597d14fdaf782f6145fb16f5927b116b8edbeee
Author: Rahul Goswami <[email protected]>
AuthorDate: Wed May 28 13:08:30 2025 -0400

    9x backport for "SOLR-7962 --jvm-opts with -e doesn't work on windows 
(#3347)" (#3376)
---
 solr/CHANGES.txt                                   |  3 ++
 solr/bin/solr.cmd                                  |  2 +-
 .../java/org/apache/solr/cli/RunExampleTool.java   | 58 +++++++++++++++-------
 .../core/src/java/org/apache/solr/cli/SolrCLI.java |  2 +-
 .../org/apache/solr/cli/TestSolrCLIRunExample.java |  2 +-
 solr/packaging/test/test_example.bats              | 41 +++++++++++++++
 6 files changed, 86 insertions(+), 22 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index adbac3199e0..9f7b6ba8c31 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -103,6 +103,9 @@ Bug Fixes
 * SOLR-17758: The NumFieldLimitingUpdateRequestProcessor's "warnOnly" mode has 
been fixed, and now processes documents even
   when the limit has been exceeded. (Jason Gerlowski, Rahul Goswami)
 
+* SOLR-7962: Passing additional arguments to solr.cmd using "--jvm-opts" 
(formerly "-a") in conjunction with "-e" (examples like 'techproducts') 
+  wouldn't reflect on Windows (Rahul Goswami via Eric Pugh)
+
 Dependency Upgrades
 ---------------------
 * SOLR-17471: Upgrade Lucene to 9.12.1. (Pierre Salagnac, Christine Poerschke)
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index 852d100a16f..239044d0622 100755
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -1278,7 +1278,7 @@ REM Run the requested example
   
-Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml"
 ^
   -Dsolr.install.symDir="%SOLR_TIP%" ^
   -classpath 
"%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*"
 ^
-  org.apache.solr.cli.SolrCLI run_example --script "%SDIR%\solr.cmd" -e 
%EXAMPLE% --server-dir "%SOLR_SERVER_DIR%" ^
+  org.apache.solr.cli.SolrCLI run_example --script "%SDIR%\solr.cmd" -e 
%EXAMPLE% --server-dir "%SOLR_SERVER_DIR%" --jvm-opts "%SOLR_ADDL_ARGS%" ^
   --url-scheme !SOLR_URL_SCHEME! !PASS_TO_RUN_EXAMPLE!
 
 REM End of run_example
diff --git a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java 
b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
index 66d7bf38d93..c624f179e31 100644
--- a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java
@@ -208,23 +208,25 @@ public class RunExampleTool extends ToolBase {
               + serverDir.getAbsolutePath()
               + " is not a directory!");
 
+    boolean isWindows = (OS.isFamilyDOS() || OS.isFamilyWin9x() || 
OS.isFamilyWindows());
     script = cli.getOptionValue("script");
     if (script != null) {
       if (!(new File(script)).isFile())
         throw new IllegalArgumentException(
             "Value of --script option is invalid! " + script + " not found");
     } else {
-      File scriptFile = new File(serverDir.getParentFile(), "bin/solr");
+      File scriptFile =
+          new File(
+              serverDir.getParentFile(),
+              "bin" + File.separator + (isWindows ? "solr.cmd" : "solr"));
       if (scriptFile.isFile()) {
         script = scriptFile.getAbsolutePath();
       } else {
-        scriptFile = new File(serverDir.getParentFile(), "bin/solr.cmd");
-        if (scriptFile.isFile()) {
-          script = scriptFile.getAbsolutePath();
-        } else {
-          throw new IllegalArgumentException(
-              "Cannot locate the bin/solr script! Please pass --script to this 
application.");
-        }
+
+        throw new IllegalArgumentException(
+            "Cannot locate the bin/"
+                + scriptFile.getName()
+                + " script! Please pass --script to this application.");
       }
     }
 
@@ -664,7 +666,8 @@ public class RunExampleTool extends ToolBase {
 
     String jvmOpts =
         cli.hasOption("jvm-opts") ? cli.getOptionValue("jvm-opts") : 
cli.getOptionValue('a');
-    String jvmOptsArg = (jvmOpts != null) ? " --jvm-opts \"" + jvmOpts + "\"" 
: "";
+    String jvmOptsArg =
+        (jvmOpts != null && !jvmOpts.isEmpty()) ? " --jvm-opts \"" + jvmOpts + 
"\"" : "";
 
     File cwd = new File(System.getProperty("user.dir"));
     File binDir = (new File(script)).getParentFile();
@@ -684,10 +687,10 @@ public class RunExampleTool extends ToolBase {
             ? "-Dsolr.modules=clustering,extraction,langid,ltr,scripting 
-Dsolr.ltr.enabled=true -Dsolr.clustering.enabled=true"
             : "";
 
-    String startCmd =
+    String startCmdStr =
         String.format(
             Locale.ROOT,
-            "\"%s\" start %s -p %d --solr-home \"%s\" --server-dir \"%s\" %s 
%s %s %s %s %s %s %s",
+            "\"%s\" start %s -p %d --solr-home \"%s\" --server-dir \"%s\" %s 
%s %s %s %s %s %s",
             callScript,
             cloudModeArg,
             port,
@@ -699,12 +702,11 @@ public class RunExampleTool extends ToolBase {
             forceArg,
             verboseArg,
             extraArgs,
-            jvmOptsArg,
             syspropArg);
-    startCmd = startCmd.replaceAll("\\s+", " ").trim(); // for pretty printing
+    startCmdStr = startCmdStr.replaceAll("\\s+", " ").trim(); // for pretty 
printing
 
     echo("\nStarting up Solr on port " + port + " using command:");
-    echo(startCmd + "\n");
+    echo(startCmdStr + jvmOptsArg + "\n");
 
     String solrUrl =
         String.format(
@@ -731,7 +733,21 @@ public class RunExampleTool extends ToolBase {
         }
       }
       DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
-      executor.execute(org.apache.commons.exec.CommandLine.parse(startCmd), 
startEnv, handler);
+      org.apache.commons.exec.CommandLine startCmd =
+          org.apache.commons.exec.CommandLine.parse(startCmdStr);
+
+      if (!jvmOptsArg.isEmpty()) {
+        startCmd.addArgument("--jvm-opts");
+
+        /* CommandLine.parse() tends to strip off the quotes by default before 
sending to cmd.exe.
+        This may cause cmd to break up the argument value on certain 
characters in unintended ways
+        thereby passing incorrect value to start.cmd
+        (eg: for 
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:18983", it
+        breaks apart the value at "-agentlib:jdwp" passing incorrect args to 
start.cmd ).
+        The 'false' here tells Exec: “don’t touch my quotes—this is one atomic 
argument” */
+        startCmd.addArgument("\"" + jvmOpts + "\"", false);
+      }
+      executor.execute(startCmd, startEnv, handler);
 
       // wait for execution.
       try {
@@ -741,21 +757,25 @@ public class RunExampleTool extends ToolBase {
         Thread.interrupted();
       }
       if (handler.hasResult() && handler.getExitValue() != 0) {
+        startCmdStr += jvmOptsArg;
         throw new Exception(
             "Failed to start Solr using command: "
-                + startCmd
+                + startCmdStr
                 + " Exception : "
                 + handler.getException());
       }
     } else {
+      // Unlike Windows, special handling of jvmOpts is not required on linux. 
We can simply
+      // concatenate to form the complete command
+      startCmdStr += jvmOptsArg;
       try {
-        code = 
executor.execute(org.apache.commons.exec.CommandLine.parse(startCmd));
+        code = 
executor.execute(org.apache.commons.exec.CommandLine.parse(startCmdStr));
       } catch (ExecuteException e) {
         throw new Exception(
-            "Failed to start Solr using command: " + startCmd + " Exception : 
" + e);
+            "Failed to start Solr using command: " + startCmdStr + " Exception 
: " + e);
       }
+      if (code != 0) throw new Exception("Failed to start Solr using command: 
" + startCmdStr);
     }
-    if (code != 0) throw new Exception("Failed to start Solr using command: " 
+ startCmd);
 
     return getNodeStatus(solrUrl, maxWaitSecs, cli);
   }
diff --git a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java 
b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
index 651dfc59653..9300a0d826d 100755
--- a/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/cli/SolrCLI.java
@@ -307,7 +307,7 @@ public class SolrCLI implements CLIO {
     List<String> dashDList = new ArrayList<>();
     for (int a = 1; a < args.length; a++) {
       String arg = args[a];
-      if (arg.startsWith("-D")) {
+      if (!args[a - 1].equals("--jvm-opts") && arg.startsWith("-D")) {
         dashDList.add(arg);
       } else {
         toolArgList.add(arg);
diff --git a/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java 
b/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
index 8ba3db45f28..f83499506c7 100644
--- a/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
+++ b/solr/core/src/test/org/apache/solr/cli/TestSolrCLIRunExample.java
@@ -103,7 +103,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
       commandsExecuted.add(cmd);
 
       String exe = cmd.getExecutable();
-      if (exe.endsWith("solr")) {
+      if (exe.endsWith("solr") || exe.endsWith("solr.cmd")) {
         String[] args = cmd.getArguments();
         if ("start".equals(args[0])) {
           if (!hasFlag("--cloud", args) && !hasFlag("-c", args)) {
diff --git a/solr/packaging/test/test_example.bats 
b/solr/packaging/test/test_example.bats
new file mode 100644
index 00000000000..a15ba4b6f62
--- /dev/null
+++ b/solr/packaging/test/test_example.bats
@@ -0,0 +1,41 @@
+#!/usr/bin/env bats
+
+# 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.
+
+load bats_helper
+
+setup() {
+  common_clean_setup
+}
+
+teardown() {
+  # save a snapshot of SOLR_HOME for failed tests
+  save_home_on_failure
+
+  solr stop --all >/dev/null 2>&1
+}
+
+@test "start -e cloud works with --jvm-opts" {
+  solr start -e cloud --no-prompt --jvm-opts "-Dcustom.prop=helloworld"
+  solr assert --started http://localhost:${SOLR_PORT} --cloud 
http://localhost:${SOLR_PORT} --timeout 60000
+  solr assert --started http://localhost:${SOLR2_PORT} --cloud 
http://localhost:${SOLR2_PORT} --timeout 60000
+
+  run curl "http://localhost:${SOLR_PORT}/solr/admin/info/properties";
+  assert_output --partial 'helloworld'
+  
+  run curl "http://localhost:${SOLR2_PORT}/solr/admin/info/properties";
+  assert_output --partial 'helloworld'
+}

Reply via email to