Found a bug in liquibase.bat

If you have multiple jar files in your lib directory (i.e. diff-ing different RDBMs), the batch file will only include one of them in your classpath.  This is apparently due to the use of SET in a dos FOR loop.  SET is not evaluated until the for loop’s close so only the last thing in the set of files takes effect.  The solution seems to be delayed variable expansion, but the requires the user to start a command prompt using CMD /v

Taken from the online SET help:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

in that it will NOT build up a list of files in the current directory,
but instead will just set the LIST variable to the last file found.
Again, this is because the %LIST% is expanded just once when the
FOR statement is read, and at that time the LIST variable is empty.
So the actual FOR loop we are executing is:

    for %i in (*) do set LIST= %i

which just keeps setting LIST to the last file found.

Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.

I haven’t done much .bat programming.  Is there anything else we can do besides requiring starting the command prompt with /v?  That seems like something we should not expect people to do.


I’m sure something can be done.  I haven’t done bat scripting in years.  I didn’t see anything right away that looked promising and this got me up and running.  I’ll poke around some more if I get some free time.

I solved the problem by calling a subroutine in FOR command this way (only lib directory is investigated):

set CP=.
for %%f in (%LIQUIBASE_HOME%lib*.jar) do call :addCP “%%f”
goto :continue

  set CP=%CP%;%1
  rem echo %1

echo CP=%CP%



that bug should be fixed in 2.0 trunk. I sent a patch some time ago and nathan integrated it.
You can take it from there or use this to replace it:

    @echo off if "%OS%" == "Windows_NT" setlocal

    setlocal enabledelayedexpansion

    rem %~dp0 is expanded pathname of the current script under NT
    set LIQUIBASE_HOME="%~dp0"

    set CP=.
    for /R %LIQUIBASE_HOME% %%f in (liquibase*.jar) do set CP=!CP!;%%f
    for /R %LIQUIBASE_HOME%\lib %%f in (*.jar) do set CP=!CP!;%%f

    rem get command line args into a variable
    set CMD_LINE_ARGS=%1
    if “”%1""=="""" goto done
    if “”%1""=="""" goto done
    goto setup

    set JAVA_OPTS=
    java -cp “%CP%” %JAVA_OPTS% liquibase.commandline.Main %CMD_LINE_ARGS%

ah, setlocal… didn’t know about that.  that’ll do it.  thanks.