Hello. Does anyone know enough about Windows batch to say what's right or wrong when it comes to delayed expansion? I know enough to be dangerous, in a "hit it till it works" approach, but I don't know enough to confidently say what the right answer is.
Someone came to me with a problem where they were getting an error when trying to start Solr on Windows along these lines: Usage: java [options] <mainclass> [args...] > (to execute a class) > After some digging, it boiled down to the fact that their password for Solr contained a special character (in their case &, but there are others). The command that was failing specifically was the check to see whether Solr had started, not the start command itself. https://github.com/apache/solr/blob/b0af29f651ba354d66c4c3887549f1a49a4da0e6/solr/bin/solr.cmd#L1294-L1297 That command is like this: > *"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% > %SOLR_TOOL_OPTS% -Dsolr.install.dir="%SOLR_TIP%" > -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^* In the env we'd set SOLR_AUTHENTICATION_OPTS=-Dbasicauth=solruser :my&Fake&Pass The AUTHC_OPTS contains the SOLR_AUTHENTICATION_OPTS With some added echo statements you'll see what happens: > > > > > * echo "-------------" echo AUTHC_OPTS echo %AUTHC_OPTS% EOL1 echo > !AUTHC_OPTS! EOL2 echo "-------------"* The & gets interpreted as the start of a new command to execute when using %expansion%, and is treated literally when using !expansion! > > > > > > > > > *"-------------"AUTHC_OPTS"-Dsolr.httpclient.builder.factory="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"" > -Dbasicauth=solruser:my'Fake' is not recognized as an internal or external > command,operable program or batch file.'Pass' is not recognized as an > internal or external command,operable program or batch > file."-Dsolr.httpclient.builder.factory="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"" > -Dbasicauth=solruser:my&Fake&Pass EOL2"-------------" * > So that seems to suggest to me that the command should be *"%JAVA%" %SOLR_SSL_OPTS% !AUTHC_OPTS! %SOLR_ZK_CREDS_AND_ACLS%*... and indeed that "fixes" this problem. But that leaves all the other parameters, and passwords can appear in others. (Maybe special characters are only likely in passwords though). It also makes me think that this *could* break something that does work, especially if anyone is already working around this problem by escaping their special characters. For example, setting SOLR_AUTHENTICATION_OPTS=-Dbasicauth=solruser :my^&Fake^&Pass will make it work with the existing %expansion% but it will be broken by a change to !expansion! > *"-Dsolr.httpclient.builder.factory="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"" > -Dbasicauth=banksy:my&Fake&Pass > EOL1"-Dsolr.httpclient.builder.factory="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"" > -Dbasicauth=banksy:my^&Fake^&Pass EOL2* The simplest solution is to tell people not to use special characters in their password but that's a bit of a hard one to sell :) Changing to use ! feels "right" as it treats the password literally, but it may break something and there's potentially lots of places in the solr.cmd that would need to be changed, so it feels risky. Escaping the password manually works on a case-by-case basis when you work out what's caused the problem but it's painful for people who hit it. Does anyone have a feeling for what the best solution is (passing in the password using a properties file specified by solr.httpclient.config works as an alternative approach, so maybe that's it) Thanks, Colvin