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

Reply via email to