Scala Programming Language
  1. Scala Programming Language
  2. SI-4858

Windows: cannot pass java opts that contain whitespaces


    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Repl / Interpreter
    • Labels:
    • Environment:

      Any Windows OS


      Disclaimer: that's NOT yet another "scala won't work if SCALA_HOME resides in C:\Program Files (x86)" issue. Please, take a look at the details provided below.

      The bug

      Here's the excerpt from scala.bat that contains the bug (though, the bug affects not only scala.bat, but all batch files that work with JAVA_OPTS):

      rem We use the value of the JAVA_OPTS environment variable if defined
      set _JAVA_OPTS=%JAVA_OPTS%
      if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=-Xmx256M -Xms32M

      Since the expansion of _JAVA_OPTS is wrapped in quotes, it works finely when the variable contains spaces (i.e. if the user has provided more than one javaopt). However, it fails when the variable itself contains quotes. As explained in, in batch files, variables in "if" statements are expanded before the "if" statement is parsed. That's why, after the variable expansion, the "if" line no longer conforms to the "if <string literal> == <string literal> <stuff to do>" pattern (since we get multiple strings instead of the first <string literal>), and command interpreter reports an error.

      This issue could be dismissed as insignificant, but it blocks an important use-case, namely passing a string with spaces as a javaopt value. The exceprt provided below explains that:

      "%_JAVACMD%" %_JAVA_OPTS% %_PROPS% -cp "%_TOOL_CLASSPATH%" %*

      That's the raison d'etre of the script. Note, that the variable expansion of _JAVA_OPTS here is not guarded by quotes. This means that the user herself has to protect whitespaces in her javaopts. The only way to do that is to use quotes, e.g. like that:

      SET JAVA_OPTS="-Dfoo=qu ux" "-Dbar=bar"
      rem or like that: SET JAVA_OPTS=-Dfoo="qu ux"
      scala.bat HelloWorld.scala

      But in that case, scala.bat will fail when the batch interpreter reaches the "if" line due to the reasons outlined above.

      A fix that won't work

      This bug cannot be fixed by simply quoting %JAVA_OPTS% or %_JAVA_OPTS% expansions in the script. If we quote the expansion in "set _JAVA_OPTS=%JAVA_OPTS%", then _JAVA_OPTS itself will contain quotes (since set does not remove quotes automatically). If we quote the expansion in "%_JAVACMD% %_JAVA_OPTS% ...", then we got two problems: 1) if _JAVA_OPTS does not contain quotes, it will be passed as a single command-line parameter, even if it contains multiple javaopts, 2) if _JAVA_OPTS contains quotes, the interpreter will get confused and will incorrectly chop it into command-line arguments to JAVACMD.

      A fix that will work

      Luckily, there's a very simple fix to the problem. We only have to replace the check at the "if" line with "if not defined _JAVA_OPTS". That check does not perform variable expansion at all, that's why we completely evade quoting issues.


      if "%_JAVA_OPTS%"=="" set _JAVA_OPTS=-Xmx256M -Xms32M


      if not defined _JAVA_OPTS set _JAVA_OPTS=-Xmx256M -Xms32M


      Scala batch scripts also contain other checks that might suffer from the same idiosyncrasy of Windows batch interpreter. For example, if "%_JAVACMD%" == "" or if not "%JAVA_HOME%"=="". However, the analysis of whether this will lead to issues has yet to be done.


        Commit Message Bot added a comment -

        (extempore in r25997) scala.bat expansion with quotes and spaces.

        Closes SI-4858.

        Commit Message Bot added a comment - (extempore in r25997 ) scala.bat expansion with quotes and spaces. Closes SI-4858 .


          • Assignee:
            Eugene Burmako
          • Votes:
            0 Vote for this issue
            3 Start watching this issue


            • Created: